],
"isSystem": true
},
+ {
+ "context": "xtuple",
+ "nameSpace": "XM",
+ "type": "SalesOrderPayment",
+ "table": "payco",
+ "idSequenceName": "payco_payco_id_seq",
+ "lockable": true,
+ "lockTable": "payco",
+ "isRest": true,
+ "comment": "Sales Order Payment Map",
+ "privileges": {
+ "all": {
+ "create": "ProcessCreditCards",
+ "read": "ProcessCreditCards",
+ "update": "ProcessCreditCards",
+ "delete": false
+ }
+ },
+ "properties": [
+ {
+ "name": "id",
+ "attr": {
+ "type": "Number",
+ "column": "payco_id",
+ "isPrimaryKey": true
+ }
+ },
+ {
+ "name": "uuid",
+ "attr": {
+ "type": "String",
+ "column": "obj_uuid",
+ "isNaturalKey": true
+ }
+ },
+ {
+ "name": "payment",
+ "toOne": {
+ "isNested": true,
+ "type": "CreditCardPayment",
+ "column": "payco_ccpay_id"
+ }
+ },
+ {
+ "name": "salesOrder",
+ "toOne": {
+ "type": "SalesOrderRelation",
+ "column": "payco_cohead_id"
+ }
+ },
+ {
+ "name": "amount",
+ "attr": {
+ "type": "Number",
+ "column": "payco_amount"
+ }
+ }
+ ],
+ "isSystem": true
+ },
+ {
+ "context": "xtuple",
+ "nameSpace": "XM",
+ "type": "CreditCardPayment",
+ "table": "ccpay",
+ "idSequenceName": "ccpay_ccpay_id_seq",
+ "lockable": true,
+ "lockTable": "ccpay",
+ "isRest": true,
+ "comment": "Credit Card Payment Map",
+ "privileges": {
+ "all": {
+ "create": "ProcessCreditCards",
+ "read": "ProcessCreditCards",
+ "update": "ProcessCreditCards",
+ "delete": false
+ }
+ },
+ "properties": [
+ {
+ "name": "id",
+ "attr": {
+ "type": "Number",
+ "column": "ccpay_id",
+ "isPrimaryKey": true
+ }
+ },
+ {
+ "name": "uuid",
+ "attr": {
+ "type": "String",
+ "column": "obj_uuid",
+ "isNaturalKey": true
+ }
+ },
+ {
+ "name": "creditCard",
+ "toOne": {
+ "type": "CreditCard",
+ "column": "ccpay_ccard_id"
+ }
+ },
+ {
+ "name": "customer",
+ "toOne": {
+ "type": "CustomerRelation",
+ "column": "ccpay_cust_id"
+ }
+ },
+ {
+ "name": "amount",
+ "attr": {
+ "type": "Number",
+ "column": "ccpay_amount"
+ }
+ },
+ {
+ "name": "wasPreauthorization",
+ "attr": {
+ "type": "Boolean",
+ "column": "ccpay_auth"
+ }
+ },
+ {
+ "name": "status",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_status"
+ }
+ },
+ {
+ "name": "type",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_type"
+ }
+ },
+ {
+ "name": "originalType",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_auth_charge"
+ }
+ },
+ {
+ "name": "orderNumber",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_order_number"
+ }
+ },
+ {
+ "name": "orderNumberSeq",
+ "attr": {
+ "type": "Number",
+ "column": "ccpay_order_number_seq"
+ }
+ },
+ {
+ "name": "gatewayTransId",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_ordernum"
+ }
+ },
+ {
+ "name": "gatewayAuthCode",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_code"
+ }
+ },
+ {
+ "name": "gatewayTransDate",
+ "attr": {
+ "type": "Date",
+ "column": "ccpay_yp_r_time"
+ }
+ },
+ {
+ "name": "gatewayAvsCode",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_avs"
+ }
+ },
+ {
+ "name": "gatewayTruncPan",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_card_pan_trunc"
+ }
+ },
+ {
+ "name": "gatewayCardType",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_card_type"
+ }
+ },
+ {
+ "name": "gatewayApproved",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_approved"
+ }
+ },
+ {
+ "name": "gatewayMessage",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_message"
+ }
+ },
+ {
+ "name": "gatewayError",
+ "attr": {
+ "type": "String",
+ "column": "ccpay_r_error"
+ }
+ }
+ ],
+ "isSystem": true
+ },
{
"context": "xtuple",
"nameSpace": "SYS",
"_xtdb_postCashReceipt6": "The selected Cash Receipt cannot be posted as the Bank Account cannot be determined. You must make a Bank Account Assignment for this Cash Receipt before you may post it.",
"_xtdb_postCashReceipt7": "The selected Cash Receipt cannot be posted, probably because the Customer's Prepaid Account was not found.",
"_xtdb_postCashReceipt8": "Cannot post this Cash Receipt because the credit card records could not be found.",
+ "_xtdb_postCCCashReceipt1": "Cannot post this Cash Receipt because annot find the default Bank Account for this Credit Card.",
"_xtdb_postCCCashReceipt11": "Cannot post this Cash Receipt because the record of the credit card transaction either does not exist or is not consistent.",
"_xtdb_postCCcredit1": "Cannot post this Credit Card refund because the default Bank Account for this Credit Card could not be found.",
"_xtdb_postCCcredit2": "Cannot post this Credit Card refund because an invalid id/reference-type pair was passed.",
"public/trigger_functions/cashrcptitem.sql",
"public/trigger_functions/cashrcptmisc.sql",
"public/trigger_functions/ccard.sql",
+ "public/trigger_functions/ccpay.sql",
"public/trigger_functions/char.sql",
"public/trigger_functions/charass.sql",
"public/trigger_functions/charopt.sql",
"public/tables/bankrecitem.sql",
"public/tables/cashrcpt.sql",
+ "public/tables/ccpay.sql",
"public/tables/metric.sql",
+ "public/tables/payco.sql",
"public/tables/priv.sql",
"public/tables/tax.sql",
"public/tables/taxpay.sql",
"public/tables/report/WarehouseMasterList.xml",
"public/tables/report/items.xml",
- "public/patches/fixacl.sql"
+ "public/patches/fixacl.sql",
+ "public/patches/populate_ccpay_card_type.sql"
]
}
pdoctype TEXT DEFAULT NULL,
pamount NUMERIC DEFAULT NULL) RETURNS INTEGER AS
$$
--- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
_aropenid INTEGER;
BEGIN
SELECT * INTO _c
- FROM ccpay, ccard, custinfo
- WHERE ( (ccpay_id = pCCpay)
- AND (ccpay_ccard_id = ccard_id)
- AND (ccpay_cust_id = cust_id) );
+ FROM ccpay
+ JOIN custinfo ON ccpay_cust_id = cust_id
+ WHERE (ccpay_id = pCCpay);
IF (NOT FOUND) THEN
RAISE EXCEPTION 'Cannot find the Credit Card transaction information [xtuple: postCCcashReceipt, -11, %]',
END IF;
SELECT bankaccnt_id, bankaccnt_accnt_id INTO _bankaccnt_id, _realaccnt
- FROM ccbank JOIN bankaccnt ON (ccbank_bankaccnt_id=bankaccnt_id)
- WHERE (ccbank_ccard_type=_c.ccard_type);
+ FROM ccbank
+ JOIN bankaccnt ON (ccbank_bankaccnt_id=bankaccnt_id)
+ WHERE (ccbank_ccard_type=_c.ccpay_card_type);
IF (_bankaccnt_id IS NULL) THEN
RAISE EXCEPTION 'Cannot find the default Bank Account for this Credit Card [xtuple: postCCcredit, -1, %]',
- _c.ccard_type;
+ _c.ccpay_card_type;
END IF;
- _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_order_number::TEXT ||
- '-' || _c.ccpay_order_number_seq::TEXT);
+ _ccOrderDesc := (_c.ccpay_card_type || '-' || _c.ccpay_order_number::TEXT ||
+ '-' || _c.ccpay_order_number_seq::TEXT);
_journal := fetchJournalNumber('C/R');
cashrcpt_usecustdeposit
) VALUES (
_c.ccpay_cust_id, _c.ccpay_amount, _c.ccpay_curr_id,
- _c.ccard_type, _c.ccpay_r_ordernum, _ccOrderDesc,
+ _c.ccpay_card_type, _c.ccpay_r_ordernum, _ccOrderDesc,
CURRENT_DATE, _bankaccnt_id,
fetchMetricBool('EnableCustomerDeposits'))
RETURNING cashrcpt_id INTO _return;
SET cashrcpt_cust_id=_c.ccpay_cust_id,
cashrcpt_amount=_c.ccpay_amount,
cashrcpt_curr_id=_c.ccpay_curr_id,
- cashrcpt_fundstype=_c.ccard_type,
+ cashrcpt_fundstype=_c.ccpay_card_type,
cashrcpt_docnumber=_c.ccpay_r_ordernum,
cashrcpt_notes=_ccOrderDesc,
cashrcpt_distdate=CURRENT_DATE,
_return := _aropenid;
END IF;
- PERFORM insertGLTransaction(_journal, 'A/R', 'CR', _ccOrderDesc,
+ PERFORM insertGLTransaction(_journal, 'A/R', 'CR', _ccOrderDesc,
('Cash Receipt from Credit Card ' || _c.cust_name),
findPrepaidAccount(_c.ccpay_cust_id),
_realaccnt,
NULL,
- ROUND(currToBase(_c.ccpay_curr_id,
- _c.ccpay_amount,
- _c.ccpay_transaction_datetime::DATE),2),
+ ROUND(currToBase(_c.ccpay_curr_id,
+ _c.ccpay_amount,
+ _c.ccpay_transaction_datetime::DATE),2),
CURRENT_DATE);
RETURN _return;
CREATE OR REPLACE FUNCTION postCCcredit(INTEGER, TEXT, INTEGER) RETURNS INTEGER AS $$
--- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
- pCCpay ALIAS FOR $1;
+ pCCpay ALIAS FOR $1;
preftype ALIAS FOR $2;
prefid ALIAS FOR $3;
- _c RECORD;
- _ccOrderDesc TEXT;
+ _c RECORD;
+ _ccOrderDesc TEXT;
_cglaccnt INTEGER;
- _dglaccnt INTEGER;
+ _dglaccnt INTEGER;
_glseriesres INTEGER;
- _notes TEXT := 'Credit via Credit Card';
- _r RECORD;
- _sequence INTEGER;
- _dmaropenid INTEGER;
+ _notes TEXT := 'Credit via Credit Card';
+ _r RECORD;
+ _sequence INTEGER;
+ _dmaropenid INTEGER;
BEGIN
IF ((preftype = 'cohead') AND NOT EXISTS(SELECT cohead_id
- FROM cohead
- WHERE (cohead_id=prefid))) THEN
+ FROM cohead
+ WHERE (cohead_id=prefid))) THEN
RAISE EXCEPTION 'Cannot find original Sales Order for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
pCCpay, preftype, prefid;
ELSIF ((preftype = 'aropen') AND NOT EXISTS(SELECT aropen_id
- FROM aropen
- WHERE (aropen_id=prefid))) THEN
+ FROM aropen
+ WHERE (aropen_id=prefid))) THEN
RAISE EXCEPTION 'Cannot find original A/R Open record for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
pCCpay, preftype, prefid;
ELSIF ((preftype = 'cmhead') AND NOT EXISTS(SELECT cmhead_id
- FROM cmhead
- WHERE cmhead_id=prefid)) THEN
+ FROM cmhead
+ WHERE cmhead_id=prefid)) THEN
RAISE EXCEPTION 'Cannot find original Credit Memo record for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
pCCpay, preftype, prefid;
END IF;
SELECT * INTO _c
- FROM ccpay
- JOIN ccard ON (ccpay_ccard_id = ccard_id)
- JOIN ccbank ON (ccard_type=ccbank_ccard_type)
- WHERE (ccpay_id = pCCpay);
+ FROM ccpay
+ WHERE (ccpay_id = pCCpay);
IF (NOT FOUND) THEN
RAISE EXCEPTION 'Cannot find the record for this Credit Card credit [xtuple: postCCcredit, -3, %, %, %]',
END IF;
SELECT bankaccnt_accnt_id INTO _cglaccnt
- FROM bankaccnt
- WHERE (bankaccnt_id=_c.ccbank_bankaccnt_id);
+ FROM ccbank
+ JOIN bankaccnt ON (ccbank_bankaccnt_id=bankaccnt_id)
+ WHERE (ccbank_ccard_type=_c.ccpay_card_type);
IF (NOT FOUND) THEN
RAISE EXCEPTION 'Cannot find the default Bank Account for this Credit Card [xtuple: postCCcredit, -1, %]',
_sequence := fetchGLSequence();
IF (_c.ccpay_r_ref IS NOT NULL) THEN
- _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_r_ref);
+ _ccOrderDesc := (_c.ccpay_card_type || '-' || _c.ccpay_r_ref);
ELSE
- _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_order_number::TEXT ||
- '-' || COALESCE(_c.ccpay_order_number_seq::TEXT, ''));
+ _ccOrderDesc := (_c.ccpay_card_type || '-' || _c.ccpay_order_number::TEXT ||
+ '-' || COALESCE(_c.ccpay_order_number_seq::TEXT, ''));
END IF;
_glseriesres := insertIntoGLSeries(_sequence, 'A/R', 'CC', _ccOrderDesc,
IF (FOUND) THEN
SELECT createardebitmemo(
- NULL,
+ NULL,
_r.aropen_cust_id, NULL, fetchARMemoNumber(),
_r.aropen_ordernumber, current_date, _c.ccpay_amount,
_notes,
- -1, -1, -1, CURRENT_DATE, -1, NULL, 0,
+ -1, -1, -1, CURRENT_DATE, -1, NULL, 0,
_r.aropen_curr_id) INTO _dmaropenid;
IF (_r.aropen_open) THEN
PERFORM applyARCreditMemoToBalance(_r.aropen_id, _dmaropenid);
PERFORM postARCreditMemoApplication(_r.aropen_id);
END IF;
-
+
END IF;
IF (preftype = 'cohead') THEN
INSERT INTO payco (
- payco_ccpay_id, payco_cohead_id, payco_amount, payco_curr_id
+ payco_ccpay_id, payco_cohead_id, payco_amount, payco_curr_id
) VALUES (
pCCpay, prefid, 0 - _c.ccpay_amount, _c.ccpay_curr_id
);
IF (_numfound <= 0) THEN
INSERT INTO ccbank (ccbank_ccard_type, ccbank_bankaccnt_id)
VALUES (pccardtype, pbankaccntid)
- RETURNING _ccbankid;
+ RETURNING ccbank_id INTO _ccbankid;
END IF;
RETURN _ccbankid;
--- /dev/null
+-- Issue #23459 adds ccpay_card_type. Populate it from historical ccard relations.
+UPDATE ccpay SET ccpay_card_type = (SELECT ccard_type FROM ccard WHERE ccard_id = ccpay_ccard_id)
+WHERE ccpay_ccard_id IS NOT NULL;
--- /dev/null
+ALTER TABLE ccbank DROP CONSTRAINT IF EXISTS ccbank_ccbank_ccard_type_check;
+ALTER TABLE ccbank ADD CONSTRAINT ccbank_ccbank_ccard_type_check
+ CHECK (ccbank_ccard_type = ANY (ARRAY['A', 'D', 'M', 'P', 'V', 'O']));
--- /dev/null
+-- Add columns for data needed for external pre-auths that will have no ccpay_ccard_id.
+select xt.add_column('ccpay','ccpay_card_pan_trunc', 'text', null, 'public', 'External Pre-Auth truncated PAN. Last four digits of the card.');
+-- TODO: PayPal
+--select xt.add_column('ccpay','ccpay_card_type', 'text', null, 'public', 'External Pre-Auth card type: V=Visa, M=MasterCard, A=American Express, D=Discover, P=Paypal.');
+select xt.add_column('ccpay','ccpay_card_type', 'text', null, 'public', 'External Pre-Auth card type: V=Visa, M=MasterCard, A=American Express, D=Discover.');
--- /dev/null
+-- TODO: Add a precheck in the upgrade package.xml for this.
+select xt.add_constraint('payco','payco_unique_ccpay_id_cohead_id', 'unique(payco_ccpay_id, payco_cohead_id)', 'public');
+-- Add primary key.
+select xt.add_column('payco','payco_id', 'serial', 'primary key', 'public', 'payco table primary key.');
--- /dev/null
+CREATE OR REPLACE FUNCTION _ccpayBeforeTrigger () RETURNS TRIGGER AS $$
+-- Copyright (c) 1999-2014 by OpenMFG LLC, d/b/a xTuple.
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+ _cardType TEXT;
+
+BEGIN
+ IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
+ -- If ccpay_ccard_id is set, we don't care if ccpay_card_type is set,
+ -- we want to get the Card Type from ccard.
+ IF (NEW.ccpay_ccard_id IS NOT NULL) THEN
+ SELECT ccard_type INTO _cardType
+ FROM ccard
+ WHERE ccard_id = NEW.ccpay_ccard_id;
+
+ IF (_cardType IS NOT NULL) THEN
+ NEW.ccpay_card_type = _cardType;
+ END IF;
+ END IF;
+ END IF;
+
+ RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+SELECT dropIfExists('TRIGGER', 'ccpayBeforeTrigger');
+CREATE TRIGGER ccpayBeforeTrigger BEFORE INSERT OR UPDATE ON ccpay FOR EACH ROW EXECUTE PROCEDURE _ccpayBeforeTrigger();
editor.setFirstFocus();
},
exportAttr: function (inSender, inEvent) {
- var gridbox = inEvent.originator.parent.parent;
+ var gridbox = this;
this.doExportAttr({ attr: gridbox.attr });
},
refreshLists: function () {
<prerequisite type = "query"
name = "Checking xTuple Edition" >
<query>SELECT fetchMetricText('Application') = 'PostBooks';</query>
- <message>This package must be applied to a Distribution database.</message>
+ <message>This package must be applied to a PostBooks database.</message>
</prerequisite>
<prerequisite type = "query"
</message>
</prerequisite>
- <prerequisite type = "query"
- name = "Checking for bad xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
+ <prerequisite type = "query"
+ name = "Checking for bad xTuple ERP database version" >
+ <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
<message>This package may not be applied to a 4.5+ PostBooks database.
</message>
</prerequisite>
- <prerequisite type = "query"
+ <prerequisite type = "query"
name = "Checking for mobile-enabled schemas" >
<query>SELECT NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'xm');</query>
<message>This package may not be applied to a mobile-enabled database. Please see your system administrator or contact xTuple.
</message>
</prerequisite>
+ <prerequisite type = "query"
+ name = "Checking for duplicate Credit Card payments on Sales Orders" >
+ <query>
+ WITH counter AS (SELECT COUNT(*) AS freq
+ FROM payco
+ GROUP BY payco_ccpay_id, payco_cohead_id
+ ORDER BY 1)
+ SELECT (COALESCE(MAX(freq), 1) = 0 OR COALESCE(MAX(freq), 1) = 1)
+ FROM counter;
+ </query>
+ <message>There are duplicate payco_ccpay_id and payco_cohead_id on the payco table. Please see your system administrator or contact xTuple.
+ </message>
+ </prerequisite>
+
<script file="postbooks_upgrade.sql" />
<script file="inventory_basic_install.sql" />
<script file="inventory_upgrade.sql" />
</message>
</prerequisite>
+ <prerequisite type = "query"
+ name = "Checking for xwd schema" >
+ <query>SELECT NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'xwd');</query>
+ <message>This package requires that XWD 240 package to be installed before continuing.</message>
+ </prerequisite>
+
<script file="postbooks_upgrade.sql" />
<script file="inventory_upgrade.sql" />
<script file="distribution_upgrade.sql" />
</message>
</prerequisite>
- <prerequisite type = "query"
- name = "Checking for bad xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
+ <prerequisite type = "query"
+ name = "Checking for bad xTuple ERP database version" >
+ <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
<message>This package may not be applied to a 4.5+ Postbooks database.
</message>
</prerequisite>
- <prerequisite type = "query"
+ <prerequisite type = "query"
name = "Checking for mobile-enabled schemas" >
<query>SELECT NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'xm');</query>
<message>This package may not be applied to a mobile-enabled database. Please see your system administrator or contact xTuple.
</message>
</prerequisite>
+ <prerequisite type = "query"
+ name = "Checking for duplicate Credit Card payments on Sales Orders" >
+ <query>
+ WITH counter AS (SELECT COUNT(*) AS freq
+ FROM payco
+ GROUP BY payco_ccpay_id, payco_cohead_id
+ ORDER BY 1)
+ SELECT COALESCE(MAX(freq), 1) <= 1
+ FROM counter;
+ </query>
+ <message>There are duplicate payco_ccpay_id and payco_cohead_id on the payco table. Please see your system administrator or contact xTuple.
+ </message>
+ </prerequisite>
+
<script file="postbooks_upgrade.sql" />
</package>
<prerequisite type = "query"
name = "Checking xTuple Edition" >
<query>SELECT fetchMetricText('Application') = 'PostBooks';</query>
- <message>This package must be applied to a Distribution Edition database.</message>
+ <message>This package must be applied to a PostBooks Edition database.</message>
</prerequisite>
<prerequisite type = "query"
</message>
</prerequisite>
- <prerequisite type = "query"
- name = "Checking for bad xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
+ <prerequisite type = "query"
+ name = "Checking for bad xTuple ERP database version" >
+ <query>SELECT NOT fetchMetricText('ServerVersion') > '4.5.0' AND fetchMetricText('ServerVersion')!='4.5.0Beta' AND fetchMetricText('ServerVersion')!='4.5.0RC';</query>
<message>This package may not be applied to a 4.5.0+ PostBooks database.
</message>
</prerequisite>
- <prerequisite type = "query"
+ <prerequisite type = "query"
name = "Checking for mobile-enabled schemas" >
<query>SELECT NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'xm');</query>
<message>This package may not be applied to a mobile-enabled database. Please see your system administrator or contact xTuple.
</message>
</prerequisite>
+ <prerequisite type = "query"
+ name = "Checking for duplicate Credit Card payments on Sales Orders" >
+ <query>
+ WITH counter AS (SELECT COUNT(*) AS freq
+ FROM payco
+ GROUP BY payco_ccpay_id, payco_cohead_id
+ ORDER BY 1)
+ SELECT (COALESCE(MAX(freq), 1) = 0 OR COALESCE(MAX(freq), 1) = 1)
+ FROM counter;
+ </query>
+ <message>There are duplicate payco_ccpay_id and payco_cohead_id on the payco table. Please see your system administrator or contact xTuple.
+ </message>
+ </prerequisite>
+
<script file="postbooks_upgrade.sql" />
<script file="inventory_basic_install.sql" />
<script file="inventory_upgrade.sql" />