first upload
authorAlan Knowles <alan@roojs.com>
Mon, 11 Nov 2013 07:44:19 +0000 (15:44 +0800)
committerAlan Knowles <alan@roojs.com>
Mon, 11 Nov 2013 07:44:19 +0000 (15:44 +0800)
733 files changed:
ApplyGLFinal.php [new file with mode: 0644]
DataObjects/Acalitem.php [new file with mode: 0644]
DataObjects/Accnt.php [new file with mode: 0644]
DataObjects/Addr.php [new file with mode: 0644]
DataObjects/Address.php [new file with mode: 0644]
DataObjects/Alarm.php [new file with mode: 0644]
DataObjects/Apaccnt.php [new file with mode: 0644]
DataObjects/Apapply.php [new file with mode: 0644]
DataObjects/Apchk.php [new file with mode: 0644]
DataObjects/Apchkitem.php [new file with mode: 0644]
DataObjects/Apcreditapply.php [new file with mode: 0644]
DataObjects/Api.account.php [new file with mode: 0644]
DataObjects/Apopen.php [new file with mode: 0644]
DataObjects/Apopentax.php [new file with mode: 0644]
DataObjects/Apselect.php [new file with mode: 0644]
DataObjects/Araccnt.php [new file with mode: 0644]
DataObjects/Arapply.php [new file with mode: 0644]
DataObjects/Arcreditapply.php [new file with mode: 0644]
DataObjects/Aropen.php [new file with mode: 0644]
DataObjects/Aropenco.php [new file with mode: 0644]
DataObjects/Aropentax.php [new file with mode: 0644]
DataObjects/Asohist.php [new file with mode: 0644]
DataObjects/Asohisttax.php [new file with mode: 0644]
DataObjects/Atlasmap.php [new file with mode: 0644]
DataObjects/Backup_usr.php [new file with mode: 0644]
DataObjects/Bankaccnt.php [new file with mode: 0644]
DataObjects/Bankadj.php [new file with mode: 0644]
DataObjects/Bankadjtype.php [new file with mode: 0644]
DataObjects/Bankrec.php [new file with mode: 0644]
DataObjects/Bankrecitem.php [new file with mode: 0644]
DataObjects/Billingeditlist.php [new file with mode: 0644]
DataObjects/Bomhead.php [new file with mode: 0644]
DataObjects/Bomitem.php [new file with mode: 0644]
DataObjects/Bomitemsub.php [new file with mode: 0644]
DataObjects/Bomwork.php [new file with mode: 0644]
DataObjects/Budget.php [new file with mode: 0644]
DataObjects/Budghead.php [new file with mode: 0644]
DataObjects/Budgitem.php [new file with mode: 0644]
DataObjects/Calhead.php [new file with mode: 0644]
DataObjects/Cashrcpt.php [new file with mode: 0644]
DataObjects/Cashrcptitem.php [new file with mode: 0644]
DataObjects/Cashrcptmisc.php [new file with mode: 0644]
DataObjects/Ccard.php [new file with mode: 0644]
DataObjects/Ccardaud.php [new file with mode: 0644]
DataObjects/Ccbank.php [new file with mode: 0644]
DataObjects/Ccpay.php [new file with mode: 0644]
DataObjects/Char.php [new file with mode: 0644]
DataObjects/Charass.php [new file with mode: 0644]
DataObjects/Charopt.php [new file with mode: 0644]
DataObjects/Checkhead.php [new file with mode: 0644]
DataObjects/Checkitem.php [new file with mode: 0644]
DataObjects/Checkrecip.php [new file with mode: 0644]
DataObjects/Classcode.php [new file with mode: 0644]
DataObjects/Cmd.php [new file with mode: 0644]
DataObjects/Cmdarg.php [new file with mode: 0644]
DataObjects/Cmhead.php [new file with mode: 0644]
DataObjects/Cmheadtax.php [new file with mode: 0644]
DataObjects/Cmitem.php [new file with mode: 0644]
DataObjects/Cmitemtax.php [new file with mode: 0644]
DataObjects/Cmnttype.php [new file with mode: 0644]
DataObjects/Cmnttypesource.php [new file with mode: 0644]
DataObjects/Cntct.php [new file with mode: 0644]
DataObjects/Cntctaddr.php [new file with mode: 0644]
DataObjects/Cntctdata.php [new file with mode: 0644]
DataObjects/Cntcteml.php [new file with mode: 0644]
DataObjects/Cntctmrgd.php [new file with mode: 0644]
DataObjects/Cntctsel.php [new file with mode: 0644]
DataObjects/Cntslip.php [new file with mode: 0644]
DataObjects/Cobapply.php [new file with mode: 0644]
DataObjects/Cobill.php [new file with mode: 0644]
DataObjects/Cobilltax.php [new file with mode: 0644]
DataObjects/Cobmisc.php [new file with mode: 0644]
DataObjects/Cobmisctax.php [new file with mode: 0644]
DataObjects/Cohead.php [new file with mode: 0644]
DataObjects/Cohist.php [new file with mode: 0644]
DataObjects/Cohisttax.php [new file with mode: 0644]
DataObjects/Coitem.php [new file with mode: 0644]
DataObjects/Comment.php [new file with mode: 0644]
DataObjects/Company.php [new file with mode: 0644]
DataObjects/Coship.php [new file with mode: 0644]
DataObjects/Cosmisc.php [new file with mode: 0644]
DataObjects/Costcat.php [new file with mode: 0644]
DataObjects/Costelem.php [new file with mode: 0644]
DataObjects/Costhist.php [new file with mode: 0644]
DataObjects/Costupdate.php [new file with mode: 0644]
DataObjects/Country.php [new file with mode: 0644]
DataObjects/Creditmemoeditlist.php [new file with mode: 0644]
DataObjects/Creditmemoitem.php [new file with mode: 0644]
DataObjects/Crmacct.php [new file with mode: 0644]
DataObjects/Curr_rate.php [new file with mode: 0644]
DataObjects/Curr_symbol.php [new file with mode: 0644]
DataObjects/Cust.php [new file with mode: 0644]
DataObjects/Custform.php [new file with mode: 0644]
DataObjects/Custgrp.php [new file with mode: 0644]
DataObjects/Custgrpitem.php [new file with mode: 0644]
DataObjects/Custinfo.php [new file with mode: 0644]
DataObjects/Custtype.php [new file with mode: 0644]
DataObjects/Dept.php [new file with mode: 0644]
DataObjects/Destination.php [new file with mode: 0644]
DataObjects/Docass.php [new file with mode: 0644]
DataObjects/Docinfo.php [new file with mode: 0644]
DataObjects/Dragon_report.php [new file with mode: 0644]
DataObjects/Emp.php [new file with mode: 0644]
DataObjects/Empgrp.php [new file with mode: 0644]
DataObjects/Empgrpitem.php [new file with mode: 0644]
DataObjects/Evntlog.php [new file with mode: 0644]
DataObjects/Evntnot.php [new file with mode: 0644]
DataObjects/Evnttype.php [new file with mode: 0644]
DataObjects/Expcat.php [new file with mode: 0644]
DataObjects/Expense.php [new file with mode: 0644]
DataObjects/Expitem.php [new file with mode: 0644]
DataObjects/Filter.php [new file with mode: 0644]
DataObjects/Flaccnt.php [new file with mode: 0644]
DataObjects/Flcol.php [new file with mode: 0644]
DataObjects/Flgrp.php [new file with mode: 0644]
DataObjects/Flhead.php [new file with mode: 0644]
DataObjects/Flitem.php [new file with mode: 0644]
DataObjects/Flnotes.php [new file with mode: 0644]
DataObjects/Flrpt.php [new file with mode: 0644]
DataObjects/Flspec.php [new file with mode: 0644]
DataObjects/Form.php [new file with mode: 0644]
DataObjects/Freightclass.php [new file with mode: 0644]
DataObjects/Glseries.php [new file with mode: 0644]
DataObjects/Gltrans.php [new file with mode: 0644]
DataObjects/Gltranssync.php [new file with mode: 0644]
DataObjects/Grp.php [new file with mode: 0644]
DataObjects/Grppriv.php [new file with mode: 0644]
DataObjects/Hnfc.php [new file with mode: 0644]
DataObjects/Image.php [new file with mode: 0644]
DataObjects/Imageass.php [new file with mode: 0644]
DataObjects/Incdt.php [new file with mode: 0644]
DataObjects/Incdtcat.php [new file with mode: 0644]
DataObjects/Incdthist.php [new file with mode: 0644]
DataObjects/Incdtpriority.php [new file with mode: 0644]
DataObjects/Incdtresolution.php [new file with mode: 0644]
DataObjects/Incdtseverity.php [new file with mode: 0644]
DataObjects/Invadj.php [new file with mode: 0644]
DataObjects/Invadjgrp.php [new file with mode: 0644]
DataObjects/Invchead.php [new file with mode: 0644]
DataObjects/Invcheadtax.php [new file with mode: 0644]
DataObjects/Invcitem.php [new file with mode: 0644]
DataObjects/Invcitemtax.php [new file with mode: 0644]
DataObjects/Invcnt.php [new file with mode: 0644]
DataObjects/Invdetail.php [new file with mode: 0644]
DataObjects/Invdetailview.php [new file with mode: 0644]
DataObjects/Invfifo.php [new file with mode: 0644]
DataObjects/Invhist.php [new file with mode: 0644]
DataObjects/Invhist_transfer.php [new file with mode: 0644]
DataObjects/Invhist_transfer_item.php [new file with mode: 0644]
DataObjects/Invoiceitem.php [new file with mode: 0644]
DataObjects/Ipsass.php [new file with mode: 0644]
DataObjects/Ipsfreight.php [new file with mode: 0644]
DataObjects/Ipshead.php [new file with mode: 0644]
DataObjects/Ipsitem.php [new file with mode: 0644]
DataObjects/Ipsitemchar.php [new file with mode: 0644]
DataObjects/Ipsiteminfo.php [new file with mode: 0644]
DataObjects/Ipsprice.php [new file with mode: 0644]
DataObjects/Ipsprodcat.php [new file with mode: 0644]
DataObjects/Item.php [new file with mode: 0644]
DataObjects/Itemalias.php [new file with mode: 0644]
DataObjects/Itemcost.php [new file with mode: 0644]
DataObjects/Itemfile.php [new file with mode: 0644]
DataObjects/Itemgrp.php [new file with mode: 0644]
DataObjects/Itemgrpitem.php [new file with mode: 0644]
DataObjects/Itemimage.php [new file with mode: 0644]
DataObjects/Itemloc.php [new file with mode: 0644]
DataObjects/Itemlocdist.php [new file with mode: 0644]
DataObjects/Itemlocpost.php [new file with mode: 0644]
DataObjects/Itemsite.php [new file with mode: 0644]
DataObjects/Itemsrc.php [new file with mode: 0644]
DataObjects/Itemsrcp.php [new file with mode: 0644]
DataObjects/Itemsub.php [new file with mode: 0644]
DataObjects/Itemtax.php [new file with mode: 0644]
DataObjects/Itemtrans.php [new file with mode: 0644]
DataObjects/Itemuom.php [new file with mode: 0644]
DataObjects/Itemuomconv.php [new file with mode: 0644]
DataObjects/Jrnluse.php [new file with mode: 0644]
DataObjects/Labelform.php [new file with mode: 0644]
DataObjects/Lang.php [new file with mode: 0644]
DataObjects/Locale.php [new file with mode: 0644]
DataObjects/Location.php [new file with mode: 0644]
DataObjects/Locbal.php [new file with mode: 0644]
DataObjects/Locitem.php [new file with mode: 0644]
DataObjects/Metasql.php [new file with mode: 0644]
DataObjects/Metric.php [new file with mode: 0644]
DataObjects/Metricenc.php [new file with mode: 0644]
DataObjects/Mrghist.php [new file with mode: 0644]
DataObjects/Msg.php [new file with mode: 0644]
DataObjects/Msguser.php [new file with mode: 0644]
DataObjects/Netsuite_balance.php [new file with mode: 0644]
DataObjects/Netsuite_stock.php [new file with mode: 0644]
DataObjects/Obsolete_tax.php [new file with mode: 0644]
DataObjects/Ophead.php [new file with mode: 0644]
DataObjects/Opsource.php [new file with mode: 0644]
DataObjects/Opstage.php [new file with mode: 0644]
DataObjects/Optype.php [new file with mode: 0644]
DataObjects/Orderhead.php [new file with mode: 0644]
DataObjects/Orderitem.php [new file with mode: 0644]
DataObjects/Orderseq.php [new file with mode: 0644]
DataObjects/Pack.php [new file with mode: 0644]
DataObjects/Payaropen.php [new file with mode: 0644]
DataObjects/Payco.php [new file with mode: 0644]
DataObjects/Period.php [new file with mode: 0644]
DataObjects/Person.php [new file with mode: 0644]
DataObjects/Pkgdep.php [new file with mode: 0644]
DataObjects/Pkghead.php [new file with mode: 0644]
DataObjects/Pkgitem.php [new file with mode: 0644]
DataObjects/Plancode.php [new file with mode: 0644]
DataObjects/Pohead.php [new file with mode: 0644]
DataObjects/Poitem.php [new file with mode: 0644]
DataObjects/Porecv.php [new file with mode: 0644]
DataObjects/Poreject.php [new file with mode: 0644]
DataObjects/Potype.php [new file with mode: 0644]
DataObjects/Pr.php [new file with mode: 0644]
DataObjects/Prftcntr.php [new file with mode: 0644]
DataObjects/Priv.php [new file with mode: 0644]
DataObjects/Prj.php [new file with mode: 0644]
DataObjects/Prjtask.php [new file with mode: 0644]
DataObjects/Prjtaskuser.php [new file with mode: 0644]
DataObjects/Prodcat.php [new file with mode: 0644]
DataObjects/Prospect.php [new file with mode: 0644]
DataObjects/Qryhead.php [new file with mode: 0644]
DataObjects/Qryitem.php [new file with mode: 0644]
DataObjects/Quhead.php [new file with mode: 0644]
DataObjects/Quitem.php [new file with mode: 0644]
DataObjects/Rcalitem.php [new file with mode: 0644]
DataObjects/Recur.php [new file with mode: 0644]
DataObjects/Recurtype.php [new file with mode: 0644]
DataObjects/Recv.php [new file with mode: 0644]
DataObjects/Recvgrp.php [new file with mode: 0644]
DataObjects/Recvgrpland.php [new file with mode: 0644]
DataObjects/Remitto.php [new file with mode: 0644]
DataObjects/Report.php [new file with mode: 0644]
DataObjects/Rjctcode.php [new file with mode: 0644]
DataObjects/Rsncode.php [new file with mode: 0644]
DataObjects/Sale.php [new file with mode: 0644]
DataObjects/Salesaccnt.php [new file with mode: 0644]
DataObjects/Salescat.php [new file with mode: 0644]
DataObjects/Salesforecast.php [new file with mode: 0644]
DataObjects/Saleshistory.php [new file with mode: 0644]
DataObjects/Saleshistorymisc.php [new file with mode: 0644]
DataObjects/Salesrep.php [new file with mode: 0644]
DataObjects/Script.php [new file with mode: 0644]
DataObjects/Sequence.php [new file with mode: 0644]
DataObjects/Shift.php [new file with mode: 0644]
DataObjects/Shipchrg.php [new file with mode: 0644]
DataObjects/Shipdata.php [new file with mode: 0644]
DataObjects/Shipdatasum.php [new file with mode: 0644]
DataObjects/Shipform.php [new file with mode: 0644]
DataObjects/Shiphead.php [new file with mode: 0644]
DataObjects/Shipitem.php [new file with mode: 0644]
DataObjects/Shipitemlocrsrv.php [new file with mode: 0644]
DataObjects/Shipto.php [new file with mode: 0644]
DataObjects/Shiptoinfo.php [new file with mode: 0644]
DataObjects/Shipvia.php [new file with mode: 0644]
DataObjects/Shipzone.php [new file with mode: 0644]
DataObjects/Sitetype.php [new file with mode: 0644]
DataObjects/Sltrans.php [new file with mode: 0644]
DataObjects/Sopack.php [new file with mode: 0644]
DataObjects/Source.php [new file with mode: 0644]
DataObjects/State.php [new file with mode: 0644]
DataObjects/Status.php [new file with mode: 0644]
DataObjects/Stdjrnl.php [new file with mode: 0644]
DataObjects/Stdjrnlgrp.php [new file with mode: 0644]
DataObjects/Stdjrnlgrpitem.php [new file with mode: 0644]
DataObjects/Stdjrnlitem.php [new file with mode: 0644]
DataObjects/Subaccnt.php [new file with mode: 0644]
DataObjects/Subaccnttype.php [new file with mode: 0644]
DataObjects/Tax.php [new file with mode: 0644]
DataObjects/Taxass.php [new file with mode: 0644]
DataObjects/Taxauth.php [new file with mode: 0644]
DataObjects/Taxclass.php [new file with mode: 0644]
DataObjects/Taxhist.php [new file with mode: 0644]
DataObjects/Taxrate.php [new file with mode: 0644]
DataObjects/Taxreg.php [new file with mode: 0644]
DataObjects/Taxtype.php [new file with mode: 0644]
DataObjects/Taxzone.php [new file with mode: 0644]
DataObjects/Terms.php [new file with mode: 0644]
DataObjects/Todoitem.php [new file with mode: 0644]
DataObjects/Trgthist.php [new file with mode: 0644]
DataObjects/Trialbal.php [new file with mode: 0644]
DataObjects/Trialbalsync.php [new file with mode: 0644]
DataObjects/Uiform.php [new file with mode: 0644]
DataObjects/Uom.php [new file with mode: 0644]
DataObjects/Uomconv.php [new file with mode: 0644]
DataObjects/Uomtype.php [new file with mode: 0644]
DataObjects/Url.php [new file with mode: 0644]
DataObjects/Usr.php [new file with mode: 0644]
DataObjects/Usr_bak.php [new file with mode: 0644]
DataObjects/Usrgrp.php [new file with mode: 0644]
DataObjects/Usrpref.php [new file with mode: 0644]
DataObjects/Usrpriv.php [new file with mode: 0644]
DataObjects/Vend.php [new file with mode: 0644]
DataObjects/Vendaddr.php [new file with mode: 0644]
DataObjects/Vendaddrinfo.php [new file with mode: 0644]
DataObjects/Vendinfo.php [new file with mode: 0644]
DataObjects/Vendtype.php [new file with mode: 0644]
DataObjects/Vodist.php [new file with mode: 0644]
DataObjects/Vohead.php [new file with mode: 0644]
DataObjects/Voheadtax.php [new file with mode: 0644]
DataObjects/Voitem.php [new file with mode: 0644]
DataObjects/Voitemtax.php [new file with mode: 0644]
DataObjects/Voucheringeditlist.php [new file with mode: 0644]
DataObjects/Warehous.php [new file with mode: 0644]
DataObjects/Whsezone.php [new file with mode: 0644]
DataObjects/Whsinfo.php [new file with mode: 0644]
DataObjects/Wo.php [new file with mode: 0644]
DataObjects/Womatl.php [new file with mode: 0644]
DataObjects/Womatlpost.php [new file with mode: 0644]
DataObjects/Womatlvar.php [new file with mode: 0644]
DataObjects/Xsltmap.php [new file with mode: 0644]
DataObjects/Yearperiod.php [new file with mode: 0644]
DataObjects/invdetailview.php [new file with mode: 0644]
Fifo/FillPurchasePrices.php [new file with mode: 0644]
Fifo/FillValuesWalk2.php [new file with mode: 0644]
Fifo/FixVoids.php [new file with mode: 0644]
Fifo/ProcessAdjVoids.php [new file with mode: 0644]
Fifo/ProcessBase.php [new file with mode: 0644]
Fifo/ProcessBasic.php [new file with mode: 0644]
Fifo/ProcessCoheadVoids.php [new file with mode: 0644]
Fifo/ProcessFifoAdjustment.php [new file with mode: 0644]
Fifo/ProcessGl.php [new file with mode: 0644]
Fifo/ProcessOldLanded.php [new file with mode: 0644]
Fifo/ProcessPoheadVoids.php [new file with mode: 0644]
Fifo/ProcessValues.php [new file with mode: 0644]
Fifo/ProcessValuesWalk.php [new file with mode: 0644]
Fifo/ResetVoids.php [new file with mode: 0644]
Import/AUPostAccounts.php [new file with mode: 0644]
Import/AUPurchaseOrder.php [new file with mode: 0644]
Import/CreditMemo.php [new file with mode: 0644]
Import/Customers.php [new file with mode: 0644]
Import/ExpCat.php [new file with mode: 0644]
Import/Flrpt.php [new file with mode: 0644]
Import/InvAdjustment.php [new file with mode: 0644]
Import/JournalEntry.php [new file with mode: 0644]
Import/Magento.php [new file with mode: 0644]
Import/MagentoOld.php [new file with mode: 0644]
Import/MyCustomers.php [new file with mode: 0644]
Import/Products.php [new file with mode: 0644]
Import/PurchaseOrder.php [new file with mode: 0644]
Import/SalesOrder.php [new file with mode: 0644]
Import/Transfer.php [new file with mode: 0644]
Import/Vendors.php [new file with mode: 0644]
Kingdee.php [new file with mode: 0644]
Kingdee/Account.php [new file with mode: 0644]
Kingdee/Currency.php [new file with mode: 0644]
Kingdee/Rate.php [new file with mode: 0644]
Kingdee/Schema/Account_Header.csv [new file with mode: 0644]
Kingdee/Schema/Account_Schema.csv [new file with mode: 0644]
Kingdee/Schema/Currency_Header.csv [new file with mode: 0644]
Kingdee/Schema/Currency_Schema.csv [new file with mode: 0644]
Kingdee/Schema/Rate_Header.csv [new file with mode: 0644]
Kingdee/Schema/Rate_Schema.csv [new file with mode: 0644]
Kingdee/Schema/VoucherGroup_Header.csv [new file with mode: 0644]
Kingdee/Schema/VoucherGroup_Schema.csv [new file with mode: 0644]
Kingdee/Schema/Voucher_Header.csv [new file with mode: 0644]
Kingdee/Schema/Voucher_Schema.csv [new file with mode: 0644]
Kingdee/Voucher.php [new file with mode: 0644]
Kingdee/VoucherGroup.php [new file with mode: 0644]
Migrate.php [new file with mode: 0644]
Period.php [new file with mode: 0644]
Pman.Dialog.XtupleAddress.bjs [new file with mode: 0644]
Pman.Dialog.XtupleAddress.js [new file with mode: 0644]
Pman.Dialog.XtupleAdjustmentGroup.bjs [new file with mode: 0644]
Pman.Dialog.XtupleAdjustmentGroup.js [new file with mode: 0644]
Pman.Dialog.XtupleContact.bjs [new file with mode: 0644]
Pman.Dialog.XtupleContact.js [new file with mode: 0644]
Pman.Dialog.XtupleCreditMemo.bjs [new file with mode: 0644]
Pman.Dialog.XtupleCreditMemo.js [new file with mode: 0644]
Pman.Dialog.XtupleCreditMemoNew.bjs [new file with mode: 0644]
Pman.Dialog.XtupleCreditMemoNew.js [new file with mode: 0644]
Pman.Dialog.XtupleCustomer.bjs [new file with mode: 0644]
Pman.Dialog.XtupleCustomer.js [new file with mode: 0644]
Pman.Dialog.XtupleCustomerCode.bjs [new file with mode: 0644]
Pman.Dialog.XtupleCustomerCode.js [new file with mode: 0644]
Pman.Dialog.XtupleDiscountOfInvoice.bjs [new file with mode: 0644]
Pman.Dialog.XtupleDiscountOfInvoice.js [new file with mode: 0644]
Pman.Dialog.XtupleExpenses.bjs [new file with mode: 0644]
Pman.Dialog.XtupleExpenses.js [new file with mode: 0644]
Pman.Dialog.XtupleGLAccountNameEdit.bjs [new file with mode: 0644]
Pman.Dialog.XtupleGLAccountNameEdit.js [new file with mode: 0644]
Pman.Dialog.XtupleInvHistory.bjs [new file with mode: 0644]
Pman.Dialog.XtupleInvHistory.js [new file with mode: 0644]
Pman.Dialog.XtupleInvHistoryOld.bjs [new file with mode: 0644]
Pman.Dialog.XtupleInvHistoryOld.js [new file with mode: 0644]
Pman.Dialog.XtupleInvc.bjs [new file with mode: 0644]
Pman.Dialog.XtupleInvc.js [new file with mode: 0644]
Pman.Dialog.XtupleInvoice.bjs [new file with mode: 0644]
Pman.Dialog.XtupleInvoice.js [new file with mode: 0644]
Pman.Dialog.XtupleItem.bjs [new file with mode: 0644]
Pman.Dialog.XtupleItem.js [new file with mode: 0644]
Pman.Dialog.XtupleLocation.bjs [new file with mode: 0644]
Pman.Dialog.XtupleLocation.js [new file with mode: 0644]
Pman.Dialog.XtupleMiscellaneousCheck.bjs [new file with mode: 0644]
Pman.Dialog.XtupleMiscellaneousCheck.js [new file with mode: 0644]
Pman.Dialog.XtuplePriceList.bjs [new file with mode: 0644]
Pman.Dialog.XtuplePriceList.js [new file with mode: 0644]
Pman.Dialog.XtupleProdcat.bjs [new file with mode: 0644]
Pman.Dialog.XtupleProdcat.js [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrder.bjs [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrder.js [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrderEdit.bjs [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrderEdit.js [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrderNew.bjs [new file with mode: 0644]
Pman.Dialog.XtuplePurchaseOrderNew.js [new file with mode: 0644]
Pman.Dialog.XtupleQuickContact.bjs [new file with mode: 0644]
Pman.Dialog.XtupleQuickContact.js [new file with mode: 0644]
Pman.Dialog.XtupleReceivePayment.bjs [new file with mode: 0644]
Pman.Dialog.XtupleReceivePayment.js [new file with mode: 0644]
Pman.Dialog.XtupleReconcile.bjs [new file with mode: 0644]
Pman.Dialog.XtupleReconcile.js [new file with mode: 0644]
Pman.Dialog.XtupleRecvGrp.bjs [new file with mode: 0644]
Pman.Dialog.XtupleRecvGrp.js [new file with mode: 0644]
Pman.Dialog.XtupleReportCustomer.bjs [new file with mode: 0644]
Pman.Dialog.XtupleReportCustomer.js [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrder.bjs [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrder.js [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrderCopy.bjs [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrderCopy.js [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrderNew.bjs [new file with mode: 0644]
Pman.Dialog.XtupleSalesOrderNew.js [new file with mode: 0644]
Pman.Dialog.XtupleSalesProductList.bjs [new file with mode: 0644]
Pman.Dialog.XtupleSalesProductList.js [new file with mode: 0644]
Pman.Dialog.XtupleShipment.bjs [new file with mode: 0644]
Pman.Dialog.XtupleShipment.js [new file with mode: 0644]
Pman.Dialog.XtupleShipmentNew.bjs [new file with mode: 0644]
Pman.Dialog.XtupleShipmentNew.js [new file with mode: 0644]
Pman.Dialog.XtupleTransfer.bjs [new file with mode: 0644]
Pman.Dialog.XtupleTransfer.js [new file with mode: 0644]
Pman.Dialog.XtupleUploadBalances.bjs [new file with mode: 0644]
Pman.Dialog.XtupleUploadBalances.js [new file with mode: 0644]
Pman.Tab.XtupleAccountsTab.bjs [new file with mode: 0644]
Pman.Tab.XtupleAccountsTab.js [new file with mode: 0644]
Pman.Tab.XtupleAdjustment.bjs [new file with mode: 0644]
Pman.Tab.XtupleAdjustment.js [new file with mode: 0644]
Pman.Tab.XtupleAdjustmentGroup.bjs [new file with mode: 0644]
Pman.Tab.XtupleAdjustmentGroup.js [new file with mode: 0644]
Pman.Tab.XtupleAdjustmentTab.bjs [new file with mode: 0644]
Pman.Tab.XtupleAdjustmentTab.js [new file with mode: 0644]
Pman.Tab.XtupleCreditMemos.bjs [new file with mode: 0644]
Pman.Tab.XtupleCreditMemos.js [new file with mode: 0644]
Pman.Tab.XtupleCustomer.bjs [new file with mode: 0644]
Pman.Tab.XtupleCustomer.js [new file with mode: 0644]
Pman.Tab.XtupleDashboard.bjs [new file with mode: 0644]
Pman.Tab.XtupleDashboard.js [new file with mode: 0644]
Pman.Tab.XtupleExpenses.bjs [new file with mode: 0644]
Pman.Tab.XtupleExpenses.js [new file with mode: 0644]
Pman.Tab.XtupleGeneralLedger.bjs [new file with mode: 0644]
Pman.Tab.XtupleGeneralLedger.js [new file with mode: 0644]
Pman.Tab.XtupleItem.bjs [new file with mode: 0644]
Pman.Tab.XtupleItem.js [new file with mode: 0644]
Pman.Tab.XtupleLanded.bjs [new file with mode: 0644]
Pman.Tab.XtupleLanded.js [new file with mode: 0644]
Pman.Tab.XtupleManage.bjs [new file with mode: 0644]
Pman.Tab.XtupleManage.js [new file with mode: 0644]
Pman.Tab.XtuplePeriods.bjs [new file with mode: 0644]
Pman.Tab.XtuplePeriods.js [new file with mode: 0644]
Pman.Tab.XtuplePriceLists.bjs [new file with mode: 0644]
Pman.Tab.XtuplePriceLists.js [new file with mode: 0644]
Pman.Tab.XtuplePurchaseRecv.bjs [new file with mode: 0644]
Pman.Tab.XtuplePurchaseRecv.js [new file with mode: 0644]
Pman.Tab.XtuplePurchaseStock.bjs [new file with mode: 0644]
Pman.Tab.XtuplePurchaseStock.js [new file with mode: 0644]
Pman.Tab.XtuplePurchases.bjs [new file with mode: 0644]
Pman.Tab.XtuplePurchases.js [new file with mode: 0644]
Pman.Tab.XtuplePurchasesVendors.bjs [new file with mode: 0644]
Pman.Tab.XtuplePurchasesVendors.js [new file with mode: 0644]
Pman.Tab.XtupleReconcile.bjs [new file with mode: 0644]
Pman.Tab.XtupleReconcile.js [new file with mode: 0644]
Pman.Tab.XtupleSales.bjs [new file with mode: 0644]
Pman.Tab.XtupleSales.js [new file with mode: 0644]
Pman.Tab.XtupleSalesHistory.bjs [new file with mode: 0644]
Pman.Tab.XtupleSalesHistory.js [new file with mode: 0644]
Pman.Tab.XtupleSalesInvoice.bjs [new file with mode: 0644]
Pman.Tab.XtupleSalesInvoice.js [new file with mode: 0644]
Pman.Tab.XtupleSalesOrder.bjs [new file with mode: 0644]
Pman.Tab.XtupleSalesOrder.js [new file with mode: 0644]
Pman.Tab.XtupleSalesPlanning.bjs [new file with mode: 0644]
Pman.Tab.XtupleSalesPlanning.js [new file with mode: 0644]
Pman.Tab.XtupleSalesShipment.bjs [new file with mode: 0644]
Pman.Tab.XtupleSalesShipment.js [new file with mode: 0644]
Pman.Tab.XtupleStock.bjs [new file with mode: 0644]
Pman.Tab.XtupleStock.js [new file with mode: 0644]
Pman.Tab.XtupleStockHistory.bjs [new file with mode: 0644]
Pman.Tab.XtupleStockHistory.js [new file with mode: 0644]
Pman.Tab.XtupleTransfer.bjs [new file with mode: 0644]
Pman.Tab.XtupleTransfer.js [new file with mode: 0644]
Pman.Xtuple.DashboardRender.js [new file with mode: 0644]
Pman.Xtuple.js [new file with mode: 0644]
Pman.php [new file with mode: 0644]
Pricing.php [new file with mode: 0644]
Print.php [new file with mode: 0644]
Reports/AccountCheckEmail.php [new file with mode: 0644]
Reports/Base.php [new file with mode: 0644]
Reports/ConsolidatedAccounts.php [new file with mode: 0644]
Reports/Meta.php [new file with mode: 0644]
Reports/PurchasesByProduct.php [new file with mode: 0644]
Reports/PurchasesByVendor.php [new file with mode: 0644]
Reports/SGTax.php [new file with mode: 0644]
Reports/SalesByCountry.php [new file with mode: 0644]
Reports/SalesByCountryItemYear.php [new file with mode: 0644]
Reports/SalesByCustomer.php [new file with mode: 0644]
Reports/SalesByProduct.php [new file with mode: 0644]
Reports/StockAtLocation.php [new file with mode: 0644]
Reports/reportstyle.css [new file with mode: 0644]
Roo.php [new file with mode: 0644]
Setup/ResetDB.php [new file with mode: 0644]
TestAuth.php [new file with mode: 0644]
UpdateDatabase.php [new file with mode: 0644]
Verify.php [new file with mode: 0644]
VerifyAP.php [new file with mode: 0644]
VerifyAR.php [new file with mode: 0644]
VerifyAccounts.php [new file with mode: 0644]
VerifyMigrate.php [new file with mode: 0644]
colorbrewer.js [new file with mode: 0644]
domtemplates/perbrand.html [new file with mode: 0644]
domtemplates/percountry.html [new file with mode: 0644]
domtemplates/perday.html [new file with mode: 0644]
domtemplates/perproduct.html [new file with mode: 0644]
domtemplates/profitbycustomer.html [new file with mode: 0644]
domtemplates/revenuebycustomer.html [new file with mode: 0644]
domtemplates/salestrend.html [new file with mode: 0644]
domtemplates/slowmoving.html [new file with mode: 0644]
domtemplates/summary.html [new file with mode: 0644]
domtemplates/totals.html [new file with mode: 0644]
dumpAccnt.php [new file with mode: 0644]
pgsql/apaging.sql [new file with mode: 0644]
pgsql/coitem_delete_trigger.sql [new file with mode: 0644]
pgsql/createapcreditmemoapplication.sql [new file with mode: 0644]
pgsql/enterporeturn.sql [new file with mode: 0644]
pgsql/explodekit.sql [new file with mode: 0644]
pgsql/fetchinvnumber.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-1.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-2.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-3.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-fill-all.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-fill.sql [new file with mode: 0644]
pgsql/fifo-testing/fifo-test-update.sql [new file with mode: 0644]
pgsql/fixes/apopen_distdate.sql [new file with mode: 0644]
pgsql/fixes/invhist_transfer_salesrep_id.sql [new file with mode: 0644]
pgsql/fixes/x-dragon-apapply_txdate.sql [new file with mode: 0644]
pgsql/fixes/x-dragon-shipping-asset-report.sql [new file with mode: 0644]
pgsql/fixes/x-dragon-shipping-report-run.sql [new file with mode: 0644]
pgsql/fixes/x-dragon-shipping-report.sql [new file with mode: 0644]
pgsql/fixes/x-dragon-shippingasset-fix.sql [new file with mode: 0644]
pgsql/investigations/ar_mismatch.sql [new file with mode: 0644]
pgsql/investigations/shipasset_query.sql [new file with mode: 0644]
pgsql/investigations/stock_imbalances.txt [new file with mode: 0644]
pgsql/migration/expense-migrate.sql [new file with mode: 0644]
pgsql/migration/x-dragon-bankrec.sql [new file with mode: 0644]
pgsql/migration/x-fifo-remove-eoy.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-createitemsrc.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-discounttaxfix.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix-based.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix-based2011.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix2009.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix2010.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix2011.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix2011sg.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-eoy-fix2012.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-fixap.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-fixap2.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-fixflipje.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-fixvendorcredit.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-fixvendorcreditje.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-recv.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-taxfix.sql [new file with mode: 0644]
pgsql/migration/x-netsuite-voidporeturn.sql [new file with mode: 0644]
pgsql/old/apaging.sql [new file with mode: 0644]
pgsql/old/api-functions-insertsalesline.sql [new file with mode: 0644]
pgsql/old/copyso.sql [new file with mode: 0644]
pgsql/old/distributeitemlocseries.sql [new file with mode: 0644]
pgsql/old/distributetolocations.sql [new file with mode: 0644]
pgsql/old/distributetolocations.sql.disabled [new file with mode: 0644]
pgsql/old/fifo-view.sql [new file with mode: 0644]
pgsql/old/geteffectivextuser.sql [new file with mode: 0644]
pgsql/old/invadjustment.sql [new file with mode: 0644]
pgsql/old/invreceipt.sql [new file with mode: 0644]
pgsql/old/postinvtrans.sql [new file with mode: 0644]
pgsql/old/sg-eoy-fixmonths2011.sql [new file with mode: 0644]
pgsql/old/x-fifo-create_invbuysell_tbls.sql [new file with mode: 0644]
pgsql/old/x-fifo-create_trig_invhisttriggerfifo.sql [new file with mode: 0644]
pgsql/old/x-fifo-invdetail-adjust.sql [new file with mode: 0644]
pgsql/old/x-fifo-invdetail_update_sell.sql [new file with mode: 0644]
pgsql/old/x-fifo-invfifo_creditmemo_cost.sql [new file with mode: 0644]
pgsql/old/x-fifo-invfifo_purchase_value.sql [new file with mode: 0644]
pgsql/old/x-fifo-invfifo_update_queued.sql [new file with mode: 0644]
pgsql/old/x-fifo-invfifo_update_values.sql [new file with mode: 0644]
pgsql/old/x-fifo-invhist_sell_unitcost_calc.sql [new file with mode: 0644]
pgsql/old/x-fifo-invhisttriggerfifo.sql [new file with mode: 0644]
pgsql/old/x-fifo-invsell_apply.sql [new file with mode: 0644]
pgsql/old/x-fifo-invsell_apply_order.sql [new file with mode: 0644]
pgsql/old/x-fifo-invsell_apply_trialbal.sql [new file with mode: 0644]
pgsql/old/x-fifo-invsell_update_after.sql [new file with mode: 0644]
pgsql/old/x-fifo-itemcost_acquire.sql [new file with mode: 0644]
pgsql/old/x-fifo-itemcost_dispense.sql [new file with mode: 0644]
pgsql/old/x-netsuite-eoy-fix2009.sql [new file with mode: 0644]
pgsql/old/x-netsuite-eoy-fix2010.sql [new file with mode: 0644]
pgsql/old/x-netsuite-eoyfix-sg-2011.sql [new file with mode: 0644]
pgsql/postapcreditmemoapplication.sql [new file with mode: 0644]
pgsql/postitemlocseries.sql.sql [new file with mode: 0644]
pgsql/postporeturncreditmemo.sql [new file with mode: 0644]
pgsql/postporeturns.sql [new file with mode: 0644]
pgsql/recallshipment.sql [new file with mode: 0644]
pgsql/releasevonumber.sql [new file with mode: 0644]
pgsql/relocateinventory.sql [new file with mode: 0644]
pgsql/sandbox.apply.sh [new file with mode: 0755]
pgsql/shipshipment.sql [new file with mode: 0644]
pgsql/sync_changes.sh [new file with mode: 0644]
pgsql/triggers-cobill.sql [new file with mode: 0644]
pgsql/triggers-coitem.sql [new file with mode: 0644]
pgsql/valueatshipping.sql [new file with mode: 0644]
pgsql/voheadaftertrigger.sql [new file with mode: 0644]
pgsql/voidapcreditmemoapplication.sql [new file with mode: 0644]
pgsql/voidapopenvoucher.sql [new file with mode: 0644]
pgsql/voidarcreditmemoapplication.sql [new file with mode: 0644]
pgsql/voidbankreconciliation.sql [new file with mode: 0644]
pgsql/voidinvoice.sql [new file with mode: 0644]
pgsql/voidpostedcheck.sql [new file with mode: 0644]
pgsql/x-dragon-accnt.sql [new file with mode: 0644]
pgsql/x-dragon-apopen_isposted.sql [new file with mode: 0644]
pgsql/x-dragon-apopen_isreversed.sql [new file with mode: 0644]
pgsql/x-dragon-aropen-accountcheck.sql [new file with mode: 0644]
pgsql/x-dragon-aropen_isposted.sql [new file with mode: 0644]
pgsql/x-dragon-bankrec-fix-historical.sql [new file with mode: 0644]
pgsql/x-dragon-charass_getvalue.sql [new file with mode: 0644]
pgsql/x-dragon-cobapply.sql [new file with mode: 0644]
pgsql/x-dragon-cohead-test-shipping-qty.sql [new file with mode: 0644]
pgsql/x-dragon-cohead.sql [new file with mode: 0644]
pgsql/x-dragon-cohist-pos.sql [new file with mode: 0644]
pgsql/x-dragon-coitem-pos.sql [new file with mode: 0644]
pgsql/x-dragon-deletesoitemcheck.sql [new file with mode: 0644]
pgsql/x-dragon-delivery-note-changes.sql [new file with mode: 0644]
pgsql/x-dragon-dragon-report.sql [new file with mode: 0644]
pgsql/x-dragon-expense.sql [new file with mode: 0644]
pgsql/x-dragon-fetchnextchecknumber.sql [new file with mode: 0644]
pgsql/x-dragon-fix-apopen.sql [new file with mode: 0644]
pgsql/x-dragon-fix-cobmisc-discount.sql [new file with mode: 0644]
pgsql/x-dragon-gl-precision.sql [new file with mode: 0644]
pgsql/x-dragon-invadj.sql [new file with mode: 0644]
pgsql/x-dragon-invadjgrp.sql [new file with mode: 0644]
pgsql/x-dragon-invdetail-bydate.sql [new file with mode: 0644]
pgsql/x-dragon-invhist-transfer.sql [new file with mode: 0644]
pgsql/x-dragon-item-beforetrigger.sql [new file with mode: 0644]
pgsql/x-dragon-itemprice_wrp.sql [new file with mode: 0644]
pgsql/x-dragon-location.sql [new file with mode: 0644]
pgsql/x-dragon-locbal.sql [new file with mode: 0644]
pgsql/x-dragon-optimize.sql [new file with mode: 0644]
pgsql/x-dragon-period-temp-close.sql [new file with mode: 0644]
pgsql/x-dragon-period-temp-open.sql [new file with mode: 0644]
pgsql/x-dragon-pohead.sql [new file with mode: 0644]
pgsql/x-dragon-poitem.sql [new file with mode: 0644]
pgsql/x-dragon-postinvtransfixed.sql [new file with mode: 0644]
pgsql/x-dragon-recvgrp.sql [new file with mode: 0644]
pgsql/x-dragon-recvgrpland.sql [new file with mode: 0644]
pgsql/x-dragon-salesforecast.sql [new file with mode: 0644]
pgsql/x-dragon-salesorder-planning.sql [new file with mode: 0644]
pgsql/x-dragon-salesordercalcs.sql [new file with mode: 0644]
pgsql/x-dragon-setbankreccleared.sql [new file with mode: 0644]
pgsql/x-dragon-trialbal-fix.sql [new file with mode: 0644]
pgsql/x-dragon-undeleteglseries.sql [new file with mode: 0644]
pgsql/x-dragon-voidunpostedinvoice.sql [new file with mode: 0644]
pgsql/x-fifo-extra-indexes.sql [new file with mode: 0644]
pgsql/x-fifo-fix-cohead-id.sql [new file with mode: 0644]
pgsql/x-fifo-invdetailview.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-adjust.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-cmhead-fix-stock.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-cmhead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-cohead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-invchead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-apply-gl-pohead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-cohead-fix-id.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-cohead-void-flag.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-cost-at-qty.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-cost-before-in.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-cost-before-out.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fill-all.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fill.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fix-cohead-id.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fixCmvoid.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fixInvdetail.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-fixPoVariance.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-hourly.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-invadj-void-flag.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-pohead-void-flag.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-unitcost-at-qty.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-adjustment-in.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-adjustment-out.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-credit-memo-void.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-credit-memo.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-invdetail-ahead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-invdetail-all.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-invdetail.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-invoice.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-pohead.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-return-inventory.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-return-invoice.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-return-shipping.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-shipment.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-transfer-in.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-transfer-out.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo-update-from-void.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo.sql [new file with mode: 0644]
pgsql/x-fifo-invfifo_apply_gl_cmhead_fix_stock.sql [new file with mode: 0644]
pgsql/x-fifo-invfifopos.sql [new file with mode: 0644]
pgsql/x-fifo-set-metric.sql [new file with mode: 0644]
pgsql/x-fix-cmhead-location-id.sql [new file with mode: 0644]
pgsql/x-fix-cmhead-missing-inv-tx.sql [new file with mode: 0644]
pgsql/x-netsuite-balances.sql [new file with mode: 0644]
pgsql/x-netsuite-mig-extra.sql [new file with mode: 0644]
pgsql/x-netsuite-stock.sql [new file with mode: 0644]
pgsql/x-timewarp-period-fill.sql [new file with mode: 0644]
pgsql/x-timewarp-trialbal-fill.sql [new file with mode: 0644]
pgsql/x-timewarp-triggers.sql [new file with mode: 0644]
pgsql/x-timewarp-yearperiod-fill.sql [new file with mode: 0644]
pgsql/x-timewarp.sql [new file with mode: 0644]
pgsql/xtuple.apply.sh [new file with mode: 0755]
sqlreports/costest.sql [new file with mode: 0644]
sqlreports/perbrand.sql [new file with mode: 0644]
sqlreports/percountry.sql [new file with mode: 0644]
sqlreports/perproduct.sql [new file with mode: 0644]
sqlreports/profitbycustomer.sql [new file with mode: 0644]
sqlreports/revenuebycustomer.sql [new file with mode: 0644]
sqlreports/salescompare.sql [new file with mode: 0644]
sqlreports/salestrend.sql [new file with mode: 0644]
sqlreports/slowmoving.sql [new file with mode: 0644]
sqlreports/summary.sql [new file with mode: 0644]
sqlreports/totals.sql [new file with mode: 0644]
templates/images/logo.gif [new file with mode: 0644]
templates/images/logo_small.gif [new file with mode: 0644]
templates/mail/AccountCheckEmail.txt [new file with mode: 0644]
templates/master.html [new file with mode: 0644]

diff --git a/ApplyGLFinal.php b/ApplyGLFinal.php
new file mode 100644 (file)
index 0000000..40dafa8
--- /dev/null
@@ -0,0 +1,556 @@
+<?php
+require_once 'Pman.php';
+
+
+
+// this will produce an excel spreadsheet with the list of adjustments to do..
+
+class Pman_Xtuple_ApplyGLFinal extends Pman
+{
+    
+    static $cli_desc = "Migrate Netsuite -- apply final GL balances";
+    
+    function getAuth()
+    {
+        $au = $this->getAuthUser();
+        
+        if (!empty($au->id)) {
+            return true;
+        }
+        if (!HTML_FlexyFramework::get()->cli) {
+            die("invalid url");
+        }
+        
+    }
+    var $db = false;
+    var $year=  2009;
+    
+    function yfile()
+    {
+        switch($this->db) {
+            case 'hk':
+                return   $this->rootDir  . '/../netsuite_balances/netsuite-HK-apr'. $this->year . '.csv';
+            case 'sg':
+                return   $this->rootDir  . '/../netsuite_balances/netsuite-SG-sep'. $this->year . '.csv';
+            default:
+                die("OPPS NO DB?");
+        }
+        
+    }
+    
+    
+    function get()
+    {
+       $this->jerr("disabled");
+       
+        $this->db = preg_match('/hk$/', $this->bootLoader->database) ? 'hk' : 'sg';
+        
+        $acc = array();
+        $head = array('accnt_number', 'accnt_name', 'curr', 'accnt_type');
+        $yo = array();
+        for ($y = 2009; $y < 2013; $y++) {
+            $yo[$y] = count($head);
+            array_push($head , 'CUR', 'NS' .$y, 'XT' .$y, 'DIFF'.  $y, '' );
+            
+            $res = $this->process($y);
+            foreach($res as $row) {
+                if (!isset($acc[$row['id']])) {
+                    $acc[$row['id']] = array();
+                }
+                $acc[$row['id']][$y] = $row;
+            }
+            
+            
+        }
+        
+        uasort($acc, function($ll,$vv) {
+           // // sort by accnt type first.
+            $l = array_pop(array_values($ll));
+            $v = array_pop(array_values($vv));
+            //echo '<PRE>';print_R($l);exit;
+            if ($l['accnt_type'] != $v['accnt_type']) {
+                return $l['accnt_type']  > $v['accnt_type'] ? 1 : -1;
+            }
+            if ($l['accnt_subaccnttype_code'] != $v['accnt_subaccnttype_code']) {
+                return $l['accnt_subaccnttype_code']  > $v['accnt_subaccnttype_code'] ? 1 : -1;
+            }
+            
+            return $l['accnt_descrip']  > $v['accnt_descrip'] ? 1 : -1;
+            
+        });
+        
+        
+        // need to sort accounts...
+        // need to feetch all totals here, rather than later...
+        // but need to know which currencies to fetch...
+        
+        //echo '<PRE>';
+        //print_r($head);exit;
+        $rows = array();
+        foreach($acc as $id => $years ) {
+            $first = array_pop(array_values($years));
+            //print_r($first);
+            $row = array_fill(0, 30, '');
+            $row[0] = $first['accnt_number'];
+            $row[1] = $first['accnt_descrip'];
+            $row[2] = $first['curr'];
+            $row[3] = $first['accnt_type'] . '/' . $first['accnt_subaccnttype_code'];
+            
+            
+            //print_r($years);
+            
+            for ($y = 2009; $y < 2013; $y++) {
+                $o = $yo[$y];
+                if (!isset($years[$y])) {
+                    continue;
+                }
+                $rec = $years[$y];
+                
+                if (empty($rec['accnt_number'])) {
+                    
+                    $curs = array_keys($rec['ns']) ;
+                    if (count($curs) != 1) {
+                        print_r($rec);
+                        die("got a ns only acc. with multiple tx's in");
+                    }
+                    $cur = $curs[0];
+                    $row[$o] = $cur ;
+                    $row[$o+1] =  $rec['ns'][$cur]['fc'];
+                    $row[$o+2] = 0;
+                    $row[$o+3] = '?? ' . $rec['ns'][$cur]['fc']; //<<< probaly not!
+                    continue;
+                    
+                }
+                
+                
+                if (empty($rec['ns'])) {
+                    $row[$o] = $rec['base'];
+                    $row[$o+1] = 0;
+                    $row[$o+2] =  sprintf('%0.2f',$rec['XT.' . $rec['base']  ]);
+                    $row[$o+3] = -1.0 * $rec['XT.' .$rec['base']  ];
+                    continue;
+                    
+                }
+                
+                if (!isset($rec['ns.' .$rec['diffcur']  ])) {
+                    echo "diffcurr NS not available...";
+                    print_R($rec);
+                    exit;
+                }
+                
+                
+                
+                $row[$o] = $rec['diffcur'];
+                $row[$o+1] =  sprintf('%0.2f',$rec['ns.' . $rec['diffcur']  ]);
+                $row[$o+2] =  sprintf('%0.2f',$rec['XT.' .$rec['diffcur']  ]);
+                $row[$o+3] =  sprintf('%0.2f', -1.0 * $rec['diff'] );
+            }
+            $rows[] = $row;
+            
+        }
+        
+        
+        // output csv..
+        
+        header('Content-type: text/csv');
+        header( 'Content-Disposition: attachment;filename=Accounts.csv');
+        $fh = fopen('php://output','w');
+        fputcsv($fh, $head);
+        $lac = '';
+        foreach($rows as $o) {
+            $ac = $o[3];
+            if (!empty($lac) && $lac !=$ac) {
+                fputcsv($fh, array());
+            }
+            $lac = $ac;
+            fputcsv($fh, $o);
+        }
+        fclose($fh);
+        exit;
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        exit;
+        
+    }
+    
+    
+    function process($y)
+    {
+        //print_r($this);exit;
+        $this->year = $y;
+        
+        
+        $base = $this->yfile();
+        
+        
+         
+        
+        $fh = fopen($base,'r');
+        if (!$fh) {
+            die("no file");
+        }
+        
+        
+        
+        $lines = array();
+        $accnts = array();
+        $start = false;
+        while (false !== ($row = fgetcsv($fh))) {
+            
+            if (!$start) {
+                //var_dump($row);
+                if (trim($row[0]) == 'Name') {
+                    $start = true;
+                    continue;
+                }
+                continue;
+            }
+            
+             if (str_replace(',','', $row[3]) * 1.0 == 0.0) {
+                continue;
+             }
+            
+            $acc = trim($row[0]);
+            if (!isset($lines[$acc])) {
+                $lines[$acc] = $this->acctDef($acc);
+                if ($lines[$acc]['id']) {
+                    $accnts[] = $lines[$acc]['id'];
+                }
+                $lines[$acc]['ns.name'] = $acc;
+                
+            }
+            
+            $curr = trim($row[2]);
+            if ($curr == 'CNY') {
+                $curr = 'RMB';
+            }
+            
+            
+            $hkd = str_replace(',', '', preg_replace('/HK\$/', '', $row[1]));
+            $fc = str_replace(',','', $row[3]);
+            
+            if (
+                    ($hkd > 0 && $fc < 0)
+                ||
+                    ($hkd < 0 && $fc > 0)
+               )
+            {
+                $fc *= -1;
+            }
+             
+            
+            $lines[$acc]['ns'][$curr] = array(
+                    'fc' => $fc,
+                    'HKD' => $hkd
+            );
+        }
+        fclose($fh);
+        
+        //DB_DataObject::DebugLevel(1);
+        // now fill in the xtuple data..
+        $gl = DB_DataObject::Factory('gltrans');
+        
+        $dt = $this->db == 'hk' ? ($this->year .'-04-30') : ($this->year .'-09-30');
+        $dt = $dt== '2012-09-30' ? '2012-08-31' : $dt;
+        
+        
+        $gl->selectAdd();
+        $gl->selectAdd('distinct(gltrans_accnt_id ) as gltrans_accnt_id ');
+        $gl->whereAdd('gltrans_accnt_id NOT IN (' .implode(',', $accnts) .')');
+        $gl->whereAdd("gltrans_date < '{$dt}'::date + INTERVAL '1 DAY'");
+        $other = $gl->fetchAll('gltrans_accnt_id');
+         
+        foreach($other as $ac) {
+            $lines['XT.'.$ac] = $this->acctDef($ac, true);
+        }
+        $res = array();
+        
+        // at this point we should decide which currency to use for the whole account.
+        
+        
+        
+        
+        //print_r($lines);
+        foreach($lines as $k=> $line) {
+            $add = $this->study($line);
+            
+             
+            
+            if ($add) {
+                $res[$k] = $add;
+            }
+        }
+        return $res;
+    }
+    
+    function acctDef($name, $isnum=false) {
+        
+        $d = DB_DataObject::Factory('accnt');
+        $d->autoJoin();
+        //why?
+        if (!$isnum) {
+            if ($name == 'Bank - HKD Transfer Account (HK HQ)') {
+                $name = 'Bank - HKD transfer Account (HK HQ)';
+            }
+            if ($name == 'CCB Motor Hire Purchase (HK HQ)') {
+                $name = 'Hire Purchase of Motor vehicle (HK HQ)';
+            }
+            if ($name == 'Loss on disposal') {
+                $name = 'Loss on disposal of assets';
+            }
+            $d->accnt_descrip = $name;
+            
+            //DB_DataObject::debugLevel(1);
+            
+            
+            $d->whereAdd('accnt_number::integer < 1000');
+            if ($d->count() != 1) {
+                //echo "Can not find accnt $name\n";
+                
+                if (in_array($name , array(
+                    'Freight Income (HK HQ)' // known badd..
+    
+                    
+                ))) {
+                    return array(
+                       'id' => 0,
+                       'accnt_descrip' => $name,
+                       'accnt_number' => '',
+                       'curr_id' => 1, // usd...
+                       'curr' => 'USD',
+                       'accnt_type' => '',
+                       'accnt_subaccnttype_code' => '',
+                       
+                   );   
+                }
+                
+                exit;
+                
+            }
+            $d->find(true);
+        } else {
+            $d->get($name);
+        }
+        $cur = 'HKD'; //$this->db == 'hk' ? 'HKD' : 'SGD';
+        $ret = array(
+                'id' => $d->accnt_id,
+                'curr' => $d->accnt_curr_id_curr_name,
+                'curr_id' => $d->accnt_curr_id,
+                'accnt_type' => $d->accnt_type,
+                'accnt_number' => $d->accnt_number,
+                'accnt_descrip' => $d->accnt_descrip,
+                'accnt_subaccnttype_code' => $d->accnt_subaccnttype_code,
+                'base' => $cur,
+                'ns' => array()
+        );
+        
+        // find the total in local...
+        
+        
+        $ret['XT.'. $cur] = $this->getAccntAt($d->accnt_id, $cur);
+        
+        if ($cur != $ret['curr']) {
+            $ret['XT.'. $ret['curr']] = $this->getAccntAt($d->accnt_id, $ret['curr_id']);
+        }
+        
+        
+        
+        return $ret;
+        
+    }
+     
+    function getAccntAt($id, $curr=false) {
+        //DB_DataObject::debugLevel(1);
+        // STATEMENT : Q, L, A
+        $dt = $this->db == 'hk' ? ($this->year .'-04-30') : ($this->year .'-09-30');
+        $dt = $dt== '2012-09-30' ? '2012-08-31' : $dt;
+        // the last column is only advisory, we can not base any data on it..
+        //if ($dt == '2012-09-30') {
+        //    $dt  = '2012-08-30';
+        //}
+        
+        
+        static $pds = array();
+        
+        if (!isset($pds[$dt])) {
+            $p = DB_DAtaObject::Factory('period');
+            $p->get('period_end', $dt);
+
+            $pds[$dt] = $p->pid();
+        }
+        
+        $pid = $pds[$dt];
+        
+          
+        
+        
+        $gl = DB_DataObject::Factory('trialbal');
+        
+        
+        $gl->selectAdd();
+        
+        if (!$curr) {
+            $gl->selectAdd('trialbal_ending');
+        } else {
+            if (!is_numeric($curr)) {
+                $curr = "getcurrid('$curr')";
+                
+                
+            }
+            $gl->selectAdd("
+                    currtocurr(
+                        baseCurrId(),
+                        $curr ,
+                        trialbal_ending,
+                        '$dt'
+                        
+                    ) as trialbal_ending ");
+            
+            
+        }
+        
+        $gl->trialbal_accnt_id = $id;
+        $gl->trialbal_period_id = $pid;
+        $gg = clone ($gl);
+        if (!$gl->find(true)) {
+            DB_DataObject::debugLevel(1);
+            $gg->find(true);
+            exit;
+        }
+        return   isset($gl->trialbal_ending)  ? $gl->trialbal_ending : 0.0;
+            
+        
+        
+    }
+    
+    function study($line) {
+        
+        // comparison = should be done on base currency for everything except the banks..
+        
+        //print_r($line);exit;
+        
+        $compare = 'HKD'; //$this->db == 'HK' ? 'HKD' : 'SGD';
+        if ($line['accnt_subaccnttype_code'] == 'CA') {
+            // it's a bank
+            $compare = $line['curr'];
+        }
+        
+        //print_r($line);exit;
+        if (empty($line['ns']) && $line['XT.'.$line['base']] == 0.0) {
+            return false;
+        }
+        
+        if (empty($line['ns']) || empty($line['id'])) {
+            //echo "SKIP {$line['accnt_descrip']}\n";
+            return $line;
+        }
+        if (!isset($line['accnt_type'])) {
+            print_r($line);exit;
+        }
+        
+        //if ($this->db == 'hk') {
+        $hkd = 0.0;
+        foreach($line['ns'] as $cur=>$data) {
+            $hkd += $data['HKD'];
+        }
+        $line['ns.HKD'] = $hkd;
+        $base = 'HKD';
+            
+        //if ($this->db == 'sg') {
+        //    $sgd = 0.0;
+        //    foreach($line['ns'] as $cur=>$data) {
+        //        $sgd += $data['HKD'] / 6.2;
+        //    }
+        //    $line['ns.SGD'] = $sgd;
+        //    $base = 'SGD';
+        //}
+        
+        $fac = 1;
+        switch($line['accnt_type'] ) {
+            case 'A':
+            case 'E':
+            case 'R':
+            case 'L':
+                $fac = -1.0;
+                break;
+            default:
+                $fac = 1.0;
+                break;
+                
+        }
+         
+        if (count(array_keys($line['ns'])) == 1) {
+            // then it should be a simple match
+            
+            
+            if (isset($line['ns'][ $compare   ])) {
+                // use the base currency to compare..
+                $line['ns.' . $compare] = $line['ns'][  $compare  ]['fc'];
+                $line['diffcur'] = $compare;
+                if ($line['XT.' .$compare ] == ($fac * $line['ns'][  $compare  ]['fc'])) {
+                        // they match!!
+                        $line['diff'] = '';
+                        return $line;
+                }
+                $line['diff'] = sprintf('%0.2f',
+                        $line['XT.' .$compare ] - ($fac * $line['ns'][  $compare ]['fc']));
+                
+                return $line; 
+                
+            }
+            
+            // otherise try and use base currency.
+            
+            if ($this->db == 'sg') {
+                if (!isset($line['ns.' . $line['base'] ] )) {
+                    //echo '<PRE>';print_R($line);exit;
+                    $line['ns.' . $line['base'] ] = sprintf('%0.2f', $line['ns'][  'HKD' ]['fc'] * (1/6.2));
+                }
+            } else {
+            // use the base currency to compare..
+                $line['ns.' . $line['base'] ] = sprintf('%0.2f', $line['ns'][  $line['base']   ]['fc']);
+            }
+            $line['diffcur'] = $line['base'];
+            if ($line['XT.' .$line['base'] ] == ($fac * $line['ns.' . $line['base'] ])) {
+                    // they match!!
+                    $line['diff'] = '';
+                    return $line;
+            }
+            $line['diff'] = sprintf('%0.2f', $line['XT.' .$line['base'] ] - ($fac * $line['ns.' . $line['base'] ]));
+            
+            return $line; 
+              
+            //print_R($line);exit;
+            
+            
+        }
+        // otherwise we have to compare on base currency...
+        
+        if (!isset($line['XT.' . $base])) {
+            echo "MISSING: XT." . $base;
+            print_r($line);exit;
+        }
+        // got a multicurrency netsuite..
+        //if ($line['XT.HKD'] == ($fac * $hkd)) {
+            // they match!!
+        //    return false;
+        //}
+        $line['diff'] = sprintf('%0.2f', $line['XT.' . $base] - ($fac * $line['ns.'.$base]));
+        $line['diffcur'] = $base;
+        return $line; 
+        
+        
+        
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/DataObjects/Acalitem.php b/DataObjects/Acalitem.php
new file mode 100644 (file)
index 0000000..a6e3b7d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for acalitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Acalitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'acalitem';            // table name
+    public $acalitem_id;                     // int4(4)  not_null default_nextval%28%28%22xcalitem_xcalitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $acalitem_calhead_id;             // int4(4)  
+    public $acalitem_periodstart;            // date(4)  
+    public $acalitem_periodlength;           // int4(4)  
+    public $acalitem_name;                   // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Accnt.php b/DataObjects/Accnt.php
new file mode 100644 (file)
index 0000000..f0d2c2b
--- /dev/null
@@ -0,0 +1,530 @@
+<?php
+/**
+ * Table Definition for accnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Accnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'accnt';               // table name
+    public $accnt_id;                        // int4(4)  not_null default_nextval%28%28accnt_accnt_id_seq%29%3A%3Aregclass%29 primary_key
+    public $accnt_number;                    // text(-1)  
+    public $accnt_descrip;                   // text(-1)  
+    public $accnt_comments;                  // text(-1)  
+    public $accnt_profit;                    // text(-1)  
+    public $accnt_sub;                       // text(-1)  
+    public $accnt_type;                      // bpchar(-1)  not_null
+    public $accnt_extref;                    // text(-1)  
+    public $accnt_company;                   // text(-1)  
+    public $accnt_closedpost;                // bool(1)  
+    public $accnt_forwardupdate;             // bool(1)  
+    public $accnt_subaccnttype_code;         // text(-1)  
+    public $accnt_curr_id;                   // int4(4)  default_basecurrid%28%29
+    public $accnt_active;                    // bool(1)  not_null default_true
+    public $accnt_name;                      // text(-1)  
+    public $accnt_code_alt;                  // text default ''
+    public $accnt_descrip_alt;               // text default ''
+
+
+    /**
+    * Getter / Setter for $accnt_company
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function company() {
+        return func_num_args() ? $this->link('accnt_company', func_get_arg(0)) : $this->link('accnt_company');
+    }
+
+   /**
+    * Getter / Setter for $accnt_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('accnt_curr_id', func_get_arg(0)) : $this->link('accnt_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function   applyFilters($q, $authUser, $roo)
+    {
+        $dt = date('Y-m-01', isset($q['_as_of']) ? strtotime($q['_as_of']) : time());
+        
+        if(isset($q['_with_xt_balances'])){
+            
+            $this->selectAdd("
+                (SELECT 
+                    SUM(trialbal_ending -  trialbal_beginning) 
+                    
+                    AS
+                        trialbal_ending
+                    FROM
+                         trialbal
+                    LEFT JOIN
+                        period
+                    ON
+                        period_id = trialbal_period_id
+                     WHERE
+                            trialbal_accnt_id=accnt_id
+                        AND
+                             period_start <= '$dt'
+                )  as balance_base
+            ");
+           
+            $this->orderBy('accnt_subaccnttype_code ASC, accnt_descrip ASC');
+        }
+        
+        if(isset($q['_general_ledger'])){
+            $this->orderBy("accnt_type asc,accnt_subaccnttype_code asc, accnt_descrip asc");
+        }
+        
+        
+        if (isset($q['_with_balances']))
+        {
+            // all gltrans are in HKD.
+            
+            // for hk office - the hkd value is line/by/line correct.
+            
+            // if baseCurrId() == getcurrid('HKD')
+            // for the sg office hkd value == 
+            
+            
+            //DB_DataObject::debugLevel(1);
+            $p = DB_DataObject::factory('period');
+            if (!$p->get('period_start', $dt)) {
+                // get the last period
+                $p = DB_DataObject::factory('period');
+                $p->orderBy('period_start DESC');
+                $p->limit(1);
+                $p->find(True);
+                
+                //$roo->jerr("period does not exist");
+            }
+            
+            
+            // for trial balances - if it's not an asset or Liability..
+            // then ending is only the end of that period...
+            
+            $this->selectAdd("
+                             
+                             
+              
+              
+                (SELECT      
+                        currtocurr(
+                            baseCurrId(),
+                            getcurrid('HKD' ),
+                            SUM( CASE WHEN accnt_type IN ( 'A') THEN  
+                                       (trialbal_ending -  trialbal_beginning)   * -1
+                                ELSE 
+                                       trialbal_ending -  trialbal_beginning 
+                                END ),
+                            '{$p->period_end}'
+                        )
+                     
+                     FROM
+                             trialbal
+                    LEFT JOIN
+                        period
+                    ON
+                        period_id = trialbal_period_id
+                    WHERE
+                            trialbal_accnt_id=accnt_id
+                        AND
+                            period_start <= '$dt'
+                )  as balance_hkd,
+                               
+                
+                
+                 
+                
+                 (SELECT      
+                        CASE WHEN accnt_type IN (  'A') THEN  
+                               SUM(trialbal_ending -  trialbal_beginning)  * -1
+                        
+                        ELSE 
+                               SUM(trialbal_ending -  trialbal_beginning)
+                        END as trialbal_ending
+                         
+                     FROM
+                         trialbal
+                    LEFT JOIN
+                        period
+                    ON
+                        period_id = trialbal_period_id
+                     WHERE
+                            trialbal_accnt_id=accnt_id
+                        AND
+                             period_start <= '$dt'
+                )  as balance_base,
+                 
+                  
+                 (SELECT      
+                        CASE WHEN accnt_type IN (  'A', 'E') THEN  
+                               trialbal_ending   * -1
+                        ELSE 
+                               trialbal_ending 
+                        END as trialbal_ending
+                         
+                     FROM
+                         trialbal
+                    LEFT JOIN
+                        period
+                    ON
+                        period_id = trialbal_period_id
+                     WHERE
+                            trialbal_accnt_id=accnt_id
+                        AND
+                            period_start =  '$dt'
+                            
+                )  as balance_base_soy,
+                 
+                     (SELECT      
+                        currtocurr(
+                            baseCurrId(),
+                            accnt_curr_id,
+                            SUM( CASE WHEN accnt_type IN ( 'A') THEN  
+                                       (trialbal_ending -  trialbal_beginning)   * -1
+                                ELSE 
+                                       trialbal_ending -  trialbal_beginning 
+                                END
+                            ),
+                            '{$p->period_end}'
+                        )
+                     
+                     FROM
+                             trialbal
+                    LEFT JOIN
+                        period
+                    ON
+                        period_id = trialbal_period_id
+                    WHERE
+                            trialbal_accnt_id=accnt_id
+                        AND
+                            period_start <= '$dt'
+                )  as balance ,
+                 (SELECT curr_name from curr_symbol where curr_id =  baseCurrId()) as base_curr,
+                
+                {$p->pid()} as period_id
+              
+         ");
+             
+           $this->selectAdd("    
+                
+                (SELECT
+                    ending
+                    FROM
+                    netsuite_balance
+                    WHERE
+                    netsuite_balance.accnt_id = accnt.accnt_id
+                    AND
+                    period_id = {$p->pid()}
+                    AND
+                    curr_id = accnt_curr_id
+                    LIMIT 1
+                ) as nsbalance,
+                
+                (SELECT
+                    COALESCE(MAX(curr_id),0) as curr_id
+                    FROM
+                    netsuite_balance
+                    WHERE
+                    netsuite_balance.accnt_id = accnt.accnt_id
+                    AND
+                    period_id = {$p->pid()}
+                    LIMIT 1
+                ) as nscurr_id,
+            
+                 
+                (SELECT
+                    base_ending
+                    FROM
+                    netsuite_balance
+                    WHERE
+                    netsuite_balance.accnt_id = accnt.accnt_id
+                    AND
+                    period_id = {$p->pid()}
+                    LIMIT 1
+                ) as nsbalance_base,
+                   
+                (SELECT
+                    base_close
+                    FROM
+                    netsuite_balance
+                    WHERE
+                    netsuite_balance.accnt_id = accnt.accnt_id
+                    AND
+                    period_id = {$p->pid()}
+                    LIMIT 1
+                ) as base_close,
+                
+                (SELECT
+                    id 
+                    FROM
+                    netsuite_balance
+                    WHERE
+                    netsuite_balance.accnt_id = accnt.accnt_id
+                    AND
+                    period_id = {$p->pid()}
+                    LIMIT 1
+                ) as nsbalance_id
+
+                 
+                
+                
+           
+           ");
+         
+           // $this->whereAdd('accnt_curr_id NOT IN ( 9,6) '); 
+            $this->whereAdd("accnt_id IN (
+                    select distinct(trialbal_accnt_id)
+                        FROM
+                        trialbal
+                        LEFT JOIN
+                        period
+                        ON
+                        period_id = trialbal_period_id
+                        
+                        WHERE
+                        period_start <= '$dt'::date
+                        AND
+                        (
+                            trialbal_credits != 0.0 
+                            OR
+                            trialbal_debits != 0.0
+                            OR
+                            trialbal_ending != 0.0
+                            OR
+                            trialbal_beginning != 0.0
+                        )
+                    )
+            "); 
+            $this->orderBy();
+            $this->orderBy('accnt_subaccnttype_code ASC, accnt_descrip ASC');
+        }
+        
+        if(!empty($q['search']['name'])){
+            $this->whereAdd("
+                accnt_name ILIKE '{$this->escape($q['search']['name'])}%'
+                OR
+                accnt_descrip ILIKE '{$this->escape($q['search']['name'])}%'
+                OR
+                accnt_descrip_alt ILIKE '{$this->escape($q['search']['name'])}%'
+            ");
+        }
+        
+    }
+    
+    function toRooArray($q)  
+    {
+        $ret = $this->toArray();
+        return $ret;
+    /*
+        if (empty($q['_with_balances'])) {
+            return $ret;
+        }
+        static $netsuite = false;
+        if (!$netsuite) {
+            $netsuite= $this->oldParse();
+        }
+        
+        //$ret['balance_ns'] = isset($netsuite[$this->accnt_number]) ?
+        //        $netsuite[$this->accnt_number]->netsuite_balance : 0.0; 
+        return $ret;
+        */
+        
+    }
+    
+    
+    function oldParse()
+    {
+        $ff = HTML_FlexyFramework::get();
+        $ff->page->baseURL;
+        $which = array_pop(explode('/', $ff->page->baseURL));
+        $cn = $which == 'hk.php' ? 'HK' : 'SG';
+        
+        $har = explode('/', realpath(__FILE__));
+        $home = '/home/alan';
+        $fn = "$home/Dropbox/xtuple_working/old_database_snapshot/$cn/Netsuite_Account.sql.json.all";
+        $ar = file($fn);
+       // echo '<PRE>';print_R($ar);exit;
+        $ret = array();
+        foreach($ar as $i=>$l) {
+            if (!$i) continue;
+            $line = json_decode($l);
+         
+            $ret[$line->id] =   (object)array(
+                    'id' => $line->id ,
+                    'description' => $line->description,
+                    'netsuite_balance' => $line->balance,
+                    'acctType' => $line->acctType,
+                    'is_old' => 1
+                );
+        }
+        return $ret;
+         
+
+        
+    }
+    // used by gltrans reports?
+    function multiplier() {
+        $map = array(
+                'Q' => 1,
+                'L' =>  1,
+                'A' => -1,
+                'E' => 1,
+                'R' => 1,
+        );
+        return $map[$this->accnt_type];
+    }
+    
+    function defaults()
+    {
+        return array(
+            'accnt_descrip' => '',
+            'accnt_comments' => '',
+            'accnt_extref' => '',
+            'accnt_closedpost'=> false,
+            'accnt_forwardupdate' => false,
+            'accnt_active' => true,
+        );
+    }
+    
+    /*
+     * public $accnt_id;                        // int4(4)  not_null default_nextval%28%28accnt_accnt_id_seq%29%3A%3Aregclass%29 primary_key
+    public $accnt_number;                    // text(-1)  
+    public $accnt_descrip;                   // text(-1)  
+    public $accnt_comments;                  // text(-1)  
+    public $accnt_profit;                    // text(-1)  
+    public $accnt_sub;                       // text(-1)  
+    public $accnt_type;                      // bpchar(-1)  not_null
+    public $accnt_extref;                    // text(-1)  
+    public $accnt_company;                   // text(-1)  
+    public $accnt_closedpost;                // bool(1)  
+    public $accnt_forwardupdate;             // bool(1)  
+    public $accnt_subaccnttype_code;         // text(-1)  
+    public $accnt_curr_id;                   // int4(4)  default_basecurrid%28%29
+    public $accnt_active;                    // bool(1)  not_null default_true
+    public $accnt_name;       
+     * 
+     */
+    
+    function joinAddBankaccnt()
+    {
+        $this->_join .= '
+            LEFT JOIN
+                bankaccnt
+            ON
+                bankaccnt_accnt_id = accnt_id
+        ';
+        $bankaccnt = DB_DataObject::Factory('bankaccnt');
+        $this->selectAs($bankaccnt, '%s');
+        
+    }
+    
+    function importFromArray($roo, $accounts)
+    {
+        foreach ($accounts as $account){
+            $accnt = DB_DataObject::factory('accnt');
+            if($accnt->get('accnt_name', $account['accnt_name'])){
+                continue;
+            }
+            $accnt->setFrom($accnt->defaults());
+            
+            $curr = DB_DataObject::factory('curr_symbol');
+            if(!$curr->get('curr_abbr', $account['accnt_curr_abbr'])){
+                $roo->jerr("Missing currency : {$account['accnt_curr_abbr']}");
+            }
+            $accnt->accnt_number = $account['accnt_number'];
+            $accnt->accnt_descrip = $account['accnt_descrip'];
+            $accnt->accnt_profit = $account['accnt_profit'];
+            $accnt->accnt_sub = $account['accnt_sub'];
+            $accnt->accnt_type = $account['accnt_type'];
+            $accnt->accnt_company = $account['accnt_company'];
+            $accnt->accnt_subaccnttype_code = $account['accnt_subaccnttype_code'];
+            $accnt->accnt_name = $account['accnt_name'];
+            
+            $accnt->insert();
+            //$roo->jerr($accnt->accnt_name);exit;
+            if(empty($account['bankaccnt_id'])){
+                continue; 
+            }
+            
+            $bankaccnt = DB_DataObject::factory('bankaccnt');
+            $bankaccnt->setFrom($account);
+            
+            $curr = DB_DataObject::factory('curr_symbol');
+            if(!$curr->get('curr_abbr', $account['bankaccnt_curr_abbr'])){
+                $roo->jerr("Missing currency : {$account['bankaccnt_curr_abbr']}");
+            }
+            $bankaccnt->bankaccnt_curr_id = $curr->pid();
+            $bankaccnt->bankaccnt_accnt_id = $accnt->pid();
+            $bankaccnt->insert();
+        }
+    }
+    
+    function checkAlternativeCode($roo, $download = false)
+    {
+        /*
+         *  check the alternative code 
+         *  if an account has transactions and there is not a alt code for it - then display an error
+         */
+        $errors = array();
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->selectAdd();
+        $accnt->selectAdd("
+            accnt_id,
+            accnt_code_alt,
+            CASE WHEN (accnt_descrip_alt IS NOT NULL AND accnt_descrip_alt != '') THEN
+                accnt_descrip_alt
+            ELSE
+                accnt_descrip
+            END AS accnt_descrip
+        ");
+        $accnt->orderBy('accnt_code_alt DESC');
+        $accnt->find();
+        while ($accnt->fetch()){
+            if(!empty($accnt->accnt_code_alt)){
+                $a = DB_DataObject::factory('accnt');
+                $a->accnt_code_alt = $accnt->accnt_code_alt;
+                if($a->count() > 1){
+                    $errors[] = "Duplicate alternative code : " . $accnt->accnt_code_alt . " - " . $accnt->accnt_descrip;
+                }
+                continue;
+            }
+            
+            $gltrans = DB_DataObject::factory('gltrans');
+            $gltrans->selectAdd();
+            $gltrans->selectAdd('gltrans_id');
+            $gltrans->whereAdd("
+                gltrans_accnt_id = {$accnt->accnt_id}
+                AND
+                NOT gltrans_deleted
+            ");
+            if(!$gltrans->count()){
+                continue;
+            }
+            
+            $errors[] = "Missing alternative code : " . $accnt->accnt_descrip;
+        }
+        
+        $errors = array_filter($errors);
+        
+        if(!empty($errors)){
+            if($download){
+                $roo->jerr(implode("\n", $errors), array(), 'text/plain');
+            }
+            
+            $roo->jerr(implode("\n", $errors));
+        }
+        
+        return true;
+    }
+    
+}
diff --git a/DataObjects/Addr.php b/DataObjects/Addr.php
new file mode 100644 (file)
index 0000000..457de79
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Table Definition for addr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Addr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'addr';                // table name
+    public $addr_id;                         // int4(4)  not_null default_nextval%28addr_addr_id_seq%29 primary_key
+    public $addr_active;                     // bool(1)  default_true
+    public $addr_line1;                      // text(-1)  default_
+    public $addr_line2;                      // text(-1)  default_
+    public $addr_line3;                      // text(-1)  default_
+    public $addr_city;                       // text(-1)  default_
+    public $addr_state;                      // text(-1)  default_
+    public $addr_postalcode;                 // text(-1)  default_
+    public $addr_country;                    // text(-1)  default_
+    public $addr_notes;                      // text(-1)  default_
+    public $addr_number;                     // text(-1)  not_null unique_key
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    // _customer_id
+    function addressArray() { 
+        return array(
+            $this->addr_line1,
+            $this->addr_line2,
+            $this->addr_line3,
+            $this->addr_city,
+            $this->addr_country
+            
+        );
+    }
+    function applyFilters($q, $au)
+    {
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['_customer_id'])) {
+            $cid = (int) $q['_customer_id'];
+           // DB_DataObject::DebugLevel(1);
+            $this->whereAdd("
+                    addr_id  IN (
+                        SELECT cntct_addr_id FROM cntct WHERE
+                            cntct_crmacct_id = (SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = $cid)
+                    ) 
+                    
+            ");
+        }
+        
+        if (!empty($q['query']['addr_state'])) {
+            $v = $this->escape($q['query']['addr_state']);
+            $this->whereAdd("addr_state ILIKE '$v%'");
+        }
+        
+        if (isset($q['query']['addr_country'])) {
+            $this->whereAdd("addr_country !='' ");
+        }
+        
+        if (!empty($q['query']['addr_country'])) {
+            $this->whereAdd("addr_country LIKE '{$this->escape($q['query']['addr_country'])}%'");
+        }
+        
+        if (!empty($q['query']['addr_postalcode'])) {
+            $this->whereAdd("addr_postalcode LIKE '{$this->escape($q['query']['addr_postalcode'])}%'");
+        }
+        
+        
+    }
+    
+    function toShortArray()
+    {
+        $ar = $this->toArray();
+        $ret = array();
+        foreach ($ar as $k =>$v) {
+            $ret[substr($k,5)] = $v;
+        }
+        return $ret;
+        
+        
+        
+    }
+    function genNumber()
+    {
+        $l = trim($this->addr_line1);
+        if (empty($l)) {
+            $l = 'Address';
+        }
+        
+        $x = DB_DataObject::Factory('addr');
+        $suf = 0;
+        while ($x->get('addr_number', $l . (!$suf ? '' : '-' . $suf))) {
+            $x = DB_DataObject::Factory('addr');
+            $suf++;
+        }
+        // got a suf..
+        $this->addr_number = $l . (!$suf ? '' : '-' . $suf);
+        
+    }
+    
+    function createFromArray($addr)
+    {
+        $this->setFrom($addr);
+        $this->genNumber();
+        $this->insert();
+        
+        return $this;
+    }
+}
diff --git a/DataObjects/Address.php b/DataObjects/Address.php
new file mode 100644 (file)
index 0000000..2295f4d
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for address
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Address extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'address';             // table name
+    public $addr_id;                         // int4(4)  
+    public $addr_active;                     // bool(1)  
+    public $addr_line1;                      // text(-1)  
+    public $addr_line2;                      // text(-1)  
+    public $addr_line3;                      // text(-1)  
+    public $addr_city;                       // text(-1)  
+    public $addr_state;                      // text(-1)  
+    public $addr_postalcode;                 // text(-1)  
+    public $addr_country;                    // text(-1)  
+    public $addr_notes;                      // text(-1)  
+    public $addr_number;                     // text(-1)  
+    public $crmacct_id;                      // int4(4)  
+    public $crmacct_number;                  // text(-1)  
+    public $crmacct_name;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Alarm.php b/DataObjects/Alarm.php
new file mode 100644 (file)
index 0000000..2ad5be1
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for alarm
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Alarm extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'alarm';               // table name
+    public $alarm_id;                        // int4(4)  not_null default_nextval%28alarm_alarm_id_seq%29 primary_key
+    public $alarm_number;                    // text(-1)  not_null
+    public $alarm_event;                     // bool(1)  not_null default_false
+    public $alarm_email;                     // bool(1)  not_null default_false
+    public $alarm_sysmsg;                    // bool(1)  not_null default_false
+    public $alarm_trigger;                   // timestamptz(8)  
+    public $alarm_time;                      // timestamptz(8)  
+    public $alarm_time_offset;               // int4(4)  
+    public $alarm_time_qualifier;            // text(-1)  
+    public $alarm_creator;                   // text(-1)  
+    public $alarm_event_recipient;           // text(-1)  
+    public $alarm_email_recipient;           // text(-1)  
+    public $alarm_sysmsg_recipient;          // text(-1)  
+    public $alarm_source;                    // text(-1)  
+    public $alarm_source_id;                 // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apaccnt.php b/DataObjects/Apaccnt.php
new file mode 100644 (file)
index 0000000..67772f9
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for apaccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apaccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apaccnt';             // table name
+    public $apaccnt_id;                      // int4(4)  not_null default_nextval%28apaccnt_apaccnt_id_seq%29 primary_key
+    public $apaccnt_vendtype_id;             // int4(4)  
+    public $apaccnt_vendtype;                // text(-1)  
+    public $apaccnt_ap_accnt_id;             // int4(4)  not_null
+    public $apaccnt_prepaid_accnt_id;        // int4(4)  
+    public $apaccnt_discount_accnt_id;       // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apapply.php b/DataObjects/Apapply.php
new file mode 100644 (file)
index 0000000..8c6c0e9
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Table Definition for apapply
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apapply extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apapply';             // table name
+    public $apapply_id;                      // int4(4)  not_null default_nextval%28apapply_apapply_id_seq%29 primary_key
+    public $apapply_vend_id;                 // int4(4)  
+    public $apapply_postdate;                // date(4)  
+    public $apapply_username;                // text(-1)  
+    public $apapply_source_apopen_id;        // int4(4)  
+    public $apapply_source_doctype;          // text(-1)  
+    public $apapply_source_docnumber;        // text(-1)  
+    public $apapply_target_apopen_id;        // int4(4)  
+    public $apapply_target_doctype;          // text(-1)  
+    public $apapply_target_docnumber;        // text(-1)  
+    public $apapply_journalnumber;           // int4(4)  
+    public $apapply_amount;                  // numeric(-1)  
+    public $apapply_curr_id;                 // int4(4)  default_basecurrid%28%29
+    public $apapply_target_paid;             // numeric(-1)  
+    public $apapply_checkhead_id;            // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $apapply_checkhead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function checkhead() {
+        return func_num_args() ? $this->link('apapply_checkhead_id', func_get_arg(0)) : $this->link('apapply_checkhead_id');
+    }
+
+   /**
+    * Getter / Setter for $apapply_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('apapply_curr_id', func_get_arg(0)) : $this->link('apapply_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apchk.php b/DataObjects/Apchk.php
new file mode 100644 (file)
index 0000000..8c8ee75
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for apchk
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apchk extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apchk';               // table name
+    public $apchk_id;                        // int4(4)  
+    public $apchk_vend_id;                   // int4(4)  
+    public $apchk_bankaccnt_id;              // int4(4)  
+    public $apchk_printed;                   // bool(1)  
+    public $apchk_checkdate;                 // date(4)  
+    public $apchk_number;                    // int4(4)  
+    public $apchk_amount;                    // numeric(-1)  
+    public $apchk_void;                      // bool(1)  
+    public $apchk_replaced;                  // bool(1)  
+    public $apchk_posted;                    // bool(1)  
+    public $apchk_rec;                       // bool(1)  
+    public $apchk_misc;                      // bool(1)  
+    public $apchk_expcat_id;                 // int4(4)  
+    public $apchk_for;                       // text(-1)  
+    public $apchk_notes;                     // text(-1)  
+    public $apchk_journalnumber;             // int4(4)  
+    public $apchk_curr_id;                   // int4(4)  
+    public $apchk_deleted;                   // bool(1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apchkitem.php b/DataObjects/Apchkitem.php
new file mode 100644 (file)
index 0000000..57bd368
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Table Definition for apchkitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apchkitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apchkitem';           // table name
+    public $apchkitem_id;                    // int4(4)  
+    public $apchkitem_apchk_id;              // int4(4)  
+    public $apchkitem_vouchernumber;         // text(-1)  
+    public $apchkitem_ponumber;              // text(-1)  
+    public $apchkitem_amount;                // numeric(-1)  
+    public $apchkitem_invcnumber;            // text(-1)  
+    public $apchkitem_apopen_id;             // int4(4)  
+    public $apchkitem_docdate;               // date(4)  
+    public $apchkitem_curr_id;               // int4(4)  
+    public $apchkitem_discount;              // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apcreditapply.php b/DataObjects/Apcreditapply.php
new file mode 100644 (file)
index 0000000..19116c8
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for apcreditapply
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apcreditapply extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apcreditapply';       // table name
+    public $apcreditapply_id;                // int4(4)  not_null default_nextval%28apcreditapply_apcreditapply_id_seq%29 primary_key
+    public $apcreditapply_source_apopen_id;    // int4(4)  
+    public $apcreditapply_target_apopen_id;    // int4(4)  
+    public $apcreditapply_amount;            // numeric(-1)  
+    public $apcreditapply_curr_id;           // int4(4)  default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $apcreditapply_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('apcreditapply_curr_id', func_get_arg(0)) : $this->link('apcreditapply_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Api.account.php b/DataObjects/Api.account.php
new file mode 100644 (file)
index 0000000..4304a37
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Table Definition for api.account
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Api.account extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'api.account';         // table name
+    public $account_number;                  // varchar(-1)  
+    public $parent_account;                  // text(-1)  
+    public $account_name;                    // text(-1)  
+    public $active;                          // bool(1)  
+    public $type;                            // text(-1)  
+    public $primary_contact_number;          // text(-1)  
+    public $primary_contact_honorific;       // text(-1)  
+    public $primary_contact_first;           // text(-1)  
+    public $primary_contact_middle;          // text(-1)  
+    public $primary_contact_last;            // text(-1)  
+    public $primary_contact_suffix;          // text(-1)  
+    public $primary_contact_job_title;       // text(-1)  
+    public $primary_contact_voice;           // text(-1)  
+    public $primary_contact_fax;             // text(-1)  
+    public $primary_contact_email;           // text(-1)  
+    public $primary_contact_change;          // text(-1)  
+    public $primary_contact_address_number;    // text(-1)  
+    public $primary_contact_address1;        // text(-1)  
+    public $primary_contact_address2;        // text(-1)  
+    public $primary_contact_address3;        // text(-1)  
+    public $primary_contact_city;            // text(-1)  
+    public $primary_contact_state;           // text(-1)  
+    public $primary_contact_postalcode;      // text(-1)  
+    public $primary_contact_country;         // text(-1)  
+    public $primary_contact_address_change;    // text(-1)  
+    public $secondary_contact_number;        // text(-1)  
+    public $secondary_contact_honorific;     // text(-1)  
+    public $secondary_contact_first;         // text(-1)  
+    public $secondary_contact_middle;        // text(-1)  
+    public $secondary_contact_last;          // text(-1)  
+    public $secondary_contact_suffix;        // text(-1)  
+    public $secondary_contact_job_title;     // text(-1)  
+    public $secondary_contact_voice;         // text(-1)  
+    public $secondary_contact_fax;           // text(-1)  
+    public $secondary_contact_email;         // text(-1)  
+    public $secondary_contact_web;           // text(-1)  
+    public $secondary_contact_change;        // text(-1)  
+    public $secondary_contact_address_number;    // text(-1)  
+    public $secondary_contact_address1;      // text(-1)  
+    public $secondary_contact_address2;      // text(-1)  
+    public $secondary_contact_address3;      // text(-1)  
+    public $secondary_contact_city;          // text(-1)  
+    public $secondary_contact_state;         // text(-1)  
+    public $secondary_contact_postalcode;    // text(-1)  
+    public $secondary_contact_country;       // text(-1)  
+    public $secondary_contact_address_change;    // text(-1)  
+    public $notes;                           // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apopen.php b/DataObjects/Apopen.php
new file mode 100644 (file)
index 0000000..86f5c11
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Table Definition for apopen
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apopen extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apopen';              // table name
+    public $apopen_id;                       // int4(4)  not_null default_nextval%28%28%22apopen_apopen_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $apopen_docdate;                  // date(4)  
+    public $apopen_duedate;                  // date(4)  
+    public $apopen_terms_id;                 // int4(4)  
+    public $apopen_vend_id;                  // int4(4)  
+    public $apopen_doctype;                  // bpchar(-1)  
+    public $apopen_docnumber;                // text(-1)  
+    public $apopen_amount;                   // numeric(-1)  
+    public $apopen_notes;                    // text(-1)  
+    public $apopen_posted;                   // bool(1)  
+    public $apopen_reference;                // text(-1)  
+    public $apopen_invcnumber;               // text(-1)  
+    public $apopen_ponumber;                 // text(-1)  
+    public $apopen_journalnumber;            // int4(4)  
+    public $apopen_paid;                     // numeric(-1)  
+    public $apopen_open;                     // bool(1)  
+    public $apopen_username;                 // text(-1)  
+    public $apopen_discount;                 // bool(1)  not_null default_false
+    public $apopen_accnt_id;                 // int4(4)  default_%28-1%29
+    public $apopen_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $apopen_closedate;                // date(4)  
+    public $apopen_distdate;                 // date(4)  
+    public $apopen_void;                     // bool(1)  not_null default_false
+    public $apopen_curr_rate;                // numeric(-1)  not_null
+    public $apopen_discountable_amount;      // numeric(-1)  default_0
+    public $apopen_status;                   // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $apopen_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('apopen_curr_id', func_get_arg(0)) : $this->link('apopen_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        
+      if (isset($q['query']['vend_number'])) {
+            //DB_dataobject::debugLevel(1);
+            $cur = $q['query']['in_currency'];
+            
+            
+            $c = DB_DAtaObject::factory('vendinfo');
+            if (!$c->get('vend_number', $q['query']['vend_number'])) {
+                $roo->jerr("invalid vendor");
+            }
+            $this->apopen_vend_id = $c->pid();
+            
+            $this->selectAdd("
+                    currtocurr(apopen_curr_id, getcurrid('HKD'),   apopen_amount  ,apopen_distdate)  as apopen_amount_hkd,
+                    currtocurr(apopen_curr_id, getcurrid('HKD'),   apopen_paid   , apopen_distdate  ) as apopen_paid_hkd
+                    
+            ");
+   
+                
+                 
+            
+            $this->selectAdd(
+                "
+                   currtocurr(
+                            apopen_curr_id,
+                            getcurrid('HKD') ,
+                            CASE WHEN (apopen_doctype IN ('C', 'R')) THEN
+                                (apopen_amount - apopen_paid) * -1.0
+                                ELSE
+                                (apopen_amount - apopen_paid)
+                                END,
+                            apopen_distdate
+                            
+                   
+                    ) as apopen_remaining_hkd
+                "
+            );
+            
+            // need to show the original data..
+            $this->selectAdd("
+                 (apopen_docnumber || apopen_notes::text) as apopen_docnumber_r
+                 
+                
+            ");
+
+            
+            
+            $this->whereAdd("
+                    CASE WHEN (apopen_doctype IN ('C', 'R')) THEN
+                       (apopen_amount - apopen_paid) * -1.0
+                       ELSE
+                       (apopen_amount - apopen_paid)
+                       END
+                       != 0.0
+               ");
+            //$this->having('apopen_remaining != 0.0' );
+             
+        }
+    }
+    
+    function toRooArray($q)
+    {
+        static $total = 0;
+        
+        $ret = $this->toArray();
+        
+        if (!isset($q['query']['vend_number'])) {
+            return $ret;
+        }
+        
+        $total += $this->apopen_remaining_hkd;
+        $ret['apopen_running_hkd'] = $total;
+        return $ret;
+        
+        
+        
+    }
+}
diff --git a/DataObjects/Apopentax.php b/DataObjects/Apopentax.php
new file mode 100644 (file)
index 0000000..6cc0343
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for apopentax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apopentax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apopentax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Apselect.php b/DataObjects/Apselect.php
new file mode 100644 (file)
index 0000000..7ff2e6a
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for apselect
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Apselect extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'apselect';            // table name
+    public $apselect_id;                     // int4(4)  not_null default_nextval%28apselect_apselect_id_seq%29 primary_key
+    public $apselect_apopen_id;              // int4(4)  not_null unique_key
+    public $apselect_amount;                 // numeric(-1)  not_null
+    public $apselect_bankaccnt_id;           // int4(4)  
+    public $apselect_curr_id;                // int4(4)  default_basecurrid%28%29
+    public $apselect_date;                   // date(4)  
+    public $apselect_discount;               // numeric(-1)  not_null default_0.0
+
+    
+   /**
+    * Getter / Setter for $apselect_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('apselect_curr_id', func_get_arg(0)) : $this->link('apselect_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Araccnt.php b/DataObjects/Araccnt.php
new file mode 100644 (file)
index 0000000..b6dc6c6
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Table Definition for araccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Araccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'araccnt';             // table name
+    public $araccnt_id;                      // int4(4)  not_null default_nextval%28%28araccnt_araccnt_id_seq%29%3A%3Aregclass%29 primary_key
+    public $araccnt_custtype_id;             // int4(4)  
+    public $araccnt_custtype;                // text(-1)  
+    public $araccnt_freight_accnt_id;        // int4(4)  
+    public $araccnt_ar_accnt_id;             // int4(4)  
+    public $araccnt_prepaid_accnt_id;        // int4(4)  
+    public $araccnt_deferred_accnt_id;       // int4(4)  
+    public $araccnt_discount_accnt_id;       // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Arapply.php b/DataObjects/Arapply.php
new file mode 100644 (file)
index 0000000..0b26a14
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Table Definition for arapply
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Arapply extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'arapply';             // table name
+    public $arapply_id;                      // int4(4)  not_null default_nextval%28arapply_arapply_id_seq%29 primary_key
+    public $arapply_postdate;                // date(4)  
+    public $arapply_cust_id;                 // int4(4)  
+    public $arapply_source_doctype;          // text(-1)  
+    public $arapply_source_docnumber;        // text(-1)  
+    public $arapply_target_doctype;          // text(-1)  
+    public $arapply_target_docnumber;        // text(-1)  
+    public $arapply_fundstype;               // text(-1)  
+    public $arapply_refnumber;               // text(-1)  
+    public $arapply_applied;                 // numeric(-1)  
+    public $arapply_closed;                  // bool(1)  
+    public $arapply_journalnumber;           // text(-1)  
+    public $arapply_source_aropen_id;        // int4(4)  
+    public $arapply_target_aropen_id;        // int4(4)  
+    public $arapply_username;                // text(-1)  
+    public $arapply_curr_id;                 // int4(4)  default_basecurrid%28%29
+    public $arapply_distdate;                // date(4)  not_null
+    public $arapply_target_paid;             // numeric(-1)  
+    public $arapply_reftype;                 // text(-1)  
+    public $arapply_ref_id;                  // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $arapply_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('arapply_curr_id', func_get_arg(0)) : $this->link('arapply_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if(!empty($q['_application'])){
+            $this->applicationsView($q, $au, $roo);
+            return;
+        }
+    }
+    
+    function applicationsView($q, $au, $roo)
+    {
+        $cmhead = DB_DataObject::factory('cmhead');
+        $cmhead->get($q['_application']);
+
+        $aropen = DB_DataObject::factory('aropen');
+        $aropen->aropen_docnumber = $cmhead->cmhead_number;
+        $aropen->doctype = 'C';
+        if(!$aropen->find(true)){
+            $this->whereAdd("1=0");
+            return;
+        }
+        
+        $this->whereAdd("
+            arapply_target_aropen_id = {$aropen->pid()}
+            OR
+            arapply_source_aropen_id = {$aropen->pid()}
+        ");
+
+    }
+}
diff --git a/DataObjects/Arcreditapply.php b/DataObjects/Arcreditapply.php
new file mode 100644 (file)
index 0000000..9396691
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for arcreditapply
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Arcreditapply extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'arcreditapply';       // table name
+    public $arcreditapply_id;                // int4(4)  not_null default_nextval%28arcreditapply_arcreditapply_id_seq%29 primary_key
+    public $arcreditapply_source_aropen_id;    // int4(4)  
+    public $arcreditapply_target_aropen_id;    // int4(4)  
+    public $arcreditapply_amount;            // numeric(-1)  
+    public $arcreditapply_curr_id;           // int4(4)  default_basecurrid%28%29
+    public $arcreditapply_reftype;           // text(-1)  
+    public $arcreditapply_ref_id;            // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $arcreditapply_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('arcreditapply_curr_id', func_get_arg(0)) : $this->link('arcreditapply_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Aropen.php b/DataObjects/Aropen.php
new file mode 100644 (file)
index 0000000..0ac5243
--- /dev/null
@@ -0,0 +1,311 @@
+<?php
+/**
+ * Table Definition for aropen
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Aropen extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'aropen';              // table name
+    public $aropen_id;                       // int4(4)  not_null default_nextval%28%28%22aropen_aropen_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $aropen_docdate;                  // date(4)  not_null
+    public $aropen_duedate;                  // date(4)  not_null
+    public $aropen_terms_id;                 // int4(4)  
+    public $aropen_cust_id;                  // int4(4)  
+    public $aropen_doctype;                  // bpchar(-1)  
+    public $aropen_docnumber;                // text(-1)  
+    public $aropen_applyto;                  // text(-1)  
+    public $aropen_ponumber;                 // text(-1)  
+    public $aropen_amount;                   // numeric(-1)  not_null
+    public $aropen_notes;                    // text(-1)  
+    public $aropen_posted;                   // bool(1)  not_null default_false
+    public $aropen_salesrep_id;              // int4(4)  
+    public $aropen_commission_due;           // numeric(-1)  
+    public $aropen_commission_paid;          // bool(1)  
+    public $aropen_ordernumber;              // text(-1)  
+    public $aropen_cobmisc_id;               // int4(4)  
+    public $aropen_journalnumber;            // int4(4)  
+    public $aropen_paid;                     // numeric(-1)  
+    public $aropen_open;                     // bool(1)  
+    public $aropen_username;                 // text(-1)  
+    public $aropen_rsncode_id;               // int4(4)  
+    public $aropen_salescat_id;              // int4(4)  default_%28-1%29
+    public $aropen_accnt_id;                 // int4(4)  default_%28-1%29
+    public $aropen_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $aropen_closedate;                // date(4)  
+    public $aropen_distdate;                 // date(4)  
+    public $aropen_curr_rate;                // numeric(-1)  not_null
+    public $aropen_discount;                 // bool(1)  not_null default_false
+
+    
+   /**
+    * Getter / Setter for $aropen_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('aropen_curr_id', func_get_arg(0)) : $this->link('aropen_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (isset($q['_opencm'])) {
+            $this->applyFilterCM($q,$roo);
+            return;
+        }
+        
+        if (isset($q['query']['cust_number'])) {
+            //DB_dataobject::debugLevel(1);
+            $c = DB_DAtaObject::factory('custinfo');
+            if (!$c->get('cust_number', $q['query']['cust_number'])) {
+                $roo->jerr("invalid customer");
+            }
+            $this->aropen_cust_id = $c->pid();
+            
+            $this->selectAdd(
+                "
+                   CASE WHEN (aropen_doctype IN ('C', 'R')) THEN
+                       (aropen_amount - aropen_paid) * -1.0
+                       ELSE
+                       (aropen_amount - aropen_paid)
+                       END
+                       as aropen_remaining
+                "
+            );
+           // DB_DataObject::DebugLevel(1);
+            // need to show the original data..
+            $this->selectAdd("
+                
+                  CASE WHEN (aropen_doctype = 'I') THEN
+                       aropen_docnumber || ' - ' || (
+                                SELECT
+                                    invchead_notes
+                                from invchead
+                                where
+                                    invchead_invcnumber = aropen_docnumber
+                        )
+                        WHEN (aropen_doctype = 'C') THEN
+                            aropen_docnumber 
+                       ELSE
+                       (aropen_docnumber || ' - ' || aropen_notes)
+                       END
+                       as aropen_docnumber_r
+                 
+                
+            ");
+
+            
+            
+            $this->whereAdd("
+                    CASE WHEN (aropen_doctype IN ('C', 'R')) THEN
+                       (aropen_amount - aropen_paid) * -1.0
+                       ELSE
+                       (aropen_amount - aropen_paid)
+                       END
+                       != 0.0
+               ");
+            //$this->having('aropen_remaining != 0.0' );
+             
+        }
+        
+    }
+    
+    function applyFilterCM($q, $roo)
+    {
+        
+        if (empty($q['_for_cohead'])) {
+            $roo->jerr("no sales order set.");
+        }
+        //DB_Dataobject::debugLevel(1);
+        $co = DB_DataObject::factory('cohead');
+        $co->get($q['_for_cohead']);
+        $this->aropen_cust_id = $co->cust()->pid();;
+        
+        $this->selectAdd();
+        
+        $this->selectAdd("
+            aropen_id,
+            aropen_docnumber,
+            (cust_number || '-' || cust_name) AS customer,
+            aropen_amount,
+            (aropen_paid + COALESCE(prepared,0.0) + COALESCE(cashapplied,0.0)) AS applied,
+            (aropen_amount - aropen_paid - COALESCE(prepared,0.0) - COALESCE(cashapplied,0.0)) AS balance,
+            currConcat(aropen_curr_id) AS currAbbr,
+            'curr' AS aropen_amount_xtnumericrole,
+            'curr' AS applied_xtnumericrole,
+            'curr' AS balance_xtnumericrole
+        ");
+        
+         $where_openar = "
+            
+                     (aropen_doctype IN ('C', 'R'))
+                     AND
+                     (aropen_open)
+                     AND
+                     ((aropen_amount - aropen_paid - COALESCE(prepared,0.0) - COALESCE(cashapplied,0.0)) > 0.0)
+                     AND
+                     (aropen_cust_id=cust_id)
+            
+        ";
+        
+        
+        $orderby = '';
+        
+        if (!empty($q['_for_cobmisc_id'])) {
+            $q['_for_cobmisc_id'] = (int) $q['_for_cobmisc_id'];
+            
+            
+            // see if it's been posted..
+            
+            $cmisc = DB_DataObject::Factory('cobmisc');
+            $cmisc->get($q['_for_cobmisc_id']);
+            if (!empty($cmisc->cobmisc_invcnumber) && $cmisc->cobmisc_posted) {
+                // it's been posted
+                
+                $this->selectAdd("
+                    COALESCE(
+                        (SELECT sum(arapply_applied) FROM arapply WHERE
+                            arapply_target_doctype = 'I'
+                            AND
+                            arapply_target_docnumber = '{$cmisc->cobmisc_invcnumber}'
+                            AND
+                             arapply_source_aropen_id = aropen_id
+                        ), 0.0
+                    ) as applied
+                    
+                ");
+                
+            } else {
+                $this->selectAdd('0.0 as applied');
+            }
+            
+            $this->selectAdd("
+                COALESCE(
+                    (SELECT count(cobapply_id) FROM cobapply WHERE
+                        cobapply_cobmisc_id = {$q['_for_cobmisc_id']}
+                        AND
+                        cobapply_aropen_id = aropen_id
+                    ), 0
+                ) as toapply
+            "); 
+            //DB_DataObject::DebugLevel(1);
+            $orderby = "COALESCE(
+                    (SELECT count(cobapply_id) FROM cobapply WHERE
+                        cobapply_cobmisc_id = {$q['_for_cobmisc_id']}
+                        AND
+                        cobapply_aropen_id = aropen_id
+                    ), 0
+                ) DESC, ";
+            
+            
+            $where_openar = "
+                  ( {$where_openar} ) OR
+            
+                    aropen_id IN (SELECT cobapply_aropen_id FROM cobapply WHERE cobapply_cobmisc_id = {$q['_for_cobmisc_id']})
+                
+            
+            
+            ";
+            
+            
+            
+            
+            
+        } else {
+            
+            $this->selectAdd(' 0 as toapply, 0.0 as applied');
+            
+        }
+        //was left outer join??
+        
+        $this->_join = " 
+            LEFT  JOIN
+                (SELECT
+                    aropen_id AS prepared_aropen_id,
+                    SUM(checkitem_amount + checkitem_discount) AS prepared
+                    FROM checkhead
+                        JOIN checkitem
+                            ON (checkitem_checkhead_id=checkhead_id)
+                        JOIN aropen
+                            ON (checkitem_aropen_id=aropen_id)
+                        WHERE
+                            ((NOT checkhead_posted)
+                             AND
+                             (NOT checkhead_void))
+                        GROUP BY aropen_id
+                )
+                AS sub1
+                ON (prepared_aropen_id=aropen_id)
+            LEFT JOIN
+                (SELECT
+                        aropen_id AS cash_aropen_id,
+                        SUM(cashrcptitem_amount + cashrcptitem_discount) * -1.0 AS cashapplied
+                    FROM cashrcpt
+                        JOIN cashrcptitem
+                            ON (cashrcptitem_cashrcpt_id=cashrcpt_id)
+                        JOIN aropen
+                            ON (cashrcptitem_aropen_id=aropen_id)
+                        WHERE
+                            (NOT cashrcpt_posted)
+                        GROUP BY aropen_id
+                )
+                AS sub2
+                ON (cash_aropen_id=aropen_id)
+            LEFT JOIN
+                cust
+            ON
+                cust_id = aropen_cust_id
+        ";
+   
+        $this->joinAddCmhead();
+        $this->whereAdd($where_openar);
+        
+        
+        
+        $this->orderBy(" $orderby  aropen_docnumber DESC ");
+
+    }
+    
+    
+    
+    function toRooArray($q)
+    {
+        static $total = 0;
+        
+        $ret = $this->toArray();
+        
+        if (!isset($q['query']['cust_number'])) {
+            return $ret;
+        }
+        
+        $total += $this->aropen_remaining;
+        $ret['aropen_running'] = $total;
+        return $ret;
+        
+        
+        
+    }
+    
+    function joinAddCmhead()
+    {
+        $cmhead = DB_DataObject::factory('cmhead');
+        $this->_join .= "
+            LEFT JOIN cmhead join_aropen_cmhead_id
+            ON
+            join_aropen_cmhead_id.cmhead_number = aropen_docnumber
+            AND
+            join_aropen_cmhead_id.cmhead_cust_id = aropen_cust_id
+        ";
+        $this->selectAs($cmhead, 'join_aropen_%s', 'join_aropen_cmhead_id');
+    }
+    
+    
+}
diff --git a/DataObjects/Aropenco.php b/DataObjects/Aropenco.php
new file mode 100644 (file)
index 0000000..068feac
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for aropenco
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Aropenco extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'aropenco';            // table name
+    public $aropenco_aropen_id;              // int4(4)  not_null primary_key multiple_key
+    public $aropenco_cohead_id;              // int4(4)  not_null primary_key multiple_key
+    public $aropenco_amount;                 // numeric(-1)  not_null default_0.00
+    public $aropenco_curr_id;                // int4(4)  default_basecurrid%28%29
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Aropentax.php b/DataObjects/Aropentax.php
new file mode 100644 (file)
index 0000000..060edf6
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for aropentax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Aropentax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'aropentax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Asohist.php b/DataObjects/Asohist.php
new file mode 100644 (file)
index 0000000..00c1fe8
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Table Definition for asohist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Asohist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'asohist';             // table name
+    public $asohist_id;                      // int4(4)  not_null default_nextval%28asohist_asohist_id_seq%29 primary_key
+    public $asohist_cust_id;                 // int4(4)  
+    public $asohist_itemsite_id;             // int4(4)  
+    public $asohist_shipdate;                // date(4)  
+    public $asohist_invcdate;                // date(4)  
+    public $asohist_duedate;                 // date(4)  
+    public $asohist_promisedate;             // date(4)  
+    public $asohist_ordernumber;             // text(-1)  
+    public $asohist_invcnumber;              // text(-1)  
+    public $asohist_qtyshipped;              // numeric(-1)  
+    public $asohist_unitprice;               // numeric(-1)  
+    public $asohist_unitcost;                // numeric(-1)  
+    public $asohist_billtoname;              // text(-1)  
+    public $asohist_billtoaddress1;          // text(-1)  
+    public $asohist_billtoaddress2;          // text(-1)  
+    public $asohist_billtoaddress3;          // text(-1)  
+    public $asohist_billtocity;              // text(-1)  
+    public $asohist_billtostate;             // text(-1)  
+    public $asohist_billtozip;               // text(-1)  
+    public $asohist_shiptoname;              // text(-1)  
+    public $asohist_shiptoaddress1;          // text(-1)  
+    public $asohist_shiptoaddress2;          // text(-1)  
+    public $asohist_shiptoaddress3;          // text(-1)  
+    public $asohist_shiptocity;              // text(-1)  
+    public $asohist_shiptostate;             // text(-1)  
+    public $asohist_shiptozip;               // text(-1)  
+    public $asohist_shipto_id;               // int4(4)  
+    public $asohist_shipvia;                 // text(-1)  
+    public $asohist_salesrep_id;             // int4(4)  
+    public $asohist_misc_type;               // bpchar(-1)  
+    public $asohist_misc_descrip;            // text(-1)  
+    public $asohist_misc_id;                 // int4(4)  
+    public $asohist_commission;              // numeric(-1)  
+    public $asohist_commissionpaid;          // bool(1)  
+    public $asohist_doctype;                 // text(-1)  
+    public $asohist_orderdate;               // date(4)  
+    public $asohist_imported;                // bool(1)  
+    public $asohist_ponumber;                // text(-1)  
+    public $asohist_curr_id;                 // int4(4)  default_basecurrid%28%29
+    public $asohist_taxtype_id;              // int4(4)  
+    public $asohist_taxzone_id;              // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $asohist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('asohist_taxtype_id', func_get_arg(0)) : $this->link('asohist_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $asohist_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('asohist_taxzone_id', func_get_arg(0)) : $this->link('asohist_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $asohist_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('asohist_curr_id', func_get_arg(0)) : $this->link('asohist_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Asohisttax.php b/DataObjects/Asohisttax.php
new file mode 100644 (file)
index 0000000..bfd6c6e
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for asohisttax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Asohisttax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'asohisttax';          // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Atlasmap.php b/DataObjects/Atlasmap.php
new file mode 100644 (file)
index 0000000..1e53f29
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for atlasmap
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Atlasmap extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'atlasmap';            // table name
+    public $atlasmap_id;                     // int4(4)  not_null default_nextval%28atlasmap_atlasmap_id_seq%29 primary_key
+    public $atlasmap_name;                   // text(-1)  not_null unique_key
+    public $atlasmap_filter;                 // text(-1)  not_null
+    public $atlasmap_filtertype;             // text(-1)  not_null
+    public $atlasmap_atlas;                  // text(-1)  not_null
+    public $atlasmap_map;                    // text(-1)  not_null
+    public $atlasmap_headerline;             // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Backup_usr.php b/DataObjects/Backup_usr.php
new file mode 100644 (file)
index 0000000..7b810bc
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Table Definition for backup_usr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Backup_usr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'backup_usr';          // table name
+    public $usr_id;                          // int4(4)  
+    public $usr_username;                    // text(-1)  
+    public $usr_propername;                  // text(-1)  
+    public $usr_passwd;                      // text(-1)  
+    public $usr_locale_id;                   // int4(4)  
+    public $usr_initials;                    // text(-1)  
+    public $usr_agent;                       // bool(1)  
+    public $usr_active;                      // bool(1)  
+    public $usr_email;                       // text(-1)  
+    public $usr_dept_id;                     // int4(4)  
+    public $usr_shift_id;                    // int4(4)  
+    public $usr_window;                      // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bankaccnt.php b/DataObjects/Bankaccnt.php
new file mode 100644 (file)
index 0000000..fa6a775
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Table Definition for bankaccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bankaccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bankaccnt';           // table name
+    public $bankaccnt_id;                    // int4(4)  not_null default_nextval%28bankaccnt_bankaccnt_id_seq%29 primary_key
+    public $bankaccnt_name;                  // text(-1)  unique_key
+    public $bankaccnt_descrip;               // text(-1)  
+    public $bankaccnt_bankname;              // text(-1)  
+    public $bankaccnt_accntnumber;           // text(-1)  
+    public $bankaccnt_ar;                    // bool(1)  
+    public $bankaccnt_ap;                    // bool(1)  
+    public $bankaccnt_nextchknum;            // int4(4)  
+    public $bankaccnt_type;                  // bpchar(-1)  
+    public $bankaccnt_accnt_id;              // int4(4)  
+    public $bankaccnt_check_form_id;         // int4(4)  
+    public $bankaccnt_userec;                // bool(1)  
+    public $bankaccnt_rec_accnt_id;          // int4(4)  
+    public $bankaccnt_curr_id;               // int4(4)  default_basecurrid%28%29
+    public $bankaccnt_notes;                 // text(-1)  
+    public $bankaccnt_routing;               // text(-1)  not_null default_
+    public $bankaccnt_ach_enabled;           // bool(1)  not_null default_false
+    public $bankaccnt_ach_origin;            // text(-1)  not_null default_
+    public $bankaccnt_ach_genchecknum;       // bool(1)  not_null default_false
+    public $bankaccnt_ach_leadtime;          // int4(4)  
+    public $bankaccnt_ach_lastdate;          // date(4)  
+    public $bankaccnt_ach_lastfileid;        // bpchar(-1)  
+    public $bankaccnt_ach_origintype;        // text(-1)  
+    public $bankaccnt_ach_originname;        // text(-1)  
+    public $bankaccnt_ach_desttype;          // text(-1)  
+    public $bankaccnt_ach_fed_dest;          // text(-1)  
+    public $bankaccnt_ach_destname;          // text(-1)  
+    public $bankaccnt_ach_dest;              // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $bankaccnt_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('bankaccnt_curr_id', func_get_arg(0)) : $this->link('bankaccnt_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bankadj.php b/DataObjects/Bankadj.php
new file mode 100644 (file)
index 0000000..11197e7
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Table Definition for bankadj
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bankadj extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bankadj';             // table name
+    public $bankadj_id;                      // int4(4)  not_null default_nextval%28bankadj_bankadj_id_seq%29 primary_key
+    public $bankadj_bankaccnt_id;            // int4(4)  not_null
+    public $bankadj_bankadjtype_id;          // int4(4)  not_null
+    public $bankadj_created;                 // timestamp(8)  not_null default_now%28%29
+    public $bankadj_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $bankadj_date;                    // date(4)  not_null
+    public $bankadj_docnumber;               // text(-1)  
+    public $bankadj_amount;                  // numeric(-1)  not_null
+    public $bankadj_notes;                   // text(-1)  
+    public $bankadj_sequence;                // int4(4)  
+    public $bankadj_posted;                  // bool(1)  not_null default_false
+    public $bankadj_curr_id;                 // int4(4)  default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $bankadj_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('bankadj_curr_id', func_get_arg(0)) : $this->link('bankadj_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bankadjtype.php b/DataObjects/Bankadjtype.php
new file mode 100644 (file)
index 0000000..a26d6b0
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for bankadjtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bankadjtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bankadjtype';         // table name
+    public $bankadjtype_id;                  // int4(4)  not_null default_nextval%28bankadjtype_bankadjtype_id_seq%29 primary_key
+    public $bankadjtype_name;                // text(-1)  not_null unique_key
+    public $bankadjtype_descrip;             // text(-1)  
+    public $bankadjtype_accnt_id;            // int4(4)  not_null
+    public $bankadjtype_iscredit;            // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bankrec.php b/DataObjects/Bankrec.php
new file mode 100644 (file)
index 0000000..b22b407
--- /dev/null
@@ -0,0 +1,361 @@
+<?php
+/**
+ * Table Definition for bankrec
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bankrec extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bankrec';             // table name
+    public $bankrec_id;                      // int4(4)  not_null default_nextval%28bankrec_bankrec_id_seq%29 primary_key
+    public $bankrec_created;                 // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $bankrec_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $bankrec_bankaccnt_id;            // int4(4)  
+    public $bankrec_opendate;                // date(4)  
+    public $bankrec_enddate;                 // date(4)  
+    public $bankrec_openbal;                 // numeric(-1)  
+    public $bankrec_endbal;                  // numeric(-1)  
+    public $bankrec_posted;                  // bool(1)  default_false
+    public $bankrec_postdate;                // timestamp(8)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    
+    function applyFilters($q,$au,$roo)
+    {
+        
+        $roo->jerr("no access at present");
+                        
+    }
+    
+    /*
+     * this function is useless... delete it later
+     * 
+     */
+    function fix($roo)
+    {
+        // look for the last day that bankrec is completed totally.
+        // find the balance for that.. - that is the open date..
+        // 
+        // rather than looking at the last recorded data...
+        
+        
+        if (!empty($this->bankrec_id)) {
+            // updating a record..
+            // do nothign??
+            return;
+        }
+        // inserting..
+        $br = DB_DataObject::Factory('bankrec');
+        
+        $br->bankrec_posted = true;
+        $br->bankrec_bankaccnt_id = $this->bankrec_bankaccnt_id ;
+        $br->orderBy('bankrec_enddate DESC');
+        $br->limit(1);
+        if (!$br->find(true)) {
+            // first record.
+            $this->setFrom(array(
+                'bankrec_created' => date('Y-m-d H:i:s'),
+                'bankrec_username' => $roo->authUser->pgname(),
+//                'bankrec_opendate' => '2000-01-01',
+                'bankrec_openbal' => '0::numeric' // if just set 0, it will NULL in database
+            ));
+            return;
+                
+                
+        }
+        $this->setFrom(array(
+              'bankrec_created' => date('Y-m-d H:i:s'),
+              'bankrec_username' => $roo->authUser->pgname(),
+//              'bankrec_opendate' => date('Y-m-d', strtotime( $br->bankrec_enddate . ' + 1 DAY')),
+              'bankrec_openbal' => $br->bankrec_endbal
+         ));
+        
+         
+        
+        
+    }
+    
+    function lastForBankAcc($roo, $bankaccnt_id, $date)  {
+        $br = DB_DataObject::Factory('bankrec');
+        $br->joinAddBankaccnt();
+//        $br->bankrec_posted = false;
+        $br->bankrec_bankaccnt_id = $bankaccnt_id;
+        $br->bankrec_opendate = $date;
+        $br->bankrec_enddate = $date;
+        
+        if (!$br->find(true)) {
+            $br->setFrom(array(
+                'bankrec_created' => date('Y-m-d H:i:s'),
+                'bankrec_username' => $roo->authUser->pgname()
+            ));
+            
+            $br->insert();
+        }
+        
+        $old = clone ($br);
+        $br->bankrec_openbal = $this->fetchOpenBalanceBydate($bankaccnt_id, $date, $roo);
+        $br->update($old);
+        
+        if(!$br->pid()){
+            $roo->jerr("Error occur on getting bankrec! bankaccnt_id : {$bankaccnt_id}. date : {$date}");
+        }
+        
+        if($br->bankrec_posted){
+            $roo->jerr("Please Void Reconcilation frist");
+        }
+        
+        return $br;
+        
+        
+    }
+    
+    
+      
+    
+    function joinAddBankaccnt()
+    {
+        $this->_join .= "
+            LEFT JOIN bankaccnt AS join_bankrec_bankaccnt_id_bankaccnt_id
+                ON (join_bankrec_bankaccnt_id_bankaccnt_id.bankaccnt_id=bankrec.bankrec_bankaccnt_id)
+                
+            ";
+        $bankaccnt= DB_DataObject::factory('bankaccnt');
+        $this->selectAs($bankaccnt, 'bankrec_bankaccnt_id_%s', 'join_bankrec_bankaccnt_id_bankaccnt_id');
+        
+        
+    }
+    
+    
+    
+    
+    function updateTotals($roo)
+    {
+        
+        if ($this->bankrec_posted) {
+            $roo->jerr("already posted");
+        }
+        // a bit simplistic...
+        $old = clone($this);
+        $bi = DB_DataObject::factory('bankrecitem');
+        /*
+         * 
+         * useless for us!
+         * 
+         * UNION ALL
+         SELECT CASE WHEN (sltrans_amount > 0) THEN bankrecitem_amount * -1.0
+                     ELSE bankrecitem_amount END AS amount
+           FROM bankaccnt, sltrans, bankrecitem
+          WHERE ((sltrans_accnt_id=bankaccnt_accnt_id)
+            AND (bankrecitem_source='SL')
+            AND (bankrecitem_source_id=sltrans_id)
+            AND (bankrecitem_bankrec_id= {$this->pid()})
+            AND (bankrecitem_cleared)
+            AND (NOT sltrans_rec)
+            AND (bankaccnt_id=  {$this->bankrec_bankaccnt_id}) )
+          UNION ALL
+         SELECT CASE WHEN(bankadjtype_iscredit=true) THEN (bankadj_amount * -1) ELSE bankadj_amount END AS amount
+           FROM bankadj, bankadjtype, bankrecitem
+          WHERE ( (bankrecitem_source='AD')
+            AND (bankrecitem_source_id=bankadj_id)
+            AND (bankrecitem_bankrec_id= {$this->pid()})
+            AND (bankrecitem_cleared)
+            AND (bankadj_bankadjtype_id=bankadjtype_id)
+            AND (NOT bankadj_posted)
+            AND (bankadj_bankaccnt_id= {$this->pid()}) )
+         * 
+         * 
+         * 
+         */
+        $bi->query("
+SELECT (COALESCE(SUM(amount),0.0) + {$this->bankrec_openbal}) AS cleared_amount 
+      
+  FROM ( SELECT CASE WHEN (gltrans_amount > 0) THEN bankrecitem_amount * -1.0
+                     ELSE bankrecitem_amount END AS amount
+           FROM bankaccnt, gltrans, bankrecitem
+          WHERE ((gltrans_accnt_id=bankaccnt_accnt_id)
+            AND (bankrecitem_source='GL')
+            AND (bankrecitem_source_id=gltrans_id)
+            AND (bankrecitem_bankrec_id= {$this->pid()})
+            AND (bankrecitem_cleared)
+            AND (NOT gltrans_rec)
+            AND (bankaccnt_id={$this->bankrec_bankaccnt_id}) ) 
+           ) AS data;
+            
+            ");
+        $bi->fetch();
+        
+        $this->bankrec_endbal = $bi->cleared_amount;
+        $this->update($old);
+        
+        
+    }
+     
+    
+    function beforeInsert($q, $roo)
+    {
+        if (!empty($q['_fix'])) {
+            $this->fixHistorical($roo);
+        }
+        
+        if(!empty($q['_closedPeriod'])){
+            $this->postClosedPeriod($roo);
+        }
+        
+        if (!empty($q['_post'])) {
+            $this->post($q,$roo);
+        }
+        if (!empty($q['_void'])) {
+            
+            if (empty($q['bankaccnt_id'])) {
+                $roo->jerr("missing bank accnt id");
+            }
+
+            if (empty($q['sotrdate'])) {
+                $roo->jerr("missing  a date");
+            }
+
+            $br = DB_DataObject::factory('bankrec');
+            $br->bankrec_bankaccnt_id = $q['bankaccnt_id'];
+            $br->bankrec_opendate = $q['sotrdate'];
+            $br->bankrec_enddate = $q['sotrdate'];
+            $br->bankrec_posted = true;
+
+            if(!$br->find(true)){
+                $roo->jerr("Error occur on getting a posted back reconciliation. bankaccnt_id : {$q['bankaccnt_id']}, date : {$q['sotrdate']}");
+            }
+            
+            $br->void($roo);
+        }
+        
+        $roo->jerr('insert not allowed.');
+    }
+    
+    function beforeUpdate($old, $q, $roo)
+    {   
+        $roo->jerr('update not allowed.');
+        
+    }
+    function closeData($bankaccnt_id, $sortdate, $roo)
+    {
+        // 
+        $br = $this->lastForBankAcc($roo,$bankaccnt_id, $sortdate);
+        
+        $bi = DB_DataObject::factory('bankrecitem');
+        $bi->bankrecitem_bankrec_id = $br->pid();
+        if (!$bi->count()) {
+            $roo->jerr("no items to close");
+        }
+        
+        if ($br->bankrec_posted) {
+            $roo->jerr("already posted");
+        }
+        
+        $xbi = clone($bi);
+        $xbi->query("DELETE FROM bankrecitem where bankrecitem_cleared = false and bankrecitem_bankrec_id = {$br->pid()}");
+        
+        // find the last date of an item.
+        $xbi = clone($bi);
+        $xbi->bankrecitem_cleared = false;
+        if ($xbi->count()) {
+            $roo->jerr("has uncleared items");
+        }
+        // now the really complex one..
+        $meta = DB_DAtaObject::Factory('metasql');
+        $queryinfo = $meta->buildReportQuery(array(
+                '_group' => 'bankrec',
+                '_name' => 'all',
+                'bankrecid:number' => $br->pid(),
+                'bankaccntid:number' => $br->bankrec_bankaccnt_id,
+                'sortdate:text' => $br->bankrec_opendate
+                ),$roo);
+        
+        $query = $queryinfo['query'];
+        
+        $meta = DB_DAtaObject::Factory('metasql');
+        $meta->query("SELECT COALESCE(count(id),0) as notcleared FROM ( $query ) mquery WHERE cleared = false");
+        $meta->fetch();
+        $notcleared = $meta->notcleared;
+        if ($notcleared ) {
+            $roo->jerr("some entries are not cleared");
+        }
+        $br->updateTotals($roo);
+        return $br;
+         
+        
+    }
+    
+    function post($q,$roo)
+    {
+        if (empty($q['bankaccnt_id'])) {
+            $roo->jerr("missing bank accnt id");
+        }
+        
+        if (empty($q['sotrdate'])) {
+            $roo->jerr("missing  a date");
+        }
+        
+        $cr = $this->closeData($q['bankaccnt_id'], $q['sotrdate'], $roo);
+
+        $br = DB_DataObject::Factory('bankrec');
+        $br->query("SELECT postBankReconciliation({$cr->pid()}) ");
+        $roo->jok("posted");
+        
+        
+    }
+    
+    function void($roo)
+    {
+        $br = DB_DataObject::Factory('bankrec');
+        $br->query("SELECT voidbankreconciliation({$this->pid()}) AS result");
+        $br->fetch();
+        if($br->result < 0){
+            $roo->jerr("Error occur on voiding bank reconciliation! bankrec_id : {$this->pid()}, result : {$br->result}");
+        }
+        $roo->jok("Voided");
+        
+    }
+    
+    
+    function fetchOpenBalanceBydate($bankaccnt_id, $date, $roo)
+    {
+        $meta = DB_DAtaObject::Factory('metasql');
+        $queryinfo = $meta->buildReportQuery(array(
+            '_group' => 'bankrec',
+            '_name' => 'all',
+            'bankaccntid:number' => $bankaccnt_id,
+            'cals:text' => $date
+
+            ),$roo);
+
+        $query = $queryinfo['query'];
+
+        $query = "SELECT COALESCE(sum(amount),0) as amount FROM ($query) mquery";
+        $do = DB_DataObject::Factory('metasql');
+        $do->query($query);
+        $do->fetch();
+        return $do->amount;
+    }
+    
+    function fixHistorical($roo)
+    {
+        $br = DB_DataObject::Factory('bankrec');
+        $br->query("SELECT bankrec_fix_historical_all() AS result");
+        $roo->jok("FIXED");
+    }
+    
+    function postClosedPeriod($roo)
+    {
+        $br = DB_DataObject::Factory('bankrec');
+        $br->query("SELECT bankrec_post_closed_period() AS result");
+        $roo->jok("DONE");
+    }
+    
+    
+}
diff --git a/DataObjects/Bankrecitem.php b/DataObjects/Bankrecitem.php
new file mode 100644 (file)
index 0000000..8698f6a
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+/**
+ * Table Definition for bankrecitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bankrecitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bankrecitem';         // table name
+    public $bankrecitem_id;                  // int4(4)  not_null default_nextval%28bankrecitem_bankrecitem_id_seq%29 primary_key
+    public $bankrecitem_bankrec_id;          // int4(4)  not_null
+    public $bankrecitem_source;              // text(-1)  not_null
+    public $bankrecitem_source_id;           // int4(4)  not_null
+    public $bankrecitem_cleared;             // bool(1)  default_false
+
+    public $bankrecitem_curr_rate;
+    public $bankrecitem_amount;
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function beforeInsert($q, $roo)
+    {
+        if (!empty($q['remove_clear'])) {
+            $this->unclearItems($q,$roo);
+      
+            
+        }
+        
+        if (!empty($q['set_clear'])) {
+            $this->clearItems($q,$roo);
+       
+        }
+        if (!empty($q['set_amount'])) {
+            $this->adjAmount($q,$roo);
+       
+        }
+        
+        
+        $roo->jerr("no data to sent");
+    }   
+        
+    function unclearItems($q,$roo)
+    {
+        
+        $data = json_decode($q['remove_clear']);
+        $brids  = array();
+        foreach($data as $row)
+        {
+            $bankrecitem = DB_DAtaObject::Factory('bankrecitem');
+            $bankrecitem->joinAddBankrec();
+            
+            switch($row->altid * 1) {
+                case 1:
+                    $bankrecitem->bankrecitem_source = 'GL';
+                    $bankrecitem->bankrecitem_source_id = $row->id;
+                    break;
+                default:
+                    $roo->jerr("fixme - not supported yet altid = ({$row->altid})");
+            }
+            
+            if (!$bankrecitem->find(true)) {
+                $roo->jerr("could not find bankrec item");
+            }
+            if (!$bankrecitem->bankrecitem_cleared) {
+                $roo->jerr("not cleared?!");
+
+            }
+            if ($bankrecitem->bankrecitem_bankrec_id_bankrec_posted) {
+                $roo->jerr("already posted");
+            }
+            
+            if (!in_array($bankrecitem->bankrecitem_bankrec_id, $brids)) {
+                $brids[] = $bankrecitem->bankrecitem_bankrec_id;
+            }
+            
+            $old = clone($bankrecitem);
+            
+            $bankrecitem->bankrecitem_cleared  =  false;
+                    
+            $bankrecitem->update($old);
+            
+            
+        }
+        foreach($brids as $brid) {
+            $bankrec = DB_DataObject::factory('bankrec');
+            $bankrec->get($brid);
+            $bankrec->updateTotals($roo);
+        }
+        
+        $roo->jok("updated");
+        
+        
+    }
+    
+    function gltrans($roo)
+    {
+        if ($this->bankrecitem_source !='GL') {
+            $roo->jerr("invalid reference");
+        }
+        $gl = DB_DataObject::Factory('gltrans');
+        if (!$gl->get($this->bankrecitem_source_id)) {
+            $roo->jerr("no source transaction");
+        }
+        return $gl;
+        
+        
+    }
+    
+    
+    function adjAmount($q,$roo)
+    {
+        // user has entered a different value for the amount..
+        
+        $bankrec = DB_DataObject::factory('bankrec');
+        $bankrec = $bankrec->lastForBankAcc($roo, $q['bankaccnt_id'], $q['sortdate']);
+        
+        $bankrecitem = DB_DAtaObject::Factory('bankrecitem');
+            
+        switch($q['altid'] * 1) {
+            case 1:
+                $bankrecitem->bankrecitem_source = 'GL';
+                $bankrecitem->bankrecitem_source_id = $q['source_id'];
+                break;
+            default:
+                $roo->jerr("fixme - not supported yet altid = ({$q['source_id']})");
+        }
+        
+        $bankrecitem->find(true);
+        if ($bankrecitem->bankrecitem_cleared) {
+            $roo->jerr("already cleared?! - unclear first.");
+
+        }
+        /// FIXME when we support other types..
+        $gl = $bankrecitem->gltrans($roo);
+        $base = abs($gl->gltrans_amount);
+        $new = abs($q['set_amount']);
+        $rate = $new  / $base;
+        
+        //$roo->jerr('rate : '. $rate . " base = $base, new= $new");
+        
+        $old = clone($bankrecitem);
+        
+        $bankrecitem->setFrom(array(
+                'bankrecitem_bankrec_id' => $bankrec->pid(),
+                'bankrecitem_cleared' => false,
+                'bankrecitem_curr_rate' => $rate,
+                'bankrecitem_amount' => $new, // ignore negative +ve..
+        ));
+        $bankrecitem->bankrecitem_id ? $bankrecitem->update($old) : $bankrecitem->insert();
+        $roo->jok("updated");
+    }
+    
+    
+    function clearItems($q,$roo)
+    {
+        
+        $bankrec = DB_DataObject::factory('bankrec');
+        $bankrec = $bankrec->lastForBankAcc($roo, $q['bankaccnt_id'], $q['sortdate']);
+        
+        $data = json_decode($q['set_clear']);
+        foreach($data as $row)
+        {
+            $bankrecitem = DB_DAtaObject::Factory('bankrecitem');
+            
+            switch($row->altid * 1) {
+                case 1:
+                    $bankrecitem->bankrecitem_source = 'GL';
+                    $bankrecitem->bankrecitem_source_id = $row->id;
+                    break;
+                default:
+                    $roo->jerr("fixme - not supported yet altid = ({$row->altid})");
+            }
+            
+            $bankrecitem->find(true);
+            if ($bankrecitem->bankrecitem_cleared) {
+                $roo->jerr("already cleared?!");
+
+            }
+            
+            $old = clone($bankrecitem);
+            
+            $bankrecitem->setFrom(array(
+                    'bankrecitem_bankrec_id' => $bankrec->pid(),
+                    'bankrecitem_cleared' => true,
+                    'bankrecitem_curr_rate' => $row->curr_rate,
+                    'bankrecitem_amount' => abs($row->amount), // ignore negative +ve..
+            ));
+            $bankrecitem->bankrecitem_id ? $bankrecitem->update($old) : $bankrecitem->insert();
+            
+            
+        }
+        $bankrec->updateTotals($roo);
+        $roo->jok("updated");
+         
+        
+        
+    }
+    
+    
+    function joinAddBankrec()
+    {
+        $this->_join .= "
+            LEFT JOIN bankrec AS join_bankrecitem_bankrec_id_bankrec_id
+                ON (join_bankrecitem_bankrec_id_bankrec_id.bankrec_id=bankrecitem.bankrecitem_bankrec_id)
+                
+            ";
+        $bankrec = DB_DataObject::factory('bankrec');
+        $this->selectAs($bankrec, 'bankrecitem_bankrec_id_%s', 'join_bankrecitem_bankrec_id_bankrec_id');
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Billingeditlist.php b/DataObjects/Billingeditlist.php
new file mode 100644 (file)
index 0000000..472c021
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Table Definition for billingeditlist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Billingeditlist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'billingeditlist';     // table name
+    public $orderid;                         // int4(4)  
+    public $itemid;                          // int4(4)  
+    public $documentnumber;                  // text(-1)  
+    public $cust_number;                     // text(-1)  
+    public $billtoname;                      // text(-1)  
+    public $ordernumber;                     // text(-1)  
+    public $linenumber;                      // int4(4)  
+    public $item;                            // text(-1)  
+    public $itemdescrip;                     // text(-1)  
+    public $iteminvuom;                      // text(-1)  
+    public $qtytobill;                       // numeric(-1)  
+    public $f_qtytobill;                     // text(-1)  
+    public $price;                           // numeric(-1)  
+    public $f_price;                         // text(-1)  
+    public $extprice;                        // numeric(-1)  
+    public $f_extprice;                      // text(-1)  
+    public $sence;                           // text(-1)  
+    public $account;                         // text(-1)  
+    public $curr_id;                         // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bomhead.php b/DataObjects/Bomhead.php
new file mode 100644 (file)
index 0000000..2950b66
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Table Definition for bomhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bomhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bomhead';             // table name
+    public $bomhead_id;                      // int4(4)  not_null default_nextval%28%28%22bomhead_bomhead_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $bomhead_item_id;                 // int4(4)  not_null
+    public $bomhead_serial;                  // int4(4)  
+    public $bomhead_docnum;                  // text(-1)  
+    public $bomhead_revision;                // text(-1)  
+    public $bomhead_revisiondate;            // date(4)  
+    public $bomhead_batchsize;               // numeric(-1)  
+    public $bomhead_requiredqtyper;          // numeric(-1)  
+    public $bomhead_rev_id;                  // int4(4)  default_%28-1%29
+
+    
+   /**
+    * Getter / Setter for $bomhead_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('bomhead_item_id', func_get_arg(0)) : $this->link('bomhead_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bomitem.php b/DataObjects/Bomitem.php
new file mode 100644 (file)
index 0000000..1719ad4
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Table Definition for bomitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bomitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bomitem';             // table name
+    public $bomitem_id;                      // int4(4)  not_null default_nextval%28%28bomitem_bomitem_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $bomitem_parent_item_id;          // int4(4)  not_null
+    public $bomitem_seqnumber;               // int4(4)  
+    public $bomitem_item_id;                 // int4(4)  not_null
+    public $bomitem_qtyper;                  // numeric(-1)  not_null
+    public $bomitem_scrap;                   // numeric(-1)  not_null
+    public $bomitem_status;                  // bpchar(-1)  
+    public $bomitem_effective;               // date(4)  not_null
+    public $bomitem_expires;                 // date(4)  not_null
+    public $bomitem_createwo;                // bool(1)  not_null
+    public $bomitem_issuemethod;             // bpchar(-1)  not_null
+    public $bomitem_schedatwooper;           // bool(1)  not_null
+    public $bomitem_ecn;                     // text(-1)  
+    public $bomitem_moddate;                 // date(4)  
+    public $bomitem_subtype;                 // bpchar(-1)  not_null
+    public $bomitem_uom_id;                  // int4(4)  not_null
+    public $bomitem_rev_id;                  // int4(4)  default_%28-1%29
+    public $bomitem_booitem_seq_id;          // int4(4)  default_%28-1%29
+    public $bomitem_char_id;                 // int4(4)  
+    public $bomitem_value;                   // text(-1)  
+    public $bomitem_notes;                   // text(-1)  
+    public $bomitem_ref;                     // text(-1)  
+    public $bomitem_qtyfxd;                  // numeric(-1)  not_null default_0
+
+    
+   /**
+    * Getter / Setter for $bomitem_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('bomitem_item_id', func_get_arg(0)) : $this->link('bomitem_item_id');
+    }
+
+   /**
+    * Getter / Setter for $bomitem_parent_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent_item() {
+        return func_num_args() ? $this->link('bomitem_parent_item_id', func_get_arg(0)) : $this->link('bomitem_parent_item_id');
+    }
+
+   /**
+    * Getter / Setter for $bomitem_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function uom() {
+        return func_num_args() ? $this->link('bomitem_uom_id', func_get_arg(0)) : $this->link('bomitem_uom_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bomitemsub.php b/DataObjects/Bomitemsub.php
new file mode 100644 (file)
index 0000000..0105ac6
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for bomitemsub
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bomitemsub extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bomitemsub';          // table name
+    public $bomitemsub_id;                   // int4(4)  not_null default_nextval%28bomitemsub_bomitemsub_id_seq%29 primary_key
+    public $bomitemsub_bomitem_id;           // int4(4)  not_null
+    public $bomitemsub_item_id;              // int4(4)  not_null
+    public $bomitemsub_uomratio;             // numeric(-1)  not_null
+    public $bomitemsub_rank;                 // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $bomitemsub_bomitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function bomitem() {
+        return func_num_args() ? $this->link('bomitemsub_bomitem_id', func_get_arg(0)) : $this->link('bomitemsub_bomitem_id');
+    }
+
+   /**
+    * Getter / Setter for $bomitemsub_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('bomitemsub_item_id', func_get_arg(0)) : $this->link('bomitemsub_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Bomwork.php b/DataObjects/Bomwork.php
new file mode 100644 (file)
index 0000000..6611b34
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for bomwork
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Bomwork extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'bomwork';             // table name
+    public $bomwork_id;                      // int4(4)  not_null default_nextval%28bomwork_bomwork_id_seq%29 primary_key
+    public $bomwork_set_id;                  // int4(4)  
+    public $bomwork_seqnumber;               // int4(4)  
+    public $bomwork_item_id;                 // int4(4)  
+    public $bomwork_item_type;               // bpchar(-1)  
+    public $bomwork_qtyper;                  // numeric(-1)  
+    public $bomwork_scrap;                   // numeric(-1)  
+    public $bomwork_status;                  // bpchar(-1)  
+    public $bomwork_level;                   // int4(4)  
+    public $bomwork_parent_id;               // int4(4)  
+    public $bomwork_effective;               // date(4)  
+    public $bomwork_expires;                 // date(4)  
+    public $bomwork_stdunitcost;             // numeric(-1)  
+    public $bomwork_actunitcost;             // numeric(-1)  
+    public $bomwork_parent_seqnumber;        // int4(4)  
+    public $bomwork_createwo;                // bool(1)  
+    public $bomwork_issuemethod;             // bpchar(-1)  
+    public $bomwork_char_id;                 // int4(4)  
+    public $bomwork_value;                   // text(-1)  
+    public $bomwork_notes;                   // text(-1)  
+    public $bomwork_ref;                     // text(-1)  
+    public $bomwork_bomitem_id;              // int4(4)  
+    public $bomwork_ecn;                     // text(-1)  
+    public $bomwork_qtyfxd;                  // numeric(-1)  not_null default_0
+    public $bomwork_qtyreq;                  // numeric(-1)  not_null default_0
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Budget.php b/DataObjects/Budget.php
new file mode 100644 (file)
index 0000000..a5b8406
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for budget
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Budget extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'budget';              // table name
+    public $budget_id;                       // int4(4)  
+    public $budget_period_id;                // int4(4)  
+    public $budget_accnt_id;                 // int4(4)  
+    public $budget_amount;                   // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Budghead.php b/DataObjects/Budghead.php
new file mode 100644 (file)
index 0000000..bd7d9bb
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for budghead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Budghead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'budghead';            // table name
+    public $budghead_id;                     // int4(4)  not_null default_nextval%28budghead_budghead_id_seq%29 primary_key
+    public $budghead_name;                   // text(-1)  not_null unique_key
+    public $budghead_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Budgitem.php b/DataObjects/Budgitem.php
new file mode 100644 (file)
index 0000000..d5b81b4
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for budgitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Budgitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'budgitem';            // table name
+    public $budgitem_id;                     // int4(4)  not_null default_nextval%28budgitem_budgitem_id_seq%29 primary_key
+    public $budgitem_budghead_id;            // int4(4)  not_null
+    public $budgitem_period_id;              // int4(4)  not_null
+    public $budgitem_accnt_id;               // int4(4)  not_null
+    public $budgitem_amount;                 // numeric(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $budgitem_budghead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function budghead() {
+        return func_num_args() ? $this->link('budgitem_budghead_id', func_get_arg(0)) : $this->link('budgitem_budghead_id');
+    }
+
+   /**
+    * Getter / Setter for $budgitem_period_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function period() {
+        return func_num_args() ? $this->link('budgitem_period_id', func_get_arg(0)) : $this->link('budgitem_period_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Calhead.php b/DataObjects/Calhead.php
new file mode 100644 (file)
index 0000000..e946535
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for calhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Calhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'calhead';             // table name
+    public $calhead_id;                      // int4(4)  not_null default_nextval%28%28%22calhead_calhead_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $calhead_type;                    // bpchar(-1)  
+    public $calhead_name;                    // text(-1)  
+    public $calhead_descrip;                 // text(-1)  
+    public $calhead_origin;                  // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cashrcpt.php b/DataObjects/Cashrcpt.php
new file mode 100644 (file)
index 0000000..12dadca
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Table Definition for cashrcpt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cashrcpt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cashrcpt';            // table name
+    public $cashrcpt_id;                     // int4(4)  not_null default_nextval%28cashrcpt_cashrcpt_id_seq%29 primary_key
+    public $cashrcpt_cust_id;                // int4(4)  not_null
+    public $cashrcpt_amount;                 // numeric(-1)  not_null
+    public $cashrcpt_fundstype;              // bpchar(-1)  not_null
+    public $cashrcpt_docnumber;              // text(-1)  
+    public $cashrcpt_bankaccnt_id;           // int4(4)  not_null
+    public $cashrcpt_notes;                  // text(-1)  
+    public $cashrcpt_distdate;               // date(4)  default_%28now%29%3A%3Adate
+    public $cashrcpt_salescat_id;            // int4(4)  default_%28-1%29
+    public $cashrcpt_curr_id;                // int4(4)  default_basecurrid%28%29
+    public $cashrcpt_usecustdeposit;         // bool(1)  not_null default_false
+    public $cashrcpt_void;                   // bool(1)  not_null default_false
+    public $cashrcpt_number;                 // text(-1)  unique_key
+    public $cashrcpt_docdate;                // date(4)  
+    public $cashrcpt_posted;                 // bool(1)  not_null default_false
+    public $cashrcpt_posteddate;             // date(4)  
+    public $cashrcpt_postedby;               // text(-1)  
+    public $cashrcpt_applydate;              // date(4)  
+    public $cashrcpt_discount;               // numeric(-1)  not_null default_0.00
+
+    
+   /**
+    * Getter / Setter for $cashrcpt_bankaccnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function bankaccnt() {
+        return func_num_args() ? $this->link('cashrcpt_bankaccnt_id', func_get_arg(0)) : $this->link('cashrcpt_bankaccnt_id');
+    }
+
+   /**
+    * Getter / Setter for $cashrcpt_cust_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cust() {
+        return func_num_args() ? $this->link('cashrcpt_cust_id', func_get_arg(0)) : $this->link('cashrcpt_cust_id');
+    }
+
+   /**
+    * Getter / Setter for $cashrcpt_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cashrcpt_curr_id', func_get_arg(0)) : $this->link('cashrcpt_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function beforeInsert($request,$roo)
+    {
+        if(empty($this->cashrcpt_number)){
+            $cr = DB_DataObject::Factory('cashrcpt');
+            $cr->query("SELECT fetchCashRcptNumber() AS number");
+            $cr->fetch();
+            $this->cashrcpt_number = $cr->number;
+        }
+    }
+    
+    function onInsert($request,$roo)
+    {
+        $this->applyCashReceiptLineBalance($request, $roo);
+        $this->post($roo);
+        
+    }
+    
+    function beforeUpdate($old, $request,$roo)
+    {
+        if(isset($request['_void'])){
+            $this->void($roo);
+            $roo->jok('VOIDED');
+        }
+    }
+    
+    function applyCashReceiptLineBalance($request,$roo)
+    {
+        if(empty($request['cashrcpt_aropen_id'])){
+            $roo->jerr('Missing aropen id');
+        }
+        $request['cashrcpt_aropen_id'] = (int) $request['cashrcpt_aropen_id'];
+        $ci = DB_DataObject::Factory('cashrcptitem');
+        $ci->query("SELECT applyCashReceiptLineBalance($this->cashrcpt_id, {$request['cashrcpt_aropen_id']}, $this->cashrcpt_amount, $this->cashrcpt_curr_id ) AS result");
+        $ci->fetch();
+        if($ci->result == 0){
+            $this->jerr('error occur on apply cash receipt to balance' . $ci->result);
+        }
+        
+    }
+    
+    function post($roo)
+    {
+        $cr = DB_DataObject::Factory('cashrcpt');
+        $cr->query("SELECT fetchJournalNumber('C/R') AS journalnumber");
+        $cr->fetch();
+        $journalnumber = $cr->journalnumber;
+        
+        $cr = DB_DataObject::Factory('cashrcpt');
+        $cr->query("SELECT postCashReceipt($this->cashrcpt_id, $journalnumber) AS result");
+        $cr->fetch();
+        if($cr->result < 1){
+            $this->jerr('error occur on post cash receipt' . $cr->result);
+        }
+    }
+    
+    /*
+     *  void cash receipt
+     *  reversecashreceipt(integer, integer)
+     *  pCashrcptid     ALIAS FOR $1;
+     *  pJournalNumber  ALIAS FOR $2;
+     */
+    
+    function void($roo)
+    {
+        $ch = DB_DataObject::Factory('cashrcpt');
+        
+        $ch->query("SELECT reverseCashReceipt({$this->pid()}, fetchJournalNumber('C/R')) AS result");
+        $ch->fetch();
+        if($ch->result < 0){
+            $roo->jerr('Error occour on voiding a cash receipt! result : ' . $ch->result);
+        }
+    }
+}
diff --git a/DataObjects/Cashrcptitem.php b/DataObjects/Cashrcptitem.php
new file mode 100644 (file)
index 0000000..816fd13
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Table Definition for cashrcptitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cashrcptitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cashrcptitem';        // table name
+    public $cashrcptitem_id;                 // int4(4)  not_null default_nextval%28cashrcptitem_cashrcptitem_id_seq%29 primary_key
+    public $cashrcptitem_cashrcpt_id;        // int4(4)  not_null
+    public $cashrcptitem_aropen_id;          // int4(4)  not_null
+    public $cashrcptitem_amount;             // numeric(-1)  not_null
+    public $cashrcptitem_discount;           // numeric(-1)  not_null default_0.00
+    public $cashrcptitem_applied;            // bool(1)  default_true
+
+    
+   /**
+    * Getter / Setter for $cashrcptitem_aropen_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function aropen() {
+        return func_num_args() ? $this->link('cashrcptitem_aropen_id', func_get_arg(0)) : $this->link('cashrcptitem_aropen_id');
+    }
+
+   /**
+    * Getter / Setter for $cashrcptitem_cashrcpt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cashrcpt() {
+        return func_num_args() ? $this->link('cashrcptitem_cashrcpt_id', func_get_arg(0)) : $this->link('cashrcptitem_cashrcpt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cashrcptmisc.php b/DataObjects/Cashrcptmisc.php
new file mode 100644 (file)
index 0000000..2e9f657
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for cashrcptmisc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cashrcptmisc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cashrcptmisc';        // table name
+    public $cashrcptmisc_id;                 // int4(4)  not_null default_nextval%28cashrcptmisc_cashrcptmisc_id_seq%29 primary_key
+    public $cashrcptmisc_cashrcpt_id;        // int4(4)  not_null
+    public $cashrcptmisc_accnt_id;           // int4(4)  not_null
+    public $cashrcptmisc_amount;             // numeric(-1)  not_null
+    public $cashrcptmisc_notes;              // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $cashrcptmisc_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function accnt() {
+        return func_num_args() ? $this->link('cashrcptmisc_accnt_id', func_get_arg(0)) : $this->link('cashrcptmisc_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $cashrcptmisc_cashrcpt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cashrcpt() {
+        return func_num_args() ? $this->link('cashrcptmisc_cashrcpt_id', func_get_arg(0)) : $this->link('cashrcptmisc_cashrcpt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ccard.php b/DataObjects/Ccard.php
new file mode 100644 (file)
index 0000000..64e748b
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Table Definition for ccard
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ccard extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ccard';               // table name
+    public $ccard_id;                        // int4(4)  not_null default_nextval%28ccard_ccard_id_seq%29 primary_key
+    public $ccard_seq;                       // int4(4)  not_null default_10
+    public $ccard_cust_id;                   // int4(4)  not_null
+    public $ccard_active;                    // bool(1)  default_true
+    public $ccard_name;                      // bytea(-1)  
+    public $ccard_address1;                  // bytea(-1)  
+    public $ccard_address2;                  // bytea(-1)  
+    public $ccard_city;                      // bytea(-1)  
+    public $ccard_state;                     // bytea(-1)  
+    public $ccard_zip;                       // bytea(-1)  
+    public $ccard_country;                   // bytea(-1)  
+    public $ccard_number;                    // bytea(-1)  
+    public $ccard_debit;                     // bool(1)  default_false
+    public $ccard_month_expired;             // bytea(-1)  
+    public $ccard_year_expired;              // bytea(-1)  
+    public $ccard_type;                      // bpchar(-1)  not_null
+    public $ccard_date_added;                // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $ccard_lastupdated;               // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $ccard_added_by_username;         // text(-1)  not_null default_%22current_user%22%28%29
+    public $ccard_last_updated_by_username;    // text(-1)  not_null default_%22current_user%22%28%29
+
+    
+   /**
+    * Getter / Setter for $ccard_cust_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cust() {
+        return func_num_args() ? $this->link('ccard_cust_id', func_get_arg(0)) : $this->link('ccard_cust_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ccardaud.php b/DataObjects/Ccardaud.php
new file mode 100644 (file)
index 0000000..11ea8e8
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Table Definition for ccardaud
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ccardaud extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ccardaud';            // table name
+    public $ccardaud_id;                     // int4(4)  not_null default_nextval%28ccardaud_ccardaud_id_seq%29 primary_key
+    public $ccardaud_ccard_id;               // int4(4)  
+    public $ccardaud_ccard_seq_old;          // int4(4)  
+    public $ccardaud_ccard_seq_new;          // int4(4)  
+    public $ccardaud_ccard_cust_id_old;      // int4(4)  
+    public $ccardaud_ccard_cust_id_new;      // int4(4)  
+    public $ccardaud_ccard_active_old;       // bool(1)  
+    public $ccardaud_ccard_active_new;       // bool(1)  
+    public $ccardaud_ccard_name_old;         // bytea(-1)  
+    public $ccardaud_ccard_name_new;         // bytea(-1)  
+    public $ccardaud_ccard_address1_old;     // bytea(-1)  
+    public $ccardaud_ccard_address1_new;     // bytea(-1)  
+    public $ccardaud_ccard_address2_old;     // bytea(-1)  
+    public $ccardaud_ccard_address2_new;     // bytea(-1)  
+    public $ccardaud_ccard_city_old;         // bytea(-1)  
+    public $ccardaud_ccard_city_new;         // bytea(-1)  
+    public $ccardaud_ccard_state_old;        // bytea(-1)  
+    public $ccardaud_ccard_state_new;        // bytea(-1)  
+    public $ccardaud_ccard_zip_old;          // bytea(-1)  
+    public $ccardaud_ccard_zip_new;          // bytea(-1)  
+    public $ccardaud_ccard_country_old;      // bytea(-1)  
+    public $ccardaud_ccard_country_new;      // bytea(-1)  
+    public $ccardaud_ccard_number_old;       // bytea(-1)  
+    public $ccardaud_ccard_number_new;       // bytea(-1)  
+    public $ccardaud_ccard_debit_old;        // bool(1)  
+    public $ccardaud_ccard_debit_new;        // bool(1)  
+    public $ccardaud_ccard_month_expired_old;    // bytea(-1)  
+    public $ccardaud_ccard_month_expired_new;    // bytea(-1)  
+    public $ccardaud_ccard_year_expired_old;    // bytea(-1)  
+    public $ccardaud_ccard_year_expired_new;    // bytea(-1)  
+    public $ccardaud_ccard_type_old;         // bpchar(-1)  
+    public $ccardaud_ccard_type_new;         // bpchar(-1)  
+    public $ccardaud_ccard_last_updated;     // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $ccardaud_ccard_last_updated_by_username;    // text(-1)  not_null default_%22current_user%22%28%29
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ccbank.php b/DataObjects/Ccbank.php
new file mode 100644 (file)
index 0000000..7383064
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for ccbank
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ccbank extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ccbank';              // table name
+    public $ccbank_id;                       // int4(4)  not_null default_nextval%28ccbank_ccbank_id_seq%29 primary_key
+    public $ccbank_ccard_type;               // text(-1)  not_null unique_key
+    public $ccbank_bankaccnt_id;             // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $ccbank_bankaccnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function bankaccnt() {
+        return func_num_args() ? $this->link('ccbank_bankaccnt_id', func_get_arg(0)) : $this->link('ccbank_bankaccnt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ccpay.php b/DataObjects/Ccpay.php
new file mode 100644 (file)
index 0000000..5c66e5e
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for ccpay
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ccpay extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ccpay';               // table name
+    public $ccpay_id;                        // int4(4)  not_null default_nextval%28ccpay_ccpay_id_seq%29 primary_key
+    public $ccpay_ccard_id;                  // int4(4)  
+    public $ccpay_cust_id;                   // int4(4)  
+    public $ccpay_amount;                    // numeric(-1)  not_null default_0.00
+    public $ccpay_auth;                      // bool(1)  not_null default_true
+    public $ccpay_status;                    // bpchar(-1)  not_null
+    public $ccpay_type;                      // bpchar(-1)  not_null
+    public $ccpay_auth_charge;               // bpchar(-1)  not_null
+    public $ccpay_order_number;              // text(-1)  
+    public $ccpay_order_number_seq;          // int4(4)  
+    public $ccpay_r_avs;                     // text(-1)  
+    public $ccpay_r_ordernum;                // text(-1)  
+    public $ccpay_r_error;                   // text(-1)  
+    public $ccpay_r_approved;                // text(-1)  
+    public $ccpay_r_code;                    // text(-1)  
+    public $ccpay_r_message;                 // text(-1)  
+    public $ccpay_yp_r_time;                 // timestamp(8)  
+    public $ccpay_r_ref;                     // text(-1)  
+    public $ccpay_yp_r_tdate;                // text(-1)  
+    public $ccpay_r_tax;                     // text(-1)  
+    public $ccpay_r_shipping;                // text(-1)  
+    public $ccpay_yp_r_score;                // int4(4)  
+    public $ccpay_transaction_datetime;      // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $ccpay_by_username;               // text(-1)  not_null default_%22current_user%22%28%29
+    public $ccpay_curr_id;                   // int4(4)  default_basecurrid%28%29
+    public $ccpay_ccpay_id;                  // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Char.php b/DataObjects/Char.php
new file mode 100644 (file)
index 0000000..0f77cd4
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Table Definition for char
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Char extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'char';                // table name
+    public $char_id;                         // int4(4)  not_null default_nextval%28char_char_id_seq%29 primary_key
+    public $char_name;                       // text(-1)  not_null unique_key
+    public $char_items;                      // bool(1)  
+    public $char_options;                    // bool(1)  
+    public $char_attributes;                 // bool(1)  
+    public $char_lotserial;                  // bool(1)  
+    public $char_notes;                      // text(-1)  
+    public $char_customers;                  // bool(1)  
+    public $char_crmaccounts;                // bool(1)  
+    public $char_addresses;                  // bool(1)  
+    public $char_contacts;                   // bool(1)  
+    public $char_opportunity;                // bool(1)  
+    public $char_employees;                  // bool(1)  default_false
+    public $char_mask;                       // text(-1)  
+    public $char_validator;                  // text(-1)  
+    public $char_incidents;                  // bool(1)  default_false
+    public $char_type;                       // int4(4)  not_null default_0
+    public $char_order;                      // int4(4)  not_null default_0
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults()
+    {
+        return array(
+            
+                     
+            'char_name' => '', // not blank!?
+            'char_items' => false,        
+            'char_options' => false,
+            'char_attributes' => false,   
+            'char_lotserial' => false,    
+            'char_notes' => '',        
+            'char_customers' => false,    
+            'char_crmaccounts' => false,  
+            'char_addresses' => false,    
+            'char_contacts' => false,     
+            'char_opportunity' => false,  
+            'char_employees' => false,    
+            //'char_mask' => '',         
+            //'char_validator' => false,    
+            'char_incidents' => false,    
+            'char_type' => 0, // text , 1 == opts..        
+            'char_order' => 0,
+            'char_search' => true,
+                              
+        );                
+        
+    }
+    
+    function initDatabase()
+    {
+        // should have used this before...
+        
+        static $once = false;;
+        if ($once) {
+            return;
+        }
+        $once = true;
+        
+        $defs = array(
+            array(
+                'char_name' => 'INTERNALCOMPANY',
+                'char_customers' => true,
+                'char_type' => 1,
+                'char_notes' => 'Internal Company Ref',
+                // this is very specific to our implementation..
+                'opts' => array('sg','hk','cn','au','my')
+            ),
+            array(
+                'char_name' => 'PRODUCTGROUP',
+                'char_items' => true,
+                'char_type' => 0,
+                'char_notes' => 'Product Group',
+                
+            ),
+            
+            array(
+                'char_name' => 'PALLET_LOCATION',
+                'char_items' => true,
+                'char_type' => 0,
+                'char_notes' => 'Pallet Location',
+                
+            ),
+            array(
+                'char_name' => 'PICKFACE_LOCATION',
+                'char_items' => true,
+                'char_type' => 0,
+                'char_notes' => 'Pickface Location',
+                
+            ),
+            
+            array(
+                'char_name' => 'BRAND',
+                'char_items' => true,
+                'char_type' => 0,
+                'char_notes' => 'Brand',
+                
+            ),
+            array(
+                'char_name' => 'SALESFORECAST',
+                'char_customers' => true,
+                'char_type' => 1,
+                'opts' => array('always display', 'hide', 'normal')
+                
+            ),
+            array(
+                'char_name' => 'AU-POST-ACCNO',
+                'char_customers' => true,
+                'char_type' => 0,
+                'char_notes' => 'AU POST ACCOUNT NO.',
+            )
+            
+            //... fill more in.. our items have brand and productcategory...
+        );
+        
+        foreach($defs as $d) {
+            $x = DB_DataObject::Factory($this->tableName());
+            if (!$x->get('char_name', $d['char_name'])) {
+                
+                $x->setFrom($this->defaults());
+                $x->setFrom($d);
+                $x->insert();
+            }
+            // no update..
+            if (!empty($d['opts'])) {
+                foreach($d['opts'] as $o) {
+                    $opt = DB_DataObject::Factory('charopt');
+                    $opt->charopt_char_id = $x->pid();
+                    if ($opt->get('charopt_value', $o)) {
+                        continue;
+                    }
+                    $opt->charopt_value = $o;
+                    $opt->charopt_order = 0;
+                    $opt->insert();
+                    
+                }
+                
+                
+                
+            }
+        }
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Charass.php b/DataObjects/Charass.php
new file mode 100644 (file)
index 0000000..47e780c
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Table Definition for charass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Charass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'charass';             // table name
+    public $charass_id;                      // int4(4)  not_null default_nextval%28charass_charass_id_seq%29 primary_key
+    public $charass_target_type;             // text(-1)  multiple_key
+    public $charass_target_id;               // int4(4)  multiple_key
+    public $charass_char_id;                 // int4(4)  
+    public $charass_value;                   // text(-1)  
+    public $charass_default;                 // bool(1)  not_null default_false
+    public $charass_price;                   // numeric(-1)  not_null default_0
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        if (isset($q['charass_char_id_char_name'])) {
+            $c = DB_DAtaObject::FActory('char');
+            $c->get('char_name', $q['charass_char_id_char_name']);
+            $this->charass_char_id = $c->pid();
+            
+        }
+        if (isset($q['query']['charass_value'])) {
+            $this->whereAdd("charass_value !='' ");
+        }
+        if (!empty($q['query']['charass_value'])) {
+            $this->whereAdd("charass_value like '{$this->escape($q['query']['charass_value'])}%'");
+        }
+        
+    }   
+    function beforeInsert($q,$roo) {
+        if (isset($q['charass_char_id_char_name'])) {
+            $c = DB_DAtaObject::FActory('char');
+            if (!$c->get('char_name', $q['charass_char_id_char_name'])) {
+                $roo->jerr("invalid char name ".$q['charass_char_id_char_name']);
+            }
+            $this->charass_char_id = $c->pid();
+            $this->setFrom($q);
+            $old = DB_DataObject::Factory('charass');
+            $old->setFrom(array(
+                'charass_target_type' => $this->charass_target_type,
+                'charass_target_id' => $this->charass_target_id,
+                'charass_char_id' => $this->charass_char_id,
+            ));
+            if ($old->find(true)) {
+                $bold = clone($old);
+                $old->setFrom($c);
+                $old->charass_value = $this->charass_value;
+                
+                $old->update($bold);
+                $roo->jok("updated");
+            }
+            // otherwise just goes trough and inserts..
+            
+            
+        }
+    }
+    
+    function lookupIds($target_type, $char_name, $charass_value)
+    {   
+        $this->autoJoinChar();
+        $this->selectAdd();
+        $this->selectAdd("charass_target_id");
+        $this->charass_target_type = $target_type;
+        if(!empty($charass_value)){
+            $this->charass_value = $charass_value;
+        }
+        $this->whereAdd("
+            join_charass_char.char_name = '{$this->escape($char_name)}'
+        ");
+        
+        $ids = $this->fetchAll('charass_target_id');
+        return $ids;
+    }
+    
+    function autoJoinChar()
+    {
+        $this->_join = "
+            LEFT JOIN char AS join_charass_char
+                ON ( join_charass_char.char_id = charass_char_id )
+        ";
+        
+        $add = DB_DataObject::Factory('char');
+        $this->selectAs($add, 'charass_%s', 'join_charass_char');
+        
+    }
+}
diff --git a/DataObjects/Charopt.php b/DataObjects/Charopt.php
new file mode 100644 (file)
index 0000000..74046a8
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Table Definition for charopt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Charopt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'charopt';             // table name
+    public $charopt_id;                      // int4(4)  not_null default_nextval%28charopt_charopt_id_seq%29
+    public $charopt_char_id;                 // int4(4)  
+    public $charopt_value;                   // text(-1)  not_null
+    public $charopt_order;                   // int4(4)  not_null default_0
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['charopt_char_id_char_name'])) {
+            $char = DB_DataObject::Factory('char');
+            if (!$char->get('char_name', $q['charopt_char_id_char_name'])) {
+                $roo->jerr("invalid char name");
+            }
+            $this->charopt_char_id = $char->pid();
+        }
+        
+        
+    }
+}
diff --git a/DataObjects/Checkhead.php b/DataObjects/Checkhead.php
new file mode 100644 (file)
index 0000000..d1899b4
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Table Definition for checkhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Checkhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'checkhead';           // table name
+    public $checkhead_id;                    // int4(4)  not_null default_nextval%28checkhead_checkhead_id_seq%29 primary_key
+    public $checkhead_recip_id;              // int4(4)  not_null
+    public $checkhead_recip_type;            // text(-1)  not_null
+    public $checkhead_bankaccnt_id;          // int4(4)  not_null
+    public $checkhead_printed;               // bool(1)  not_null default_false
+    public $checkhead_checkdate;             // date(4)  not_null
+    public $checkhead_number;                // int4(4)  not_null
+    public $checkhead_amount;                // numeric(-1)  not_null
+    public $checkhead_void;                  // bool(1)  not_null default_false
+    public $checkhead_replaced;              // bool(1)  not_null default_false
+    public $checkhead_posted;                // bool(1)  not_null default_false
+    public $checkhead_rec;                   // bool(1)  not_null default_false
+    public $checkhead_misc;                  // bool(1)  not_null default_false
+    public $checkhead_expcat_id;             // int4(4)  
+    public $checkhead_for;                   // text(-1)  not_null
+    public $checkhead_notes;                 // text(-1)  not_null
+    public $checkhead_journalnumber;         // int4(4)  
+    public $checkhead_curr_id;               // int4(4)  not_null default_basecurrid%28%29
+    public $checkhead_deleted;               // bool(1)  not_null default_false
+    public $checkhead_ach_batch;             // text(-1)  
+    public $checkhead_curr_rate;             // numeric(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $checkhead_bankaccnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function bankaccnt() {
+        return func_num_args() ? $this->link('checkhead_bankaccnt_id', func_get_arg(0)) : $this->link('checkhead_bankaccnt_id');
+    }
+
+   /**
+    * Getter / Setter for $checkhead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('checkhead_curr_id', func_get_arg(0)) : $this->link('checkhead_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $checkhead_expcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function expcat() {
+        return func_num_args() ? $this->link('checkhead_expcat_id', func_get_arg(0)) : $this->link('checkhead_expcat_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function beforeInsert($request,$roo)
+    {
+        if(empty($request['_create_and_post'])){
+            $roo->jerr('insert checkhead not supported');
+        }
+        // create a check
+        $checkhead = $this->create($request, $roo);
+        
+        // print the check
+        $checkhead->flagPrinted();
+        
+        // prepare the check
+        // $this->prepare($roo); << nothing to do
+        
+        // post the check
+        $checkhead->post($roo);
+        
+        $roo->jok('CREATED AND POSTED!');
+    }
+    
+    function beforeUpdate($old, $request,$roo)
+    {
+        if(isset($request['_voidPosted'])){
+            $this->voidPostedCheck($roo);
+            $roo->jok('VOIDED');
+        }
+    }
+    
+    function create($request, $roo)
+    {
+        $request['aropen_id'] = (int) $request['aropen_id'];
+        $aropen = DB_DataObject::factory('aropen');
+        if(!$aropen->get($request['aropen_id'])){
+            $roo->jerr('no valid aropen!?');
+        }
+        $ch = DB_DataObject::Factory('checkhead');
+        $ch->query("SELECT createCheck(
+                        $this->checkhead_bankaccnt_id, 
+                        '{$this->checkhead_recip_type}', 
+                        $this->checkhead_recip_id, 
+                        '{$this->checkhead_checkdate}', 
+                        $this->checkhead_amount, 
+                        $this->checkhead_curr_id, 
+                        NULL, NULL, 
+                        '{$this->checkhead_for}', 
+                        '{$this->checkhead_notes}', 
+                        $this->checkhead_misc, 
+                        {$request['aropen_id']} 
+                    ) AS result
+        ");
+        $ch->fetch();
+        if($ch->result < 0){
+            $roo->jerr('Error occour on create a check! result : ' . $ch->result);
+        }
+        
+        $checkhead = DB_DataObject::factory('checkhead');
+        if(!$checkhead->get($ch->result)){
+            $this->jerr('Error occour on getting the check that you just created!');
+        }
+        return $checkhead;
+    }
+    
+    function flagPrinted()
+    {
+        $ch = DB_DataObject::Factory('checkhead');
+        $ch->query("UPDATE {$this->tableName()} SET checkhead_number = fetchNextCheckNumber(checkhead_bankaccnt_id) WHERE checkhead_id = {$this->pid()}");
+        
+        $ch = DB_DataObject::Factory('checkhead');
+        $ch->query("SELECT markCheckAsPrinted({$this->pid()}) AS result");
+        $ch->fetch();
+    }
+    
+    function prepare($roo)
+    {   
+        $ch = DB_DataObject::Factory('checkhead');
+        $ch->query("SELECT createChecks($this->checkhead_bankaccnt_id, '{$this->checkhead_checkdate}' ) AS result");
+        $ch->fetch();
+       // print_r($ch->result);exit; => get 0
+        
+    }
+    
+    function post($roo)
+    {
+        $ch = DB_DataObject::Factory('checkhead');
+        $ch->query("SELECT postCheck({$this->pid()}, NULL) AS result FROM {$this->tableName()} WHERE checkhead_id = {$this->pid()} AND (NOT checkhead_posted)");
+        $ch->fetch();
+        if($ch->result < 0){
+            $roo->jerr('Error occour on post the check! result : ' . $ch->result);
+        }
+    }
+    
+    /*
+     *  this is for void the un-posted check
+     *  voidcheck(integer)
+     *  pCheckid ALIAS FOR $1;
+     */
+    
+    function void()
+    {
+        
+        
+    }
+    
+    /*
+     *  this is for void the posted check
+     *  voidpostedcheck(integer, integer, date)
+     *  pCheckid               ALIAS FOR $1;
+     *  pJournalNumber          ALIAS FOR $2;
+     *  pVoidDate              ALIAS FOR $3;
+     */
+    
+    function voidPostedCheck($roo)
+    {
+        
+        $ch = DB_DataObject::Factory('checkhead');
+        // not sure whether we can use the old journalnumber !!!!???
+        // $ch->query("SELECT voidpostedcheck({$this->pid()}, {$this->checkhead_journalnumber}, NOW()::date) AS result");
+        $ch->query("SELECT voidpostedcheck({$this->pid()}, fetchJournalNumber('AP-CK'), NOW()::date) AS result");
+        $ch->fetch();
+        if($ch->result < 0){
+            $roo->jerr('Error occour on voiding a posted check! result : ' . $ch->result);
+        }
+        
+    }
+
+}
diff --git a/DataObjects/Checkitem.php b/DataObjects/Checkitem.php
new file mode 100644 (file)
index 0000000..79fc376
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Table Definition for checkitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Checkitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'checkitem';           // table name
+    public $checkitem_id;                    // int4(4)  not_null default_nextval%28checkitem_checkitem_id_seq%29 primary_key
+    public $checkitem_checkhead_id;          // int4(4)  not_null
+    public $checkitem_amount;                // numeric(-1)  not_null default_0.0
+    public $checkitem_discount;              // numeric(-1)  not_null default_0.0
+    public $checkitem_ponumber;              // text(-1)  
+    public $checkitem_vouchernumber;         // text(-1)  
+    public $checkitem_invcnumber;            // text(-1)  
+    public $checkitem_apopen_id;             // int4(4)  
+    public $checkitem_aropen_id;             // int4(4)  
+    public $checkitem_docdate;               // date(4)  
+    public $checkitem_curr_id;               // int4(4)  not_null default_basecurrid%28%29
+    public $checkitem_cmnumber;              // text(-1)  
+    public $checkitem_ranumber;              // text(-1)  
+    public $checkitem_curr_rate;             // numeric(-1)  
+
+    
+   /**
+    * Getter / Setter for $checkitem_apopen_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function apopen() {
+        return func_num_args() ? $this->link('checkitem_apopen_id', func_get_arg(0)) : $this->link('checkitem_apopen_id');
+    }
+
+   /**
+    * Getter / Setter for $checkitem_aropen_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function aropen() {
+        return func_num_args() ? $this->link('checkitem_aropen_id', func_get_arg(0)) : $this->link('checkitem_aropen_id');
+    }
+
+   /**
+    * Getter / Setter for $checkitem_checkhead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function checkhead() {
+        return func_num_args() ? $this->link('checkitem_checkhead_id', func_get_arg(0)) : $this->link('checkitem_checkhead_id');
+    }
+
+   /**
+    * Getter / Setter for $checkitem_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('checkitem_curr_id', func_get_arg(0)) : $this->link('checkitem_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        $this->joinAddBankaccnt();
+    }
+    
+    function joinAddBankaccnt()
+    {
+        $bankaccnt = DB_DataObject::factory('bankaccnt');
+        $this->_join .= "
+            LEFT JOIN bankaccnt join_checkitem_bankaccnt_id
+            ON
+            join_checkitem_bankaccnt_id.bankaccnt_id = join_checkitem_checkhead_id_checkhead_id.checkhead_bankaccnt_id
+        ";
+        
+        $this->selectAs($bankaccnt, 'checkitem_bankaccnt_id_%s', 'join_checkitem_bankaccnt_id');
+    }
+    
+}
diff --git a/DataObjects/Checkrecip.php b/DataObjects/Checkrecip.php
new file mode 100644 (file)
index 0000000..a375316
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for checkrecip
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Checkrecip extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'checkrecip';          // table name
+    public $checkrecip_id;                   // int4(4)  
+    public $checkrecip_type;                 // text(-1)  
+    public $checkrecip_number;               // text(-1)  
+    public $checkrecip_name;                 // text(-1)  
+    public $checkrecip_gltrans_source;       // text(-1)  
+    public $checkrecip_accnt_id;             // int4(4)  
+    public $checkrecip_addr_id;              // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Classcode.php b/DataObjects/Classcode.php
new file mode 100644 (file)
index 0000000..80a5f6b
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Table Definition for classcode
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Classcode extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'classcode';           // table name
+    public $classcode_id;                    // int4(4)  not_null default_nextval%28%28classcode_classcode_id_seq%29%3A%3Aregclass%29 primary_key
+    public $classcode_code;                  // text(-1)  
+    public $classcode_descrip;               // text(-1)  
+    public $classcode_mfg;                   // bool(1)  
+    public $classcode_creator;               // text(-1)  
+    public $classcode_created;               // timestamp(8)  
+    public $classcode_modifier;              // text(-1)  
+    public $classcode_modified;              // timestamp(8)  
+    public $classcode_type;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE###
+    
+    function initDatabase($roo)
+    {
+        
+        static $ar = array(
+         'SOLD' => 'Sold Items'  ,
+
+         'OUTSIDE PROCESS' => 'Outside Process',
+         'SUB ASSEMBLY'=> 'Sub Assembly',
+         'COMPONENT'=> 'Component',
+        );
+         
+        foreach($ar as $k=>$v) {
+            $pc = DB_DataObject::Factory('classcode');
+            if ($pc->get('classcode_code', $k)) {
+                continue;
+            }
+            $pc->setFrom(array(
+                'classcode_code' => $k,
+                'classcode_descrip' => $v
+            ));
+            $pc->insert();
+        }
+        
+        
+    }
+}
diff --git a/DataObjects/Cmd.php b/DataObjects/Cmd.php
new file mode 100644 (file)
index 0000000..aa4c37b
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for cmd
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmd extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmd';                 // table name
+    public $cmd_id;                          // int4(4)  not_null default_nextval%28cmd_cmd_id_seq%29 primary_key
+    public $cmd_module;                      // text(-1)  not_null
+    public $cmd_title;                       // text(-1)  not_null
+    public $cmd_descrip;                     // text(-1)  
+    public $cmd_privname;                    // text(-1)  
+    public $cmd_executable;                  // text(-1)  not_null
+    public $cmd_name;                        // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cmdarg.php b/DataObjects/Cmdarg.php
new file mode 100644 (file)
index 0000000..890f268
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for cmdarg
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmdarg extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmdarg';              // table name
+    public $cmdarg_id;                       // int4(4)  not_null default_nextval%28cmdarg_cmdarg_id_seq%29 primary_key
+    public $cmdarg_cmd_id;                   // int4(4)  not_null
+    public $cmdarg_order;                    // int4(4)  not_null
+    public $cmdarg_arg;                      // text(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $cmdarg_cmd_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cmd() {
+        return func_num_args() ? $this->link('cmdarg_cmd_id', func_get_arg(0)) : $this->link('cmdarg_cmd_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cmhead.php b/DataObjects/Cmhead.php
new file mode 100644 (file)
index 0000000..40fdff7
--- /dev/null
@@ -0,0 +1,1102 @@
+<?php
+/**
+ * Table Definition for cmhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmhead';              // table name
+    public $cmhead_id;                       // int4(4)  not_null default_nextval%28%28cmhead_cmhead_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cmhead_number;                   // text(-1)  
+    public $cmhead_posted;                   // bool(1)  
+    public $cmhead_invcnumber;               // text(-1)  
+    public $cmhead_custponumber;             // text(-1)  
+    public $cmhead_cust_id;                  // int4(4)  
+    public $cmhead_docdate;                  // date(4)  
+    public $cmhead_shipto_id;                // int4(4)  
+    public $cmhead_shipto_name;              // text(-1)  
+    public $cmhead_shipto_address1;          // text(-1)  
+    public $cmhead_shipto_address2;          // text(-1)  
+    public $cmhead_shipto_address3;          // text(-1)  
+    public $cmhead_shipto_city;              // text(-1)  
+    public $cmhead_shipto_state;             // text(-1)  
+    public $cmhead_shipto_zipcode;           // text(-1)  
+    public $cmhead_salesrep_id;              // int4(4)  
+    public $cmhead_freight;                  // numeric(-1)  
+    public $cmhead_misc;                     // numeric(-1)  
+    public $cmhead_comments;                 // text(-1)  
+    public $cmhead_printed;                  // bool(1)  
+    public $cmhead_billtoname;               // text(-1)  
+    public $cmhead_billtoaddress1;           // text(-1)  
+    public $cmhead_billtoaddress2;           // text(-1)  
+    public $cmhead_billtoaddress3;           // text(-1)  
+    public $cmhead_billtocity;               // text(-1)  
+    public $cmhead_billtostate;              // text(-1)  
+    public $cmhead_billtozip;                // text(-1)  
+    public $cmhead_hold;                     // bool(1)  
+    public $cmhead_commission;               // numeric(-1)  
+    public $cmhead_misc_accnt_id;            // int4(4)  
+    public $cmhead_misc_descrip;             // text(-1)  
+    public $cmhead_rsncode_id;               // int4(4)  
+    public $cmhead_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $cmhead_freighttaxtype_id;        // int4(4)  
+    public $cmhead_gldistdate;               // date(4)  
+    public $cmhead_billtocountry;            // text(-1)  
+    public $cmhead_shipto_country;           // text(-1)  
+    public $cmhead_rahead_id;                // int4(4)  
+    public $cmhead_taxzone_id;               // int4(4)  
+    public $cmhead_prj_id;                   // int4(4)  
+    public $cmhead_billto_cntct_id;          // int4(4)
+    public $cmhead_billto_addr_id;          // int4(4)
+    public $cmhead_location_id;  // extra...
+    
+    
+   /**
+    * Getter / Setter for $cmhead_freighttaxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freighttaxtype() {
+        return func_num_args() ? $this->link('cmhead_freighttaxtype_id', func_get_arg(0)) : $this->link('cmhead_freighttaxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $cmhead_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('cmhead_prj_id', func_get_arg(0)) : $this->link('cmhead_prj_id');
+    }
+
+   /**
+    * Getter / Setter for $cmhead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('cmhead_taxzone_id', func_get_arg(0)) : $this->link('cmhead_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $cmhead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cmhead_curr_id', func_get_arg(0)) : $this->link('cmhead_curr_id');
+    }
+    
+    /**
+    * Getter / Setter for $cmhead_billto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function billto_cntct() {
+        return func_num_args() ? $this->link('cmhead_billto_cntct_id', func_get_arg(0)) : $this->link('cmhead_billto_cntct_id');
+    }
+    
+    /**
+    * Getter / Setter for $cohead_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('cmhead_salesrep_id', func_get_arg(0)) : $this->link('cmhead_salesrep_id');
+    }
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults() {
+        
+        $sa =  DB_DataObject::Factory('salesaccnt');
+        $sa->salesaccnt_custtype ='.*';
+        $sa->salesaccnt_prodcat = '.*';
+        $sa->find(true);
+          
+        
+        return array(
+            'cmhead_printed'=>true,
+            'cmhead_rsncode_id'=> $this->sqlValue('NULL'),
+            'cmhead_posted'=>  false,
+            'cmhead_custponumber' => '',
+            'cmhead_freight' => 0.0,
+            'cmhead_misc' => 0.0,
+            'cmhead_hold' => false,
+            'cmhead_commission' => 0.0,
+            'cmhead_misc_accnt_id' =>  $sa->salesaccnt_credit_accnt_id,
+            'cmhead_misc_descrip' => '',
+            'cmhead_freighttaxtype_id' => $this->sqlValue('NULL'),
+            'cmhead_rahead_id' => $this->sqlValue('NULL'),
+            'cmhead_prj_id'=> $this->sqlValue('NULL'),
+        );
+        
+        //public $cmhead_invcnumber;               // text(-1)  
+        //public $cmhead_cust_id;                  // int4(4)  
+        //public $cmhead_docdate;                  // date(4)  
+        //public $cmhead_shipto_id;                // int4(4)  
+        //public $cmhead_salesrep_id;              // int4(4)  
+        //public $cmhead_freight;                  // numeric(-1)  
+        //public $cmhead_misc;                     // numeric(-1)  
+        //public $cmhead_comments;                 // text(-1)  
+        //public $cmhead_curr_id;                  // int4(4)  default_basecurrid%28%29
+        //public $cmhead_taxzone_id;               // int4(4)  
+        
+        //public $cmhead_billto_cntct_id;          // int4(4)
+        //public $cmhead_billto_addr_id;          // int4(4)
+        //public $cmhead_location_id;  // extra...
+            
+        
+    }
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        //join the customer table
+        //DB_DataObject::debugLevel(1);
+        $tn=  $this->tableName();
+        
+        //$ci = DB_DataObject::Factory('custinfo');
+        //$this->selectAs($ci, 'cmhead_cust_id_%s');
+        //$this->_join .= " LEFT JOIN custinfo ON cmhead_cust_id=custinfo.cmhead_cust_id ";
+        
+        //join the value from cmitem table as cmhead_value
+        $this->selectAdd("
+            CASE WHEN
+                cmhead_taxzone_id != gettaxzoneid('NO TAX')
+            THEN
+                (SELECT SUM(cmitem_unitprice * cmitem_qtyreturned + 
+                            calculatetax(
+                                cmhead_taxzone_id,
+                                cmitem_taxtype_id,
+                                cmhead_docdate,
+                                cmhead_curr_id,
+                                cmitem_unitprice * cmitem_qtyreturned
+                            )) 
+                 FROM 
+                    cmitem 
+                 WHERE 
+                    cmitem_cmhead_id = cmhead.cmhead_id
+                ) 
+            ELSE
+                (SELECT 
+                    SUM(cmitem_unitprice * cmitem_qtyreturned) 
+                 FROM 
+                    cmitem 
+                 WHERE 
+                    cmitem_cmhead_id = cmhead.cmhead_id
+                ) 
+            END AS cmhead_value
+        "); 
+        
+        // tax...
+        $this->selectAdd("
+            CASE WHEN
+                cmhead_taxzone_id != gettaxzoneid('NO TAX')
+            THEN
+                (
+                    select COALESCE( sum(
+                        calculatetax(
+                            cmhead_taxzone_id,
+                            cmitem_taxtype_id,
+                            cmhead_docdate,
+                            cmhead_curr_id,
+                            cmitem_unitprice * cmitem_qtyreturned
+                        )
+                    ), 0.0)
+                        from 
+                            cmitem 
+                        where 
+                            cmitem_cmhead_id = cmhead.cmhead_id
+                            AND
+                            cmitem_taxtype_id = gettaxtypeid('Taxable')
+                )
+                ELSE
+                    0.0
+                END as cmhead_tax_value,
+            
+                CASE WHEN
+                    cmhead_taxzone_id != gettaxzoneid('NO TAX')
+                THEN
+                    (
+                        select COALESCE( sum(
+                            cmitem_unitprice * cmitem_qtyreturned
+                          
+                        ), 0,0)
+                            from 
+                                cmitem 
+                            where 
+                                cmitem_cmhead_id = cmhead.cmhead_id
+                                AND
+                                cmitem_taxtype_id = gettaxtypeid('Taxable')
+                    )
+                ELSE
+                    0.0
+                END as cmhead_taxable_value
+                
+                
+            "); 
+        
+        
+        $this->selectAdd("gettaxtypeid('Taxable') AS default_taxtype_id");
+        
+        //join the bill contact and address
+        
+        $cntct = DB_DataObject::factory('cntct');
+        $this->_join .= '
+            LEFT JOIN cntct AS billcntct ON ( cmhead_billto_cntct_id = billcntct.cntct_id)
+        ';
+        $this->selectAs($cntct, 'cmhead_billto_cntct_id_%s', 'billcntct');
+        
+        $addr = DB_DataObject::Factory('addr');
+        $this->_join .= '
+            LEFT JOIN addr AS billaddr ON ( cmhead_billto_addr_id = billaddr.addr_id)
+        ';
+        $this->selectAs($addr, 'cmhead_billto_cntct_id_cntct_addr_id_%s', 'billaddr');
+        
+        
+        //get the location name
+        // this is not used?
+        /*$loc = DB_DataObject::factory('location');
+        $loc->selectAdd("
+            distinct(cmhead_location_id) as cmhead_location_id,
+            (SELECT location_name from location where location_id = cmhead_location_id) as cmhead_location_name
+            ");
+        */
+        
+        
+        $tax = DB_DataObject::factory('taxzone');
+        $d = date('Y-m-d');
+        //error_log($d);
+        $this->selectAdd("
+            COALESCE( (SELECT taxrate_percent FROM taxrate WHERE taxrate_tax_id IN 
+                (SELECT taxass_tax_id FROM taxass WHERE
+                    taxass_taxzone_id = cmhead.cmhead_taxzone_id
+                    AND taxrate_effective < '$d' AND taxrate_expires > '$d'
+                )
+            ), 0) as taxzone_rate
+        ");
+        
+        $this->selectAdd("
+             COALESCE(
+                (SELECT aropen_amount - aropen_paid FROM
+                        aropen
+                    WHERE
+                            aropen_doctype ='C'
+                        AND
+                            aropen_ordernumber = cmhead.cmhead_number
+                        LIMIT 1
+                ), 0
+            ) as cmhead_unpaid
+        ");
+        
+        
+        if (!empty($q['query']['cmhead_number'])) {
+            //DB_DataObject::DebugLevel(1);
+            $this->whereAdd("{$tn}.cmhead_number ilike '" . $this->escape($q['query']['cmhead_number']) . "%'");
+            
+
+        }
+        
+        if (!empty($q['query']['status']))
+        {
+            $ap = "(SELECT aropen_open FROM aropen WHERE aropen_doctype ='C' and aropen_ordernumber = cmhead.cmhead_number LIMIT 1)";
+           //DB_DataObject::DebugLevel(1);
+            // if it's been used..
+            switch($q['query']['status']) {
+                case   'NOTCLOSED' :
+                    $this->whereAdd("
+                        {$tn}.cmhead_posted = false OR
+                        {$ap}
+                    ");
+                    break;
+                    
+                    
+                case 'CLOSED' :
+                    $this->whereAdd("
+                        {$tn}.cmhead_posted = true AND
+                        {$ap} = false
+                    ");
+                    break;
+                
+                case 'UNPOSTED':
+                    $this->cmhead_posted = false;
+                    break;
+                
+                case 'UNUSED':
+                    $this->whereAdd("
+                        {$tn}.cmhead_posted = true AND
+                        {$ap}
+                    ");
+                    break;
+                
+                case 'VOIDED':
+                    $this->whereAdd("
+                        
+                        NOT  {$ap}
+                    ");
+                    break;
+                
+                
+            }
+        }
+        
+        if(isset($q['_with_aropen'])){
+            $this->joinAddAropen();
+            
+            $this->selectAdd("
+                (join_cmhead_aropen_id.aropen_amount - join_cmhead_aropen_id.aropen_paid - 
+                (SELECT 
+                    COALESCE(SUM(checkhead_amount),0)  
+                FROM 
+                    checkhead,checkitem  
+                WHERE 
+                    ((checkhead_id=checkitem_checkhead_id)  
+                AND 
+                    (NOT checkhead_posted)
+                AND 
+                    (NOT checkhead_void)  
+                AND 
+                    (checkitem_aropen_id=aropen_id)))
+                ) AS checkhead_total
+            ");
+        }
+        
+    }
+    
+    function beforeUpdate($old, $q,$roo){
+        
+      
+        $this->contact2bill($q);
+        if (isset($q['cmhead_posted']) && $q['cmhead_posted'] == 'false') {
+            $this->cmhead_posted = false;
+        }
+        if (!empty($q['_post'])) {
+            $this->post($roo); // should only return if it succeeds.
+            $roo->jok($this->pid());
+        }
+        if (!empty($q['_void'])) {
+            $this->void($roo); // should only return if it succeeds.
+            $roo->jok("VOIDED");
+        }
+        if (empty($this->cmhead_misc_accnt_id)) {
+            
+            
+            $sa =  DB_DataObject::Factory('salesaccnt');
+            $sa->salesaccnt_custtype ='.*';
+            $sa->salesaccnt_prodcat = '.*';
+            $sa->find(true);
+            $this->cmhead_misc_accnt_id = $sa->salesaccnt_credit_accnt_id;
+        }
+        
+    }
+    
+    function beforeInsert($request,$roo)
+    {
+        if(isset($request['_fix_stock'])){
+            $cmhead = DB_DataObject::factory('cmhead');
+            $cmhead->query("SELECT invfifo_apply_gl_cmhead_fix_stock()");
+            
+            $roo->jok("FIXED");
+        }
+        
+        if (isset($request['_is_xfer'])) {
+            $this->recieveXfer($roo, $request);
+            $this->jerr("no ok");
+        }
+        
+        // handle automatic numbering..
+        if ($this->cmhead_number == 'Automatic' || empty($this->cmhead_number)) {
+            $this->cmhead_number = $this->nextNumber();
+        }
+        $this->cmhead_posted = false;
+        $this->contact2bill($request);
+    }
+    
+    function beforeDelete()
+    {
+        $cmitem = DB_DataObject::factory('cmitem');
+        $cmitem->whereAdd("
+            cmitem_cmhead_id = {$this->pid()}
+        ");
+        $cmitem->delete(DB_DATAOBJECT_WHEREADD_ONLY);
+    }
+
+    function items($what=false)
+    {
+        $i = $this->factory('cmitem');
+        $i->cmitem_cmhead_id = $this->cmhead_id;
+        
+        //$i->orderBy('cmitem_linenumber ASC');
+        return $i->fetchAll($what);
+        
+    }
+     function relatedWhere()
+    {
+        return  array(
+            'cmitem' => $this->items('cmitem_id'),
+        );
+        
+        
+        
+        
+    }
+    
+    
+    
+    function contact2bill($request){
+        
+        $bill = $this->billto_cntct();
+        //print_r($bill);exit;
+        
+        if ($bill->cntct_id) {
+            $this->setFrom($bill->toArray('cmhead_billto_%s'));
+            $this->cmhead_billto_cntct_id = $bill->cntct_id;
+            
+            
+            $addr = $bill->addr();
+            //print_r($addr);exit;
+            $this->cmhead_billto_addr_id = $addr->addr_id;
+            $this->setFrom(array(
+                'cmhead_billtoname' =>       $bill->cntct_name,
+                'cmhead_billtoaddress1' =>   $addr->addr_line1,
+                'cmhead_billtoaddress2' =>   $addr->addr_line2,
+                'cmhead_billtoaddress3' =>   $addr->addr_line3,
+                'cmhead_billtocity' =>       $addr->addr_city,
+                'cmhead_billtostate' =>      $addr->addr_state,
+                'cmhead_billtozipcode' =>    $addr->addr_postalcode,
+                'cmhead_billtocountry'  =>   $addr->addr_country,
+            ));
+        }
+    }
+    
+    function toRooArray($req)
+    {
+        
+        $ret = $this->toArray();
+        // seaching for order id's does not include id..
+        if (!$this->cmhead_id) {
+            return $ret;
+        }
+        
+        $l = $this->factory('cmhead');
+        $l->selectAdd();
+        $l->selectAdd("
+              calcsalesordersubtotal(cmhead_id::integer) as cmhead_subtotal,
+              calcsalesordertax(cmhead_id::integer) as cmhead_tax
+        ");
+        $l->get($this->pid());
+        $x = $l->toArray('%s', true);
+        $ret = $ret + $x;
+        return $ret;
+    }
+    
+    function nextNumber()
+    {
+        //DB_DataObject::debugLevel(1);
+        $cp = DB_DataObject::factory('cmhead');
+        $date = substr(date('Y'), -2);
+        
+        $pr = "CM-". strtoupper(substr($this->database(), -2)).$date."-";
+        $cp->whereAdd("cmhead_number LIKE '$pr%'");
+        
+
+        $cp->orderBy('cmhead_number DESC');
+        $cp->limit(1);
+        $res = $cp->fetchAll('cmhead_number');
+        
+        if (empty($res)) {
+            $np = '9999';
+        } else {
+            $last = $res[0];
+            $np = substr($last,strlen($pr)) *1;
+        }
+        
+        return $pr . sprintf('%04d', ($np+1));
+    }
+    
+    function post($roo)
+    {
+        $tn = $this->tableName();
+        // check we are ready to go..
+        if (empty($this->cmhead_location_id)) {
+            $roo->jerr("no location provided");
+        }
+        if (!empty($this->cmhead_posted)) {
+            $roo->jerr("credit memo is already posted");
+        }
+        
+        // we have created a cmhead..
+        $ret = $this->pid();
+        $db = DB_DataObject::factory($tn);
+        $db->query("SELECT postCreditMemo({$ret}, 0) as result");
+        $db->fetch();
+        if (empty($db->result) || $db->result < 0) {
+            $roo->jerr("postCreditMemo failed with result being {$db->result}! " .
+                        print_r($ret,true) );
+        }
+       
+        $itemlocdist_series = $db->result;
+
+        // print_r("\nDEBUG: {$itemlocdist_series} \n");
+
+        $db = DB_DataObject::factory($tn);
+        $db->query("SELECT itemlocdist_id,
+                itemlocdist_reqlotserial,
+                itemlocdist_distlotserial,
+                itemlocdist_qty,
+                itemsite_loccntrl,
+                itemsite_controlmethod,
+                itemsite_perishable,
+                itemsite_warrpurc,
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                FROM itemlocdist, itemsite
+                WHERE ( (itemlocdist_itemsite_id=itemsite_id) 
+                        AND (itemlocdist_series={$itemlocdist_series}) ) 
+                ORDER BY itemlocdist_id
+        ");
+
+        while ($db->fetch()) {
+            if (empty($db->itemlocdist_id) || $db->itemlocdist_id < 0) {
+                die("itemlocdist_id isn't found! \n");
+            }
+            $itemlocdist_id = $db->itemlocdist_id;
+
+            $sdb = DB_DataObject::factory($tn);
+            $sdb->query("INSERT INTO itemlocdist (itemlocdist_itemlocdist_id,
+                            itemlocdist_source_type,
+                            itemlocdist_source_id,
+                            itemlocdist_qty,
+                            itemlocdist_ls_id, itemlocdist_expiration
+                    )
+                    SELECT itemlocdist_id, 
+                            'L', 
+                            {$this->cmhead_location_id}, 
+                            itemlocdist_qty, 
+                            itemlocdist_ls_id,
+                            endOfTime()
+                    FROM itemlocdist
+                    WHERE (itemlocdist_id={$itemlocdist_id})
+            ");
+
+
+            $sdb = DB_DataObject::factory($tn);
+            $sdb->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+            $sdb->fetch();
+        }
+
+        $db = DB_DataObject::factory($tn);                    
+        $db->query("SELECT postItemlocseries({$itemlocdist_series}) AS result");
+        $db->fetch();
+        
+        
+        
+        $loc = DB_DataObject::Factory('location');
+        if (!$loc->get($this->cmhead_location_id)) {
+            $roo->jerr("no location specified");
+        }
+        
+        $cust = $loc->customer();
+        if (!$cust) {
+            $roo->jerr("the location specified does not have a customer associated with it.");
+        }
+        $our_db = substr($this->database(),-2);
+        
+        
+        $loc_db = $cust->char('INTERNALCOMPANY');
+        
+        $loc_db = empty($loc_db) ? $our_db : $loc_db ;
+        
+        // this now needs to create a credit memo in HK to transfer the stock back to HK..
+         
+        // transfer if necessary..
+        if ($our_db != $loc_db) {
+            if (HTML_FlexyFramework::get()->cli) {  
+                $roo->jerr("CLI can not be used to do transfer");
+            }
+            
+            $res  = $this->doStockTransfer($roo);
+            if (true !== $res) {
+                // rollback handled by top level..
+                //$s->query("ROLLBACK");
+                
+                return $res;
+            }
+            
+            
+        }
+        
+        
+        
+        
+        
+        return true;
+        // end handling items being posted..
+    }
+    // SG ONLY ... - creates a matching credit memo in HK..
+    
+    /*
+     *  this is for voiding a un-apply credit memo
+     *  voidcreditmemo(integer)
+     *  pCmheadid ALIAS FOR $1;
+     * 
+     */
+    function void($roo)
+    {   
+        $tn = $this->tableName();
+        
+        if (empty($this->cmhead_posted)) {
+            $roo->jerr("credit memo is not posted");
+        }
+        
+        
+        // check who can do this..
+        $admin = DB_DataObject::factory('groups')->lookup('name', 'Administrators' );
+        if (
+                ($this->cmhead_salesrep_id != $roo->authUser->salesrep()->pid())
+                &&
+                (!in_array($roo->authUser->pid() , $admin->memberIds()))
+           )
+        {
+            $roo->jerr("you may not void this credit memo - you must be the sales rep or an administrator");
+            
+        }
+        
+        
+        
+        // check apply??
+        $aropen = DB_DataObject::factory('aropen');
+        $aropen->aropen_docnumber = $this->cmhead_number;
+        $aropen->doctype = 'C';
+        if(!$aropen->find(true)){
+            $roo->jerr("Error occur on finding aropen id for {$this->cmhead_number}");
+        }
+        
+        $arapply = DB_DataObject::factory('arapply');
+        $arapply->whereAdd("
+            arapply_target_aropen_id = {$aropen->pid()}
+            OR
+            arapply_source_aropen_id = {$aropen->pid()}
+        ");
+        
+        if($arapply->find(true)){
+            $roo->jerr("Can not void {$this->cmhead_number} since it has applied to application");
+        }
+        
+        $this->checkLocationStock($roo);
+        
+        $ret = $this->pid();
+        
+        $db = DB_DataObject::factory($tn);
+        $db->query("SELECT voidCreditMemo({$ret}) as result");
+        $db->fetch();
+        if (empty($db->result) || $db->result < 0) {
+            $roo->jerr("voidCreditMemo failed with result being {$db->result}! " .  print_r($ret,true) );
+        }
+       
+        $itemlocdist_series = $db->result;
+         //$roo->jerr("$itemlocdist_series");
+         
+         
+         
+        
+        
+         
+        $db = DB_DataObject::factory($tn);
+        $db->query("SELECT itemlocdist_id,
+                itemlocdist_reqlotserial,
+                itemlocdist_distlotserial,
+                itemlocdist_qty,
+                itemsite_loccntrl,
+                itemsite_controlmethod,
+                itemsite_perishable,
+                itemsite_warrpurc,
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                FROM itemlocdist, itemsite
+                WHERE ( (itemlocdist_itemsite_id=itemsite_id) 
+                        AND (itemlocdist_series={$itemlocdist_series}) ) 
+                ORDER BY itemlocdist_id
+        ");
+
+        while ($db->fetch()) {
+            if (empty($db->itemlocdist_id) || $db->itemlocdist_id < 0) {
+                die("itemlocdist_id isn't found! \n");
+            }
+            $itemlocdist_id = $db->itemlocdist_id;
+
+            $sdb = DB_DataObject::factory($tn);
+            $sdb->query("INSERT INTO itemlocdist (itemlocdist_itemlocdist_id,
+                            itemlocdist_source_type,
+                            itemlocdist_source_id,
+                            itemlocdist_qty,
+                            itemlocdist_ls_id, itemlocdist_expiration
+                    )
+                    SELECT itemlocdist_id, 
+                            'L', 
+                            {$this->cmhead_location_id}, 
+                            itemlocdist_qty, 
+                            itemlocdist_ls_id,
+                            endOfTime()
+                    FROM itemlocdist
+                    WHERE (itemlocdist_id={$itemlocdist_id})
+            ");
+
+
+            $sdb = DB_DataObject::factory($tn);
+            $sdb->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+            $sdb->fetch();
+        }
+
+               
+        
+        // this generates an additional itemlocdist record..
+         
+        
+        
+        
+        $db = DB_DataObject::factory($tn);                    
+        $db->query("SELECT postItemlocseries({$itemlocdist_series}) AS result");
+        $db->fetch();
+        
+        return true;
+        
+    }
+    
+    
+    function fixCmvoid()
+    {
+       $query = " select * from invhist where invhist_comments like 'Credit Voided%' and not invhist_hasdetail ";
+       
+       // fetch the CM-head based on ordnumber
+       // 
+       // look up in itemloc -> what the current qty is..
+       
+       // search for invdetail - with same doc number invdetail_qty > 0 - distinct locatoin_id 
+       //if more than 1.. error out.. and let's check them;
+       
+$query = " 
+         INSERT INTO invdetail
+            ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+              invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration, 
+              invdetail_warrpurc )
+              
+
+
+            SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
+                   _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
+                   itemloc_expiration,_itemlocdist.warranty
+            FROM itemloc
+            WHERE (itemloc_id=_itemlocid)
+            
+
+";
+$query = " 
+        --  Update the parent invhist to indicate that it has invdetail records
+            UPDATE invhist
+            SET invhist_hasdetail=TRUE
+            WHERE ((invhist_hasdetail=FALSE)
+             AND (invhist_id=_itemlocdist.invhistid));
+             ";
+
+    }
+    
+    
+    function doStockTransfer($roo)
+    {
+        $roo->jerr("cross company transfer disabled");
+        $items =  $this->items();
+        
+        
+        $items = $this->sellToHK($roo, $items); // remove the stock so that HK can have it..
+        
+
+        $ff = HTML_FlexyFramework::get();
+        
+        if (empty($ff->Xtuple['main_url'])) {
+            $roo->jerr("Xtuple['main_url'] is not configured");
+        }
+        if (empty($ff->Xtuple['main_remote_cust_number'])) {
+            //$roo->jerr( "Xtuple['main_remote_cust_number'] is not configured");
+            $roo->jerr("Old code using remote_customer - disabled");
+        }
+        
+        
+        
+        
+        $loc = DB_DataObject::Factory('location');
+        $loc->get($this->cmhead_location_id); 
+        
+        
+        
+        
+        
+        // on hk side..
+        //Needs to know 
+        //  Order number (so it can be voided later..)
+        //  list of items (and the source location)
+        //  Qty
+        //  UnitPrice?? - this should be the FIFO cost..
+        
+        
+        // on the signapore site
+        
+        $full = DB_DataObject::Factory('cmhead');
+        $full->autoJoin();
+        $full->get($this->pid());
+        
+        $roo->jerr("Old code using remote_customer - disabled");
+        
+        require_once 'HTTP/Request.php';
+        
+        $req = new HTTP_Request( $ff->Xtuple['main_url'] . '/Roo/Cmhead' );
+        $req->setMethod(HTTP_REQUEST_METHOD_POST);
+     
+        
+        $base = $this->toArray();
+        unset($base['cmhead_id']);
+        unset($base['cmhead_id']);
+                    
+        $req->addPostData( array(
+                '_is_xfer' => 1,
+                
+                
+                'cmhead_number' => 'XF-' . $full->cmhead_number,
+                'cust_number' => $ff->Xtuple['main_remote_cust_number'], // $roo->jerr("Old code using remote_customer - disabled");
+                'cmhead_docdate' => $full->cmhead_docdate,
+    
+                
+                'cmhead_freight' => 0 , //$full->cmhead_freight ,
+                'cmhead_misc' => 0, //$full->cmhead_misc,
+            
+                'cmhead_comments' => $full->cmhead_comments,
+                //'cmhead_misc_descrip'=> '', //$full->cmhead_misc_descrip,
+                
+                'location_name' => $full->cmhead_location_id_location_name,
+                //'cmhead_misc_accnt_id_accnt_number' => $full->cmhead_misc_accnt_id_accnt_number,
+                
+    
+                //'cmhead_curr_id;                  // int4(4)  default_basecurrid%28%29
+                //cmhead_freighttaxtype_id;        // int4(4)  
+                //public $cmhead_salesrep_id;              // int4(4)  
+    
+                //cmhead_taxzone_id;               // int4(4)  
+    
+                 
+                'items' => $items,
+                
+        ));
+        
+        $res = $req->sendRequest();
+        if (is_a($res,'PEAR_Error')) {
+            $roo->jerr( "MAIN REQUEST RETURNED: ". $res->toString());
+        }
+        $res = json_decode($req->getResponseBody());
+        
+        
+        
+        if (!is_object($res)) {
+            $roo->jerr("MAIN REQUEST RETURNED: ". $req->getResponseBody());
+        }
+        
+        if (!$res->success) {
+            $roo->jerr("MAIN REQUEST RETURNED: ". $res->errorMsg);
+        }
+         
+        return true;
+         
+        
+    }
+         
+    function sellToHK($roo,$items)
+    {
+        
+        $ff = HTML_FlexyFramework::get();
+
+        $out = array();
+        foreach($items as $item) {
+            
+            $xitem = $item->itemsite()->item();
+            if (!isset($item_req[$xitem ->item_number])) {
+                $item_req[$xitem ->item_number] = 0;
+            }
+            $item_req[$xitem->item_number] += $item->cmitem_qtycredit;
+            
+            $out[] = array(
+                
+                'linenumber'=> $item->cmitem_linenumber,
+                'item_number'=> $xitem->item_number,
+                'qty' => $item->cmitem_qtycredit    
+            );
+            
+            
+        }
+        
+        
+        $po = DB_DataObject::factory('pohead');
+        
+        //print_R($item_req);exit;
+        
+        $prices = $po->fetchXferPrices($roo, $item_req);
+       
+        // now read the data and fill in the values..
+        foreach($out as $i=>$item) {
+            
+            if (!isset($prices[$item['item_number']])) {
+                $roo->jerr( "ERROR MAIN REQUEST FAILED TO RETURN PRICE FOR {$item['item_number']}");
+            }
+            $out[$i]['unitprice'] = $prices[$item['item_number']];
+        }
+       
+        $loc = DB_DataObject::Factory('location');
+        $loc->get($this->cmhead_location_id); 
+        
+        //print_R($out);exit;
+        
+        $cust = DB_DataObject::Factory('custinfo');
+        $cust ->get('cust_number', $ff->Xtuple['main_vendor_number']);
+        
+        $curr= DB_DataObject::Factory('curr_symbol');
+        $curr->get('curr_abbr', 'HKD');
+        
+        // now make a debit memo... for the transaction..
+        $d = DB_DataObject::Factory('invchead');
+        $d->handleXfer($roo, array(
+        
+         
+                'invchead_invcnumber' => 'XF-'.$this->cmhead_number,  // invoice should match number...
+                'invchead_orderdate' => $this->cmhead_docdate,
+                'invchead_invcdate' => $this->cmhead_docdate,
+                'cust_number' => $cust->cust_number,
+                'invchead_curr_id' => $curr->pid(),
+                'invchead_posted' => false,
+                'invchead_printed' => false,
+                'invchead_commission' => 0,
+                'invchead_freight' => 0,
+                'invchead_misc_amount' => 0,
+                'invchead_shipchrg_id' => -1,
+                
+                'src_location' => $loc->location_name,
+                
+                'items' => $out,
+          
+        ));
+        
+        return $out;
+        
+        
+        
+    }
+    
+    // in HK... we recieved a  transfer CM..
+    function recieveXfer($roo, $r)
+    {
+        
+        //$roo->jerr("xfer testing");
+        $cm = DB_DataObject::factory('cmhead');
+        $cm->setFrom($r);
+        
+        foreach($cm->defaults() as $k=>$v) {
+            if (!isset($r[$k])) {
+                $cm->$k  = $v;
+            }
+        }
+        
+        if (empty($r['location_name'])) {
+            $roo->jerr("no location name recieved.");
+        }
+        $loc = DB_DataObject::Factory('location');
+        if (!$loc->get('location_name', $r['location_name'])) {
+            $roo->jerr("could not find lcoation {$r['location_name']}");
+        }
+        $cm->cmhead_location_id = $loc->pid();
+        
+        
+        if (empty($r['cust_number'])) {
+            $roo->jerr("no cust_number   recieved.");
+        }
+        $cust = DB_DataObject::Factory('custinfo');
+        if (!$cust->get('cust_number', $r['cust_number'])) {
+            $roo->jerr("could not find customer number : {$r['cust_number']}");
+           
+        }
+        $cm->cmhead_cust_id = $cust->pid();
+        
+         
+        $cm->insert();
+        
+        foreach($r['items'] as $item) {
+            $i = DB_DataObject::Factory('cmitem');
+            $i->recieveXfer($roo,$cm, $item);
+            
+        }
+        
+        $cm->post($roo);
+        
+        // fill in our varous data...
+        
+        
+        $roo->jok("transfered");
+        
+        
+        
+    }
+    
+    function joinAddAropen()
+    {
+        $aropen = DB_DataObject::factory('aropen');
+        $this->_join .= "
+            LEFT JOIN aropen join_cmhead_aropen_id
+            ON
+            join_cmhead_aropen_id.aropen_doctype = 'C'
+            AND
+            join_cmhead_aropen_id.aropen_docnumber = cmhead_number
+            AND
+            join_cmhead_aropen_id.aropen_cust_id = cmhead_cust_id
+            AND
+            aropen_open
+        ";
+        
+        $this->selectAs($aropen, 'cmhead_aropen_id_%s', 'join_cmhead_aropen_id');
+    }
+    
+    function checkLocationStock($roo)
+    {
+        if(empty($roo->bootLoader->Xtuple['prevent_negative'])){
+            return;
+        }
+        
+        $items = $this->items();
+        
+        $stock = array();
+        
+        foreach ($items as $item){
+            if(empty($item->cmitem_qtycredit)){
+                continue;
+            }
+            
+            $balance = $item->itemsite()->checkLocationStock($this->cmhead_location_id);
+            
+            if(empty($balance) || $balance < $item->cmitem_qtycredit){
+                $stock[] = $item->itemsite()->item()->item_number;
+            }
+        }
+
+        if(count($stock)){
+            $roo->jerr("These items have negative stock " . implode(', ', $stock));
+        }
+    }
+    
+}
diff --git a/DataObjects/Cmheadtax.php b/DataObjects/Cmheadtax.php
new file mode 100644 (file)
index 0000000..702520c
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for cmheadtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmheadtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmheadtax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cmitem.php b/DataObjects/Cmitem.php
new file mode 100644 (file)
index 0000000..3cf36ad
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/**
+ * Table Definition for cmitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmitem';              // table name
+    public $cmitem_id;                       // int4(4)  not_null default_nextval%28%28cmitem_cmitem_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cmitem_cmhead_id;                // int4(4)  not_null unique_key multiple_key
+    public $cmitem_linenumber;               // int4(4)  not_null unique_key multiple_key
+    public $cmitem_itemsite_id;              // int4(4)  not_null
+    public $cmitem_qtycredit;                // numeric(-1)  not_null
+    public $cmitem_qtyreturned;              // numeric(-1)  not_null
+    public $cmitem_unitprice;                // numeric(-1)  not_null
+    public $cmitem_comments;                 // text(-1)  
+    public $cmitem_rsncode_id;               // int4(4)  
+    public $cmitem_taxtype_id;               // int4(4)  
+    public $cmitem_qty_uom_id;               // int4(4)  not_null
+    public $cmitem_qty_invuomratio;          // numeric(-1)  not_null
+    public $cmitem_price_uom_id;             // int4(4)  not_null
+    public $cmitem_price_invuomratio;        // numeric(-1)  not_null
+    public $cmitem_raitem_id;                // int4(4)  
+    public $cmitem_updateinv;                // bool(1)  not_null default_true
+    
+   /**
+    * Getter / Setter for $cmitem_cmhead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cmhead() {
+        return func_num_args() ? $this->link('cmitem_cmhead_id', func_get_arg(0)) : $this->link('cmitem_cmhead_id');
+    }
+    
+    /**
+    * Getter / Setter for $cmitem_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('cmitem_itemsite_id', func_get_arg(0)) : $this->link('cmitem_itemsite_id');
+    }
+
+   /**
+    * Getter / Setter for $cmitem_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('cmitem_price_uom_id', func_get_arg(0)) : $this->link('cmitem_price_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $cmitem_qty_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qty_uom() {
+        return func_num_args() ? $this->link('cmitem_qty_uom_id', func_get_arg(0)) : $this->link('cmitem_qty_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $cmitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('cmitem_taxtype_id', func_get_arg(0)) : $this->link('cmitem_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function defaults()
+    {   
+        return array(
+            'cmitem_qty_uom_id' => $this->sqlValue("( SELECT uom_id FROM uom WHERE uom_name = 'EA' LIMIT 1)"),
+            'cmitem_price_uom_id' => $this->sqlValue("( SELECT uom_id FROM uom WHERE uom_name = 'EA' LIMIT 1)"),
+            'cmitem_qty_invuomratio' => 1,
+            'cmitem_price_invuomratio' => 1,
+            'cmitem_taxtype_id' => $this->sqlValue("gettaxtypeid('Taxable'::text)"),
+            'cmitem_raitem_id' => $this->sqlValue('NULL')
+        );
+    }
+    
+    function applyFilters($q, $au)
+    {   
+        
+        $tbl = $this->tableName();
+        //DB_DataObject::DebugLevel(1);
+        // add the join for items...
+        $item = DB_DataObject::Factory('item');
+        
+        $this->_join .= "\n INNER JOIN item AS join_cmitem_item ON
+            join_cmitem_itemsite_id_itemsite_id.itemsite_item_id = join_cmitem_item.item_id";
+        $this->selectAs($item, '%s', 'join_cmitem_item');
+        //Db_DAtaObject::debugLevel(1);
+        $this->selectAdd( "(
+                SELECT uom_descrip FROM uom where uom_id=cmitem_qty_uom_id LIMIT 1)
+                as cmitem_qty_uom_id_descrip"
+        );
+         
+        $this->selectAdd('(cmitem_unitprice * cmitem_qtyreturned) as cmitem_line_value');
+        
+        $this->selectAdd("
+            gettaxtypeid('Taxable') AS cmitem_taxable_id,
+            
+            ROUND(itemprice(join_cmitem_item.item_id, join_cmitem_cmhead_id_cmhead_id.cmhead_cust_id, -1, 1, join_cmitem_cmhead_id_cmhead_id.cmhead_curr_id,  NOW()::date),3) 
+            AS cmitem_item_listprice
+        ");
+        
+    }
+    
+    
+    function beforeInsert($req, $roo)
+    {
+       
+        foreach($this->defaults() as $k=>$v) {
+            if (empty($this->$k)) {
+                $this->$k = $v;
+            }
+        }
+        
+        $this->cmitem_qtycredit = $req['cmitem_qtycredit'];
+        $this->cmitem_qtyreturned = $req['cmitem_qtycredit'];
+        //print_r($this);exit;
+    }
+    
+    function beforeUpdate($old, $req, $roo)
+    {
+        
+        foreach($this->defaults() as $k=>$v) {
+            if (empty($this->$k)) {
+                $this->$k = $v;
+            }
+        }
+        
+        $this->cmitem_qtycredit = $req['cmitem_qtycredit'];
+        $this->cmitem_qtyreturned = $req['cmitem_qtycredit'];
+    }
+    function beforeDelete($deps, $roo)
+    {
+        $ch = $this->cmhead();
+        if ($ch->cmhead_posted) {
+            $roo->jerr("memo is posted");
+        }
+        $tax = DB_DataObject::Factory('cmitemtax');
+        $tax->taxhist_parent_id =  $this->pid();
+        $all = $tax->fetchAll() ;
+        foreach($all as $x) {
+            if ($x->taxhist_journalnumber) {
+                $roo->jerr("line has been posted");
+            }
+            $x->delete();
+        }
+        //$roo->jerr(count($all));
+        return true;
+        
+        
+    }
+    function recieveXfer($roo, $head, $r)
+    {
+        
+        
+        $item = DB_DataObject::Factory('item');
+        $item->get('item_number', $r['item_number']);
+        $itemsite = $item->itemsite();
+        
+        $this->setFrom($this->defaults());
+        
+        $this->cmitem_cmhead_id = $head->pid();
+        $this->cmitem_linenumber = $r['linenumber'];
+        $this->cmitem_itemsite_id = $itemsite->pid();
+        $this->cmitem_qtycredit = $r['qty'];
+        $this->cmitem_qtyreturned = $r['qty'];
+        $this->cmitem_unitprice = $r['unitprice']; // CHECK CURRNECY!?!?
+        $this->cmitem_comments = '';                 // text(-1)  
+        $this->cmitem_updateinv = true;                // bool(1)  not_null default_true
+
+        $this->insert();
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Cmitemtax.php b/DataObjects/Cmitemtax.php
new file mode 100644 (file)
index 0000000..602b779
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for cmitemtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmitemtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmitemtax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cmnttype.php b/DataObjects/Cmnttype.php
new file mode 100644 (file)
index 0000000..6716e4c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for cmnttype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmnttype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmnttype';            // table name
+    public $cmnttype_id;                     // int4(4)  not_null default_nextval%28cmnttype_cmnttype_id_seq%29 primary_key
+    public $cmnttype_name;                   // text(-1)  not_null unique_key
+    public $cmnttype_descrip;                // text(-1)  not_null
+    public $cmnttype_usedin;                 // text(-1)  
+    public $cmnttype_sys;                    // bool(1)  not_null default_false
+    public $cmnttype_editable;               // bool(1)  not_null default_false
+    public $cmnttype_order;                  // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cmnttypesource.php b/DataObjects/Cmnttypesource.php
new file mode 100644 (file)
index 0000000..f3359c0
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for cmnttypesource
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cmnttypesource extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cmnttypesource';      // table name
+    public $cmnttypesource_id;               // int4(4)  not_null default_nextval%28cmnttypesource_cmnttypesource_id_seq%29 primary_key
+    public $cmnttypesource_cmnttype_id;      // int4(4)  
+    public $cmnttypesource_source_id;        // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cntct.php b/DataObjects/Cntct.php
new file mode 100644 (file)
index 0000000..36e4bba
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Table Definition for cntct
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntct extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntct';               // table name
+    public $cntct_id;                        // int4(4)  not_null default_nextval%28cntct_cntct_id_seq%29 primary_key
+    public $cntct_crmacct_id;                // int4(4)  
+    public $cntct_addr_id;                   // int4(4)  
+    public $cntct_first_name;                // text(-1)  
+    public $cntct_last_name;                 // text(-1)  
+    public $cntct_honorific;                 // text(-1)  
+    public $cntct_initials;                  // text(-1)  
+    public $cntct_active;                    // bool(1)  default_true
+    public $cntct_phone;                     // text(-1)  
+    public $cntct_phone2;                    // text(-1)  
+    public $cntct_fax;                       // text(-1)  
+    public $cntct_email;                     // text(-1)  
+    public $cntct_webaddr;                   // text(-1)  
+    public $cntct_notes;                     // text(-1)  
+    public $cntct_title;                     // text(-1)  
+    public $cntct_number;                    // text(-1)  not_null unique_key
+    public $cntct_middle;                    // text(-1)  
+    public $cntct_suffix;                    // text(-1)  
+    public $cntct_owner_username;            // text(-1)  
+    public $cntct_name;                      // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $cntct_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('cntct_addr_id', func_get_arg(0)) : $this->link('cntct_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $cntct_crmacct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function crmacct() {
+        return func_num_args() ? $this->link('cntct_crmacct_id', func_get_arg(0)) : $this->link('cntct_crmacct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function shipto()
+    {
+        $sh  = DB_DataObject::factory('shiptoinfo');
+        if ($sh->get('shipto_cntct_id', $this->cntct_id)) {
+            return $sh;
+        }
+        return DB_DataObject::factory('shiptoinfo');
+        
+    }
+    
+    
+    
+    
+    
+   // _customer_id
+    function applyFilters($q, $au)
+    {
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['_customer_id'])) {
+            $cid = $q['_customer_id'];
+           // DB_DataObject::DebugLevel(1);
+            $this->whereAdd("
+                    cntct_crmacct_id = (SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = $cid)
+                    ");
+        }
+        if (!empty($q['_add_is_types'])) {
+            $this->selectAdd("
+                0 as is_main,
+                (SELECT int4smaller(1,COUNT(shipto_id)::int) FROM shiptoinfo where
+                    shipto_cntct_id = cntct_id and shipto_active = true) as is_ship   
+            ");
+        }
+        if (!empty($q['query']['with_shipinfo'])) {   
+            $this->whereAdd("cntct_id IN (SELECT shipto_cntct_id FROM
+                            shiptoinfo
+                            WHERE
+                            shipto_active= true
+                            AND
+                            shipto_cntct_id IS NOT NULL
+                            )");
+        }
+        
+        if (!empty($q['query']['cntct_name'])) {
+            $this->whereAdd("cntct_name ILIKE '{$this->escape($q['query']['cntct_name'])}%'");
+        }
+        
+        
+        
+    }
+    function toShortArray()
+    {
+        
+        $ar = $this->toArray();
+        $ret = array();
+        foreach ($ar as $k =>$v) {
+            $ret[substr($k,6)] = $v;
+        }
+        return $ret;
+        
+    }
+    
+    function genNumber()
+    {
+        $l = $this->cntct_first_name . ' '. $this->cntct_last_name ;
+        $l = trim($l);// text(-1)
+        if (empty($l)) {
+            $l = 'Contact';
+        }
+        $x = DB_DataObject::Factory('cntct');
+        $suf = 0;
+        while ($x->get('cntct_number', $l . (!$suf ? '' : '-' . $suf))) {
+            $x = DB_DataObject::Factory('cntct');
+            $suf++;
+             
+        }
+        // got a suf..
+        $this->cntct_number = $l . (!$suf ? '' : '-' . $suf);
+        
+        
+    }
+    
+    function beforeInsert($q, $roo)
+    {
+        if (empty($this->cntct_number)) {
+            $this->genNumber();
+        }
+        if (empty($this->cntct_name)) {
+            $this->cntct_name = $this->cntct_first_name . ' '. $this->cntct_last_name ;  
+        }
+        
+        if (!empty($q['customer_id'])) {
+            $crm  = DB_DataObject::factory('crmacct');
+            $crm->get('crmacct_cust_id' , $q['customer_id']);
+            $this->cntct_crmacct_id = $crm->pid();
+        }
+        if (empty($this->cntct_addr_id)) {
+            $this->cntct_addr_id = $this->sqlValue('NULL');
+        }
+        
+    }
+    
+    function onInsert($q, $roo)
+    {
+        $this->fillAddr($roo,$q);
+        
+    }
+    function onUpdate($old, $q, $roo)
+    {
+        $this->fillAddr($roo,$q);
+        
+    }
+    function fillAddr($roo, $q)
+    {
+        $t = DB_DataObject::Factory('cntct');
+        $t->get($this->pid());
+        //
+        //$roo->jerr("testing - ignore this" . print_r($q, true));
+        if (!isset($q['cntct_addr_id_addr_line1'])) {
+            return;
+        }
+        //DB_DataObject::DebugLevel(1);
+        $oldaddr = false;
+        $addr = DB_DataObject::Factory('addr');
+        if ($t->cntct_addr_id) {
+            $addr->get($t->cntct_addr_id);
+            $oldaddr = clone($addr);
+        }
+        $addr->setFrom($q, 'cntct_addr_id_%s');
+        
+        if ($oldaddr) {
+            $addr->update($oldaddr);
+            return;
+        }
+        // init the number?
+        $old = clone($t);
+        $addr->genNumber();
+        $t->cntct_addr_id = $addr->insert();
+        $t->update($old);
+        
+        
+        
+        
+    }
+    
+    function createFromArray($c)
+    {
+        $this->setFrom($c);
+        $this->genNumber();
+        $this->insert();
+        return $this;
+    }
+    
+    
+}
diff --git a/DataObjects/Cntctaddr.php b/DataObjects/Cntctaddr.php
new file mode 100644 (file)
index 0000000..6c4bc2b
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Table Definition for cntctaddr = it's a view, but needs to be creatable..
+ */
+
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntctaddr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntctaddr';               // table name
+}
\ No newline at end of file
diff --git a/DataObjects/Cntctdata.php b/DataObjects/Cntctdata.php
new file mode 100644 (file)
index 0000000..bc0767e
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Table Definition for cntctaddr = it's a view, but needs to be creatable..
+ */
+
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntctdata extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntctdata';               // table name
+}
+
diff --git a/DataObjects/Cntcteml.php b/DataObjects/Cntcteml.php
new file mode 100644 (file)
index 0000000..33f8b76
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for cntcteml
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntcteml extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntcteml';            // table name
+    public $cntcteml_id;                     // int4(4)  not_null default_nextval%28cntcteml_cntcteml_id_seq%29 primary_key
+    public $cntcteml_cntct_id;               // int4(4)  
+    public $cntcteml_primary;                // bool(1)  not_null default_false
+    public $cntcteml_email;                  // text(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $cntcteml_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('cntcteml_cntct_id', func_get_arg(0)) : $this->link('cntcteml_cntct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cntctmrgd.php b/DataObjects/Cntctmrgd.php
new file mode 100644 (file)
index 0000000..bfd077c
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Table Definition for cntctmrgd
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntctmrgd extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntctmrgd';           // table name
+    public $cntctmrgd_cntct_id;              // int4(4)  not_null primary_key
+    public $cntctmrgd_error;                 // bool(1)  default_false
+
+    
+   /**
+    * Getter / Setter for $cntctmrgd_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('cntctmrgd_cntct_id', func_get_arg(0)) : $this->link('cntctmrgd_cntct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cntctsel.php b/DataObjects/Cntctsel.php
new file mode 100644 (file)
index 0000000..2a1a831
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Table Definition for cntctsel
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntctsel extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntctsel';            // table name
+    public $cntctsel_cntct_id;               // int4(4)  not_null primary_key
+    public $cntctsel_target;                 // bool(1)  
+    public $cntctsel_mrg_crmacct_id;         // bool(1)  default_false
+    public $cntctsel_mrg_addr_id;            // bool(1)  default_false
+    public $cntctsel_mrg_first_name;         // bool(1)  default_false
+    public $cntctsel_mrg_last_name;          // bool(1)  default_false
+    public $cntctsel_mrg_honorific;          // bool(1)  default_false
+    public $cntctsel_mrg_initials;           // bool(1)  default_false
+    public $cntctsel_mrg_phone;              // bool(1)  default_false
+    public $cntctsel_mrg_phone2;             // bool(1)  default_false
+    public $cntctsel_mrg_fax;                // bool(1)  default_false
+    public $cntctsel_mrg_email;              // bool(1)  default_false
+    public $cntctsel_mrg_webaddr;            // bool(1)  default_false
+    public $cntctsel_mrg_notes;              // bool(1)  default_false
+    public $cntctsel_mrg_title;              // bool(1)  default_false
+    public $cntctsel_mrg_middle;             // bool(1)  default_false
+    public $cntctsel_mrg_suffix;             // bool(1)  default_false
+    public $cntctsel_mrg_owner_username;     // bool(1)  default_false
+
+    
+   /**
+    * Getter / Setter for $cntctsel_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('cntctsel_cntct_id', func_get_arg(0)) : $this->link('cntctsel_cntct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cntslip.php b/DataObjects/Cntslip.php
new file mode 100644 (file)
index 0000000..5d68587
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Table Definition for cntslip
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cntslip extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cntslip';             // table name
+    public $cntslip_id;                      // int4(4)  not_null default_nextval%28%28%22cntslip_cntslip_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $cntslip_cnttag_id;               // int4(4)  
+    public $cntslip_entered;                 // timestamptz(8)  
+    public $cntslip_posted;                  // bool(1)  
+    public $cntslip_number;                  // text(-1)  
+    public $cntslip_qty;                     // numeric(-1)  
+    public $cntslip_comments;                // text(-1)  
+    public $cntslip_location_id;             // int4(4)  
+    public $cntslip_lotserial;               // text(-1)  
+    public $cntslip_lotserial_expiration;    // date(4)  
+    public $cntslip_lotserial_warrpurc;      // date(4)  
+    public $cntslip_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cobapply.php b/DataObjects/Cobapply.php
new file mode 100644 (file)
index 0000000..f795f0c
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Table Definition for cntslip
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cobapply extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cobapply';             // table name
+    public $cobapply_id;                      //  
+     
+    public $cobapply_cobmisc_id; // integer,
+    public $cobapply_aropen_id; // integer,
+    public $cobapply_applied; // boolean,
+  
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function aropen() {
+        $d = DB_DataObject::Factory('aropen');
+        $d->get($this->cobapply_aropen_id);
+        return $d;
+        
+    }
+    
+    function onDelete($request, $roo)
+    {
+        if(isset($request['_void'])){
+            $this->void($roo);
+        }
+    }
+    
+    /*
+     * this is for voiding a applied credit memo 
+     * voidarcreditmemoapplication(integer)
+     * i_id ALIAS FOR $1; -- arapply_id
+     * 
+     */
+    
+    function void($roo)
+    {
+        $cobmisc = DB_DataObject::factory('cobmisc');
+        if(!$cobmisc->get($this->cobapply_cobmisc_id)){
+            $roo->jerr('Error occour on getting cobmisc! cobapply id : ' . $this->pid());
+        }
+        
+        $arapply = DB_DataObject::factory('arapply');
+        $arapply->arapply_source_aropen_id = $this->cobapply_aropen_id;
+        $arapply->arapply_target_docnumber = $cobmisc->cobmisc_invcnumber;
+        if(!$arapply->find(true)){
+            return true;
+        }
+        
+        // void the check which belongs to the credit memo.
+        $checkitem = DB_DataObject::factory('checkitem');
+        $checkitem->autoJoin();
+        $checkitem->checkitem_aropen_id = $this->cobapply_aropen_id;
+        $checkitem->whereAdd("
+            join_checkitem_checkhead_id_checkhead_id.checkhead_posted = TRUE
+            AND
+            join_checkitem_checkhead_id_checkhead_id.checkhead_void = FALSE
+            AND
+            join_checkitem_checkhead_id_checkhead_id.checkhead_deleted = FALSE
+
+        ");
+        foreach ($checkitem->fetchAll() as $checki){
+            $checkhead = DB_DataObject::factory('checkhead');
+            if(!$checkhead->get($checki->checkitem_checkhead_id)){
+                continue;
+            }
+            $checkhead->voidPostedCheck($roo);
+        }
+        
+        // void the credit memo
+        
+        $ch = DB_DataObject::Factory('cobapply');
+        $ch->query("SELECT voidarcreditmemoapplication({$arapply->pid()}) AS result");
+        $ch->fetch();
+        if($ch->result < 0){
+            $roo->jerr('Error occour on voiding a applied credit memo! result : ' . $ch->result);
+        }
+    }
+}
diff --git a/DataObjects/Cobill.php b/DataObjects/Cobill.php
new file mode 100644 (file)
index 0000000..d5ba05a
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Table Definition for cobill
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cobill extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cobill';              // table name
+    public $cobill_id;                       // int4(4)  not_null default_nextval%28%28cobill_cobill_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cobill_coitem_id;                // int4(4)  
+    public $cobill_selectdate;               // timestamptz(8)  
+    public $cobill_qty;                      // numeric(-1)  
+    public $cobill_invcnum;                  // int4(4)  
+    public $cobill_toclose;                  // bool(1)  
+    public $cobill_cobmisc_id;               // int4(4)  
+    public $cobill_select_username;          // text(-1)  
+    public $cobill_invcitem_id;              // int4(4)  
+    public $cobill_taxtype_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $cobill_invcitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invcitem() {
+        return func_num_args() ? $this->link('cobill_invcitem_id', func_get_arg(0)) : $this->link('cobill_invcitem_id');
+    }
+
+   /**
+    * Getter / Setter for $cobill_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('cobill_taxtype_id', func_get_arg(0)) : $this->link('cobill_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cobilltax.php b/DataObjects/Cobilltax.php
new file mode 100644 (file)
index 0000000..9915919
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for cobilltax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cobilltax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cobilltax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cobmisc.php b/DataObjects/Cobmisc.php
new file mode 100644 (file)
index 0000000..1415adc
--- /dev/null
@@ -0,0 +1,941 @@
+<?php
+/**
+ * Table Definition for cobmisc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cobmisc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cobmisc';             // table name
+    public $cobmisc_id;                      // int4(4)  not_null default_nextval%28%28cobmisc_cobmisc_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cobmisc_cohead_id;               // int4(4)  
+    public $cobmisc_shipvia;                 // text(-1)  
+    public $cobmisc_freight;                 // numeric(-1)  
+    public $cobmisc_misc;                    // numeric(-1)  
+    public $cobmisc_payment;                 // numeric(-1)  
+    public $cobmisc_paymentref;              // text(-1)  
+    public $cobmisc_notes;                   // text(-1)  
+    public $cobmisc_shipdate;                // date(4)  
+    public $cobmisc_invcnumber;              // int4(4)  
+    public $cobmisc_invcdate;                // date(4)  
+    public $cobmisc_posted;                  // bool(1)  
+    public $cobmisc_misc_accnt_id;           // int4(4)  
+    public $cobmisc_misc_descrip;            // text(-1)  
+    public $cobmisc_closeorder;              // bool(1)  
+    public $cobmisc_curr_id;                 // int4(4)  default_basecurrid%28%29
+    public $cobmisc_invchead_id;             // int4(4)  
+    public $cobmisc_taxzone_id;              // int4(4)  
+    public $cobmisc_taxtype_id;              // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $cobmisc_invchead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invchead() {
+        return func_num_args() ? $this->link('cobmisc_invchead_id', func_get_arg(0)) : $this->link('cobmisc_invchead_id');
+    }
+
+   /**
+    * Getter / Setter for $cobmisc_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('cobmisc_taxtype_id', func_get_arg(0)) : $this->link('cobmisc_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $cobmisc_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('cobmisc_taxzone_id', func_get_arg(0)) : $this->link('cobmisc_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $cobmisc_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cobmisc_curr_id', func_get_arg(0)) : $this->link('cobmisc_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    public function cohead() {
+        
+        if (func_num_args()) {
+            $ar = func_get_arg(0);
+            $this->cobmisc_cohead_id = is_object($ar) ? $ar->pid() : $ar;
+            return $this->cobmisc_cohead_id;
+        }
+        
+        
+        $o = $this->factory('cohead');
+        $o->get($this->cobmisc_cohead_id);
+        return $o;
+    }
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+         if (!empty($q['_stash'])) {
+            return $this->stashList($q['_stash'],$roo);
+        }
+        //DB_DataObject::DebugLevel(1);
+        // summarize how much is invoiced on this one.
+        
+        // find the taxfree
+        $tt = DB_DataObject::Factory('taxtype');
+        if (!$tt->get('taxtype_name' , 'Taxfree')) {
+            // should probably create this as it's simple..
+            $roo->jerr("Taxtype : Taxfree has not been set up");
+        }
+        
+        $this->joinAddCohead();
+        
+         
+        $this->selectAdd("
+            COALESCE((SELECT SUM(cobill_qty) FROM cobill where cobill_cobmisc_id = cobmisc_id), 0) as cobmisc_qty,
+            COALESCE((SELECT SUM(coitem_qtyord) FROM coitem where coitem_cohead_id = cobmisc_cohead_id), 0) as cobmisc_total_qty,
+            
+            COALESCE((
+                SELECT SUM(ROUND(cobill_qty * coitem_price,2))
+                    FROM cobill LEFT JOIN coitem ON
+                        cobill_coitem_id = coitem_id
+                    where cobill_cobmisc_id = cobmisc_id), 0) as cobmisc_itemcost,
+            
+            
+            
+            COALESCE(
+                (SELECT
+                    SUM(calculatetax(
+                        cobmisc_taxzone_id,  coitem_taxtype_id  ,cobmisc_invcdate::date,   cobmisc_curr_id  , cobill_qty * coitem_price
+                    ))
+                    FROM
+                        cobill
+                    LEFT JOIN
+                        coitem
+                    ON
+                        cobill_coitem_id = coitem_id
+                    WHERE
+                        cobill_cobmisc_id = cobmisc_id
+                ), 0) as cobmisc_tax,
+   
+            
+            COALESCE((
+                SELECT
+                        SUM(ROUND(cobill_qty * coitem_price,2))
+                    FROM
+                        cobill
+                    LEFT JOIN coitem ON
+                        cobill_coitem_id = coitem_id
+                    where
+                        cobill_cobmisc_id = cobmisc_id
+                        AND
+                        coitem_taxtype_id = {$tt->pid()}
+            ), 0) as cobmisc_itemcost_taxfree
+                    
+        ");
+        
+        if (!empty($q['_canCreate'])) {
+            // check if an invoice can be created..
+            $ret = array();
+            $x = $this->factory('cobmisc');
+            $x->cobmisc_cohead_id = (int) $q['_canCreate'];
+            $x->whereAdd('NOT cobmisc_posted');
+            $ret['canCreate'] = $x->count();
+            
+            $co = DB_DataObject::factory('cohead');
+            if($co->get((int) $q['_canCreate'])){
+                $ret['cohead'] = $co->toArray();
+            }
+            $roo->jok($ret);
+            
+        }
+        
+        if(isset($q['_with_other_payment'])){
+            $this->joinAddAropen();
+            
+            // make some extra cols
+            $this->selectAdd("
+               '' AS cobmisc_total,
+               0 AS cobmisc_cobapply_aropen_id,
+               0 AS cobmisc_cobapply_id,
+               0 AS cobmisc_checkhead_id,
+               0 AS cobmisc_cashrcpt_id,
+               0 AS cobmisc_cashrcpt_amount,
+               COALESCE(((join_cobmisc_aropen_id.aropen_amount - join_cobmisc_aropen_id.aropen_paid) / join_cobmisc_aropen_id.aropen_curr_rate), 0) AS cobmisc_outstanding
+            ");
+           
+        }
+        
+    
+    }
+    
+    function items()
+    {
+        $i = $this->factory('cobill');
+        $i->cobill_cobmisc_id = $this->cobmisc_id;
+         
+        
+        $ret = array();
+        $i->find();
+        while($i->fetch()) {
+            $ret[$i->cobill_coitem_id] = clone($i);
+        }
+        return $ret;
+        
+    }
+    
+    function beforeInsert($q, $roo)
+    {
+        // allways fill in taxable into tax type.
+        if (empty($this->cobmisc_taxtype_id)) {
+            $this->cobmisc_taxtype_id = $this->sqlValue("gettaxtypeid('Taxable'::text)");
+        }
+        
+        $this->fixMisc();
+        
+        if (!empty($q['_void'])) {
+            if (empty($q['invchead_id'])) {
+                $roo->jerr("Need invchead_id");
+            }
+            $inv = DB_DAtaObject::factory('invchead');
+            $inv->get($q['invchead_id']);
+            $inv->void($roo);
+            
+            $roo->jok('VOIDED');
+        }
+        
+        // this
+        if (empty($q['cobmisc_cohead_id'])) {
+            $roo->jerr("missing order id");
+        }
+        
+        $q['cobmisc_cohead_id'] = (int) $q['cobmisc_cohead_id'];
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->coitem_cohead_id = $q['cobmisc_cohead_id'];
+        if($coitem->find(true)){
+            $coitem->updatePretaxDiscount($roo);
+        }
+        
+        $t = $this->factory('cobmisc');
+        $t->query("SELECT createBillingHeader({$q['cobmisc_cohead_id']}) AS cobmisc_id");
+        $t->fetch();
+        $this->cobmisc_id = $t->cobmisc_id;
+        if ($this->cobmisc_id  < 1) {
+            $roo->jerr("createbill header returned ". $this->cobmisc_id );
+        }
+        if (isset($q['billitems'])) {
+            $this->updateItems(json_decode($q['billitems']));
+        }
+        if (isset($q['cobapply_list'])) {
+            $this->updateCobApply($roo,explode(',',$q['cobapply_list']));
+        }
+        $t = $this->factory('cobmisc');
+        $t->get($this->cobmisc_id);
+        $old = clone ($t);
+        
+        
+        
+        if(!empty($this->cobmisc_misc)){
+          
+            $t->cobmisc_misc = $this->cobmisc_misc;
+        
+        }
+        $posttaxdisc = isseT($q['cobmisc_posttax_discount']) ? $q['cobmisc_posttax_discount'] : 0;
+        $pretaxdisc =isset($q['cobmisc_cohead_id_cohead_pretax_discount']) ? $q['cobmisc_cohead_id_cohead_pretax_discount'] : 0;
+        
+        // make sure notes get added...
+        $t->setFrom(array(
+            'cobmisc_notes' => isseT($q['cobmisc_notes']) ? $q['cobmisc_notes'] : '',
+            'cobmisc_misc_descrip' => isseT($q['cobmisc_misc_descrip']) ? $q['cobmisc_misc_descrip'] : '',
+            // posttax discount does not exist ...
+            //'cobmisc_posttax_discount' => isset($q['cobmisc_posttax_discount']) ? $q['cobmisc_posttax_discount'] : '',
+            'cobmisc_misc' => $posttaxdisc  + $pretaxdisc,
+            'cobmisc_shipdate' => isseT($q['cobmisc_shipdate']) ? $q['cobmisc_shipdate'] : '',
+            'cobmisc_invcdate' => isseT($q['cobmisc_invcdate']) ? $q['cobmisc_invcdate'] : '',
+            'cobmisc_freight' => isseT($q['cobmisc_freight']) ? $q['cobmisc_freight'] : '',
+        ));
+        
+        
+        $t->update($old);
+        $roo->addEvent('ADD', $this);
+        return $roo->jok($t->toArray());
+         
+    }
+    
+    
+    
+    function beforeUpdate($old, $q, $roo)
+    {
+        // handle void first...
+        if (!empty($q['_void'])) {
+            $this->void($roo);
+            $roo->addEvent('VOIDED', $this);
+            $roo->jok('VOIDED');
+        }
+        
+        $this->fixMisc(); 
+        
+        // allways fill in taxable into tax type.
+        if (empty($this->cobmisc_taxtype_id)) {
+            $this->cobmisc_taxtype_id = $this->sqlValue("gettaxtypeid('Taxable'::text)");
+        }
+        
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->coitem_cohead_id = $this->cobmisc_cohead_id;
+        $coitem->limit(1);
+        if($coitem->find(true)){
+            $coitem->updatePretaxDiscount($roo);
+        }
+        
+        
+        if (!empty($q['_post'])) {
+            $this->post($roo);
+            $roo->addEvent('POSTED', $this);
+            $roo->jok('POSTED');
+        }
+        
+       
+        
+    }
+    
+    function beforeDelete($dependants_array, $roo)
+    {
+        
+        $ap = DB_DataObject::Factory('cobapply');
+        $ap->cobapply_cobmisc_id = $this->pid();
+        foreach($ap->fetchAll() as $ap) {
+            $ap->delete();   
+        }
+         
+        
+        
+    }
+    
+    
+    function onUpdate($old, $q, $roo)
+    {
+        if (isset($q['billitems'])) {
+            $this->updateItems(json_decode($q['billitems']));
+        }
+        if (isset($q['cobapply_list'])) {
+            $this->updateCobApply($roo,explode(',',$q['cobapply_list']));
+        }
+        
+    }
+    
+    // fixes misc account 
+     function fixMisc()
+    {
+        if (empty($this->cobmisc_misc) || !empty($this->cobmisc_misc_accnt_id)) {
+            return;
+        }
+        if (empty($this->cobmisc_cohead_id)) {
+            return;
+        }
+        
+        
+        $co = DB_DataObject::factory('cohead');
+        $co->query("
+            select max(findardiscountaccount(cohead_cust_id)) as accnt_id
+                from
+                cohead
+                WHERE
+                 cohead_id = {$this->cobmisc_cohead_id}
+            
+        ");
+        
+        $co->fetch();
+        if (empty($co->accnt_id) or $co->accnt_id < 1) {
+            return;
+        }
+        $sa = DB_DataObject::factory('salesaccnt');
+        $sa->get($co->accnt_id);
+        $this->cobmisc_misc_accnt_id =  $sa->salesaccnt_sales_accnt_id;
+        
+         
+    }
+    
+    
+    function updateCobApply($roo, $list)
+    {
+        
+        $ca = DB_DataObject::Factory('cobapply');
+        $ca->cobapply_cobmisc_id = $this->cobmisc_id;
+        $base = clone($ca);
+        // needs to delete dupes..
+        $old = $ca->fetchAll( 'cobapply_id' , 'cobapply_aropen_id');
+        $seen = array();
+        foreach($old as $apid => $open_id) {
+            if (!in_array($open_id, $seen)) {
+                $seen[] = $open_id;
+                continue;
+                
+            }
+            unset($old[$apid]);
+            $ca = DB_DataObject::Factory('cobapply');
+            $ca->get($apid);
+            $ca->delete();
+            
+        }
+        
+        $old = array_flip($old);
+        
+        foreach($list as $k) {
+            if (empty($k)) {
+                continue;
+            }
+            if (isset($old[$k])) {
+                unset($old[$k]);
+                continue;
+            }
+            $new = clone($base);
+            $new->cobapply_aropen_id = $k;
+            $new->insert();
+            
+        }
+        
+        foreach($old as $k=>$v) {
+            $del = clone($base);
+            $del->get($v);
+            if ($del->cobapply_applied) {
+                $roo->jerr("Credit memo has already been applied");
+            }
+            $del->delete();
+        }
+        
+        
+    }
+    
+    function updateItems($ar)
+    {
+       // ar is 
+        //$o->shipitem_orderitem_id,
+        //$o->shipitem_qty,
+        $old = $this->items();
+        
+        
+        foreach($ar as $new) {
+            if (!isset($old[$new->cobill_coitem_id])) {
+                if (empty($new->cobill_qty )) {
+                    continue; // skip empty lines..
+                }
+                $this->addItem($new->cobill_coitem_id, $new->cobill_qty );
+                continue;
+            }
+            $ol = $old[$new->cobill_coitem_id];
+            
+            if (empty($new->cobill_qty)) {
+                $ol->delete();
+                unset($old[$new->cobill_coitem_id]);
+            }
+            
+            if ($ol->cobill_qty == $new->cobill_qty) {
+                unset($old[$new->cobill_coitem_id]);
+                continue;
+            }
+            $oo = clone($ol);
+            $ol->cobill_qty = $new->cobill_qty;
+            $ol->update($oo);
+            
+            unset($old[$new->cobill_coitem_id]);
+        }
+        // $ar - should contain all the order items.. if it does not...
+        // then we should update the quatities.
+        foreach($old as $id => $ol) {
+            $ol->delete();
+        }
+        
+        
+        
+        
+    }
+    function addItem($oid, $qty)
+    {
+        $bi = $this->factory('cobill');
+        $o = $this->cohead();
+        $oi = $this->factory('coitem');
+        $oi->get($oid);
+        
+        
+        $bi->setFrom(array(
+            'cobill_coitem_id' => $oid,
+           // 'cobill_selectdate' => '',
+            'cobill_qty' => $qty,
+            //'cobill_invcnum' => '',
+            //'cobill_toclose' => false,
+            'cobill_cobmisc_id' => $this->cobmisc_id,
+            //'cobill_select_username' => '',
+            //'cobill_invcitem_id' => '',
+          //  'cobill_taxtype_id' => '',
+            
+        ));
+        
+        $bi->cobill_taxtype_id = $oi->coitem_taxtype_id; //$this->sqlValue("gettaxtypeid('Taxable'::text)");
+        // it's actually a
+        
+        /// issue to shipping can not handle multiple shipments for the same
+        // product!!!
+          
+        $bi->insert();
+    }
+    /***
+     *
+     * There are 2 invoice post methods...
+     * - one here.. and one in invchead
+     *
+     * This is the one used by the Interface!! (and standard migrate code)
+     * 
+     *  
+     *
+     *
+     */
+    function post($roo)
+    {
+        
+        // we can only do this if the order does not have outstanding shipments.
+        $co = $this->cobmisc_cohead_id ? $this->cohead() : false;
+        if($co) {
+            $sh = $this->factory('shiphead');
+            
+            $sh->order($co);
+            $sh->whereAdd('shiphead_shipped = false AND shiphead_shipdate IS NOT NULL');
+            if ($sh->count()) {
+                $roo->jerr( "This order has unconfirmed shipments ".
+                "- delete or confirm the shipments before posting the invoice ");
+             }
+        }   
+        
+        
+        // create an invoice.. and post?
+        $transObj = false;
+        if (empty($roo->transObj)) {
+            
+            $transObj = $this->factory('cobmisc');
+            $transObj->query("BEGIN");
+        }
+        
+        $t = $this->factory('cobmisc');
+        $t->query("SELECT createInvoice({$this->cobmisc_id}) AS result");
+        $t->fetch();
+        $inv_id =  $t->result * 1;
+        if ($inv_id < 1) {
+            $t = $this->factory('cobmisc');
+        
+            $roo->jerr( " create invoice returned $inv_id");
+        }
+            
+        
+        
+        
+        $t = $this->factory('cobmisc');
+        //$t->query("SELECT postInvoice({$inv_id} , fetchJournalNumber('AR-IN') ) AS result");
+        $t->query("SELECT postInvoice({$inv_id} ) AS result");
+        $t->fetch();
+        $ils =  empty($t->result) ? -1  : $t->result;
+        
+        if ($ils < 1) {
+          
+            $roo->jerr("post invoice returned $ils");
+        }
+        /*
+        $x = $this->factory($this->tableName());
+        $x->get($this->pid());
+        $x = $x->invchead();
+        if (!$x->invchead_posted) {
+            $roo->jerr("resulting invoice is not posted? ILS = $ils");
+        }
+        */
+        
+        $t = $this->factory('cobmisc');
+        $t->query("SELECT postItemlocseries({$ils} ) AS result");
+        $t->fetch();
+        $WHAT =  empty($t->result) ? -1 : $t->result;
+        if ($WHAT < 1) {
+             
+            $roo->jerr("post item loc series returned $ils");
+        }
+        
+        
+        // post any credit memo's to it..
+        $t = $this->factory('cobmisc');
+        $t->get($this->pid());
+        
+        $our_ar = $t->invchead()->aropen();
+        
+        //$roo->jerr($our_ar->aropen_amount);
+        
+        $ado = DB_DAtaObject::factory('cobapply');
+        
+        // now find all the 'cm' to apply.. = and update them when done..
+        
+        $applied =  0.0;
+        
+        $ca = DB_DAtaObject::factory('cobapply');
+        $ca->cobapply_cobmisc_id = $this->cobmisc_id;
+        $ar = $ca->fetchAll();
+        $done = array();
+        foreach($ar as $ca) {
+            // dupes ignore..
+            if (in_array($ca->cobapply_aropen_id, $done)) {
+                continue;
+            }
+            $done[] =$ca->cobapply_aropen_id;
+            if ($ca->cobapply_applied) {
+                continue;
+            }
+            $appply_aropen = $ca->aropen();
+            
+            $total_to_apply = $applied + ($appply_aropen ->aropen_amount - $appply_aropen->aropen_paid);
+            //if ($total_to_apply > $our_ar->aropen_amount) {
+            //    $roo->jerr("application is more than invoice");
+            //}
+            
+            // apply it..
+            $q = clone($ado);
+            $q->query("SELECT applyARCreditMemoToBalance({$ca->cobapply_aropen_id}, {$our_ar->pid()}) AS result;");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 0) {
+                
+                
+                $roo->jerr("Problem applying credit memo's go back and edit the invoice and save and try again.
+                           SELECT applyARCreditMemoToBalance({$ca->cobapply_aropen_id}, {$our_ar->pid()}) AS result
+                           RETURNED:" . @$q->result );
+            }
+            $q = clone($ado);
+            $q->query("SELECT postARCreditMemoApplication({$ca->cobapply_aropen_id}) AS result;");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 0) {
+                $roo->jerr("Problem posting credit memo application go back and edit the invoice and save and try again.
+                         SELECT postARCreditMemoApplication({$ca->cobapply_aropen_id}) AS result;  
+                            RETURNED:" . @$q->result );
+            }
+            
+        }
+        
+        
+        
+         if ($transObj) {
+            $transObj->query("COMMIT");
+        }
+                
+       
+        return true;
+        
+        
+        
+    }
+    function void($roo, $ret = false)
+    {
+        // if it's posted, we need to run voidInvoice - this is our little addon from
+        // newer version of xtuple...
+        if ($this->cobmisc_invchead_id) {
+            $inv = $this->invchead();
+            $this->stashInvoice();
+            
+            $inv->void($roo);
+            //$roo->jerr("Changed to draft?");
+            return true; // not really needed...
+        }
+        
+        
+        //$t = $this->factory('cobmisc');
+        //$t->query("BEGIN");
+        $ar = $this->items();
+        foreach($ar as $i) {
+            $i->delete();
+        }
+        // delets cobapply as well.
+        
+        $this->beforeDelete(array(), $roo);
+        $this->delete();
+        
+        //$t->query("COMMIT");
+        if ($ret) {
+            return true;
+        }
+        $roo->addEvent('DELETED', $this);
+        $roo->jok("DELETED");
+         
+           
+        
+        
+    }
+    
+    
+     
+    // dumping old versions..
+    function stashItems()
+    {
+        $i = $this->factory('cobill');
+        $i->cobill_cobmisc_id = $this->pid();
+        $i->selectAdd();
+        $i->selectAdd("
+            (SELECT coitem_itemsite_id FROM coitem where coitem_id =  cobill_coitem_id) AS itemsite_id,
+            cobill_qty
+        ");
+        return $i->fetchAll('itemsite_id','cobill_qty');
+        
+    }
+    
+    
+    function stashInvoice()
+    {
+        
+        $old = $this->stashItems();
+        if (empty($old)) {
+            return; // no point in stashing empty..
+        }
+        // we should stash based on id.. - so old ones can be deleted.
+        // group into 100's.. eg.
+        //  /shipstash/{floor(id/100)00/{id}/... versions..
+        $ff = HTML_FlexyFramework::get();
+        
+        if (empty($ff->Xtuple['storedir'])) {
+            $ff->page->jerr("Xtuple['storedir'] is not configured");
+        }
+        
+        $fd = $ff->Xtuple['storedir'] .
+            '/billstash/' .
+            floor($this->cobmisc_cohead_id /100) .
+            '/' . $this->cobmisc_cohead_id .'/';
+        
+        
+        if (!is_writable( $ff->Xtuple['storedir'])) {
+            $ff->page->jerr("Xtuple['storedir']: " . $ff->Xtuple['storedir'] . " is not writable");
+            return;
+        }
+        
+        if (!file_exists($fd)) {
+            mkdir($fd,0700, true);
+        }
+        
+        $d = time();
+        while (true) {
+            $fn = $fd.  $this->cobmisc_id . '_' . date('Y-m-d h:i:s',$d). '.json';
+            if (file_exists($fn)) {
+                $d++;
+                continue;
+            }
+            break;
+        }
+        
+       
+        
+        file_put_contents($fn, json_encode( $old ));
+        //$ff->page->jok("wrote stash");
+        
+    }
+    function stashList($id, $roo)
+    {
+        $ff = HTML_FlexyFramework::get();
+        
+        $id = (int) $id;
+        
+           
+        
+        if (empty($ff->Xtuple['storedir'])) {
+            $roo>jerr("Xtuple['storedir'] is not configured");
+        }
+        $fd = $ff->Xtuple['storedir'] .
+            '/billstash/' .
+            floor($id /100) .
+            '/' . $id;
+            
+        if (!file_exists($fd)) {
+            $roo->jerr("no data available " . $fd);
+            $roo->jdata(array());
+        }
+        
+        
+        
+        $ret = array();
+        foreach(scandir($fd) as $d) {
+            if (!preg_match('/\.json$/', $d)) {
+                continue;
+            }
+            $n = preg_replace('/\.json$/', '', $d);
+            $n = explode('_', $n);
+            $n = $n[0] . ' voided on ' . $n[1];
+            
+            $ret[] = array(
+                
+                'name' => $n,
+                'data' => json_decode(file_get_contents($fd.'/'. $d))
+            );
+        }
+        return $roo->jdata($ret);
+        
+        
+    }
+    function postListFilter($data, $authUser, $q)
+    {
+        
+        if(empty($q['cobmisc_cohead_id'])) {
+            return $data;
+        }
+        
+        if(isset($q['_with_other_payment'])){
+            $new_data = array();
+            
+            foreach($data as $d){
+                $new_data[] = $d;
+              
+                $cobapply = DB_DataObject::factory('cobapply');
+                $cobapply->cobapply_cobmisc_id = $d['cobmisc_id'];
+                if($cobapply->count()){
+                    foreach($cobapply->fetchAll() as $coba){
+                        $applyValue = true;
+                        $aropen = DB_DataObject::factory('aropen');
+                        $aropen->get($coba->cobapply_aropen_id);
+                        $arapply = DB_DataObject::factory('arapply');
+                        $arapply->arapply_source_aropen_id = $coba->cobapply_aropen_id;
+                        $arapply->arapply_target_docnumber = $d['cobmisc_invcnumber'];
+                        $arapply->find(true);
+                        
+                        $add = array(
+                            'cobmisc_id' => -2,
+                            'cobmisc_cobapply_aropen_id' => $aropen->pid(),
+                            'cobmisc_cobapply_id' => $cobapply->pid(),
+                            'cobmisc_invchead_id_invchead_invcnumber' => $aropen->aropen_docnumber,
+                            'cobmisc_invcdate' => $aropen->aropen_docdate,
+                            'cobmisc_qty' => 1,
+                            'cobmisc_total' => $arapply->arapply_applied * -1,
+                            'cobmisc_outstanding' => ($aropen->aropen_amount - $aropen->aropen_paid) / $aropen->aropen_curr_rate,
+                            'cobmisc_posted' => $d['cobmisc_posted'],
+                        );
+                         
+                        $new_data[] = $add;
+                        
+                        $checkitem = DB_DataObject::factory('checkitem');
+                        $checkitem->autoJoin();
+                        $checkitem->checkitem_aropen_id = $aropen->pid();
+                        $checkitem->whereAdd("
+                            join_checkitem_checkhead_id_checkhead_id.checkhead_posted = TRUE
+                            AND
+                            join_checkitem_checkhead_id_checkhead_id.checkhead_void = FALSE
+                            AND
+                            join_checkitem_checkhead_id_checkhead_id.checkhead_deleted = FALSE
+
+                        ");
+                        
+                        foreach ($checkitem->fetchAll() as $checki){
+                            $add = array(
+                                'cobmisc_id' => -3,
+                                'cobmisc_checkhead_id' => $checki->checkitem_checkhead_id,
+                                'cobmisc_invchead_id_invchead_invcnumber' => $checki->checkitem_checkhead_id_checkhead_number,
+                                'cobmisc_invcdate' => $checki->checkitem_docdate,
+                                'cobmisc_qty' => 1,
+                                'cobmisc_total' => $checki->checkitem_amount / $checki->checkitem_curr_rate * -1,
+                                
+                             );
+                            $new_data[] = $add;
+                        }
+                    }
+                }
+                
+                if(!empty($d['cobmisc_aropen_id_aropen_id'])){
+                    $cashrcptitem = DB_DataObject::factory('cashrcptitem');
+                    $cashrcptitem->cashrcptitem_aropen_id = $d['cobmisc_aropen_id_aropen_id'];
+                    if($cashrcptitem->count()){
+                        
+                        $cashrcpt = DB_DataObject::factory('cashrcpt');
+                        $cashrcpt->whereAddIn('cashrcpt_id', $cashrcptitem->fetchAll('cashrcptitem_cashrcpt_id'), 'int');
+                        $cashrcpt->cashrcpt_posted = TRUE;
+                        $cashrcpt->cashrcpt_void = FALSE;
+                        foreach($cashrcpt->fetchAll() as $cashr){
+                            $add = array(
+                               'cobmisc_id' => -4,
+                               'cobmisc_cashrcpt_id' => $cashr->pid(),
+                               'cobmisc_invchead_id_invchead_invcnumber' => $cashr->cashrcpt_number,
+                               'cobmisc_invcdate' => $cashr->cashrcpt_docdate,
+                               'cobmisc_cashrcpt_amount' => $cashr->cashrcpt_amount / $cashr->cashrcpt_curr_rate * -1,
+                               'cobmisc_qty' => 1,
+                               'cobmisc_total' => $d['cobmisc_aropen_id_aropen_paid'] / $cashr->cashrcpt_curr_rate * -1
+                            );
+                           $new_data[] = $add;
+                        }
+                    }
+                    
+                }
+            }
+            
+            return $new_data;
+        }
+        
+        $co = DB_DataObject::Factory('cohead');
+        $co->get((int)$q['cobmisc_cohead_id']);
+        $invc = DB_DataObject::Factory('invchead');
+        // broken!?!?
+        $invc->whereAdd("
+            invchead_posted = false
+            AND
+            invchead_void =  false
+            AND
+            invchead_ordernumber = '{$this->escape($co->cohead_number)}'
+            AND
+            invchead_id NOT IN (
+                SELECT cobmisc_invchead_id FROM
+                    cobmisc WHERE cobmisc_cohead_id = {$co->pid()}
+            )
+        ");
+        
+        $base = $this->factory('cobmisc')->toArray();
+      
+        foreach($invc->fetchAll() as $invc) {
+            $data[] = ($base + $invc->toArray('cobmisc_invchead_id_%s'));
+        }
+        
+        return $data;
+        
+    }
+    
+    function joinAddCohead()
+    {
+        $co = DB_DataObject::Factory('cohead');
+        $this->_join .= "
+            LEFT JOIN cohead join_cobmisc_cohead_id
+            ON
+            join_cobmisc_cohead_id.cohead_id = cobmisc_cohead_id
+            ";
+        $this->selectAs($co, 'cobmisc_cohead_id_%s', 'join_cobmisc_cohead_id');
+        
+        
+    } 
+    
+    function joinAddAropen()
+    {
+        $aropen = DB_DataObject::factory('aropen');
+        $this->_join .= "
+            LEFT JOIN aropen join_cobmisc_aropen_id
+            ON
+            join_cobmisc_aropen_id.aropen_doctype = 'I'
+            AND
+            join_cobmisc_aropen_id.aropen_docnumber = cobmisc_invcnumber::TEXT
+        ";
+        
+        $this->selectAs($aropen, 'cobmisc_aropen_id_%s', 'join_cobmisc_aropen_id');
+    }
+    
+}
diff --git a/DataObjects/Cobmisctax.php b/DataObjects/Cobmisctax.php
new file mode 100644 (file)
index 0000000..d94cc30
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for cobmisctax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cobmisctax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cobmisctax';          // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cohead.php b/DataObjects/Cohead.php
new file mode 100644 (file)
index 0000000..9bac05d
--- /dev/null
@@ -0,0 +1,1686 @@
+<?php
+/**
+ * Table Definition for cohead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cohead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cohead';              // table name
+    public $cohead_id;                       // int4(4)  not_null default_nextval%28%28cohead_cohead_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cohead_number;                   // text(-1)  unique_key unique_key
+    public $cohead_cust_id;                  // int4(4)  not_null
+    public $cohead_custponumber;             // text(-1)  
+    public $cohead_type;                     // bpchar(-1)  
+    public $cohead_orderdate;                // date(4)  
+    public $cohead_warehous_id;              // int4(4)  
+    public $cohead_shipto_id;                // int4(4)  
+    public $cohead_shiptoname;               // text(-1)  
+    public $cohead_shiptoaddress1;           // text(-1)  
+    public $cohead_shiptoaddress2;           // text(-1)  
+    public $cohead_shiptoaddress3;           // text(-1)  
+    public $cohead_shiptoaddress4;           // text(-1)  
+    public $cohead_shiptoaddress5;           // text(-1)  
+    public $cohead_salesrep_id;              // int4(4)  not_null
+    public $cohead_terms_id;                 // int4(4)  not_null
+    public $cohead_origin;                   // bpchar(-1)  
+    public $cohead_fob;                      // text(-1)  
+    public $cohead_shipvia;                  // text(-1)  
+    public $cohead_shiptocity;               // text(-1)  
+    public $cohead_shiptostate;              // text(-1)  
+    public $cohead_shiptozipcode;            // text(-1)  
+    public $cohead_freight;                  // numeric(-1)  not_null
+    public $cohead_misc;                     // numeric(-1)  not_null default_0
+    public $cohead_imported;                 // bool(1)  default_false
+    public $cohead_ordercomments;            // text(-1)  
+    public $cohead_shipcomments;             // text(-1)  
+    public $cohead_shiptophone;              // text(-1)  
+    public $cohead_shipchrg_id;              // int4(4)  
+    public $cohead_shipform_id;              // int4(4)  not_null
+    public $cohead_billtoname;               // text(-1)  
+    public $cohead_billtoaddress1;           // text(-1)  
+    public $cohead_billtoaddress2;           // text(-1)  
+    public $cohead_billtoaddress3;           // text(-1)  
+    public $cohead_billtocity;               // text(-1)  
+    public $cohead_billtostate;              // text(-1)  
+    public $cohead_billtozipcode;            // text(-1)  
+    public $cohead_misc_accnt_id;            // int4(4)  
+    public $cohead_misc_descrip;             // text(-1)  
+    public $cohead_commission;               // numeric(-1)  
+    public $cohead_miscdate;                 // date(4)  
+    public $cohead_holdtype;                 // bpchar(-1)  
+    public $cohead_packdate;                 // date(4)  
+    public $cohead_prj_id;                   // int4(4)  
+    public $cohead_wasquote;                 // bool(1)  not_null default_false
+    public $cohead_lastupdated;              // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $cohead_shipcomplete;             // bool(1)  not_null default_false
+    public $cohead_created;                  // timestamp(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $cohead_creator;                  // text(-1)  default_%22current_user%22%28%29
+    public $cohead_quote_number;             // text(-1)  
+    public $cohead_billtocountry;            // text(-1)  
+    public $cohead_shiptocountry;            // text(-1)  
+    public $cohead_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $cohead_calcfreight;              // bool(1)  not_null default_false
+    public $cohead_shipto_cntct_id;          // int4(4)  
+    public $cohead_shipto_cntct_honorific;    // text(-1)  
+    public $cohead_shipto_cntct_first_name;    // text(-1)  
+    public $cohead_shipto_cntct_middle;      // text(-1)  
+    public $cohead_shipto_cntct_last_name;    // text(-1)  
+    public $cohead_shipto_cntct_suffix;      // text(-1)  
+    public $cohead_shipto_cntct_phone;       // text(-1)  
+    public $cohead_shipto_cntct_title;       // text(-1)  
+    public $cohead_shipto_cntct_fax;         // text(-1)  
+    public $cohead_shipto_cntct_email;       // text(-1)  
+    public $cohead_billto_cntct_id;          // int4(4)  
+    public $cohead_billto_cntct_honorific;    // text(-1)  
+    public $cohead_billto_cntct_first_name;    // text(-1)  
+    public $cohead_billto_cntct_middle;      // text(-1)  
+    public $cohead_billto_cntct_last_name;    // text(-1)  
+    public $cohead_billto_cntct_suffix;      // text(-1)  
+    public $cohead_billto_cntct_phone;       // text(-1)  
+    public $cohead_billto_cntct_title;       // text(-1)  
+    public $cohead_billto_cntct_fax;         // text(-1)  
+    public $cohead_billto_cntct_email;       // text(-1)  
+    public $cohead_taxzone_id;               // int4(4)  
+    public $cohead_taxtype_id;               // int4(4)  
+    public $cohead_ophead_id;                // int4(4)  
+    public $cohead_status;                   // bpchar(-1)  not_null default_O
+    public $cohead_targetdate;                   // date
+
+    public $cohead_display_salesrep_id;   //int allow null
+    public $cohead_pretax_discount;   // numeric(16,4) NOT NULL DEFAULT 0,
+    public $cohead_posttax_discount;   //numeric(16,4) NOT NULL DEFAULT 0, 
+    
+   /**
+    * Getter / Setter for $cohead_billto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function billto_cntct() {
+        return func_num_args() ? $this->link('cohead_billto_cntct_id', func_get_arg(0)) : $this->link('cohead_billto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_cust_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cust() {
+        return func_num_args() ? $this->link('cohead_cust_id', func_get_arg(0)) : $this->link('cohead_cust_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_misc_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function misc_accnt() {
+        return func_num_args() ? $this->link('cohead_misc_accnt_id', func_get_arg(0)) : $this->link('cohead_misc_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_ophead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ophead() {
+        return func_num_args() ? $this->link('cohead_ophead_id', func_get_arg(0)) : $this->link('cohead_ophead_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('cohead_prj_id', func_get_arg(0)) : $this->link('cohead_prj_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('cohead_salesrep_id', func_get_arg(0)) : $this->link('cohead_salesrep_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_shipform_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipform() {
+        return func_num_args() ? $this->link('cohead_shipform_id', func_get_arg(0)) : $this->link('cohead_shipform_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_shipto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipto_cntct() {
+        return func_num_args() ? $this->link('cohead_shipto_cntct_id', func_get_arg(0)) : $this->link('cohead_shipto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_shipto_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipto() {
+        return func_num_args() ? $this->link('cohead_shipto_id', func_get_arg(0)) : $this->link('cohead_shipto_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('cohead_taxtype_id', func_get_arg(0)) : $this->link('cohead_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('cohead_taxzone_id', func_get_arg(0)) : $this->link('cohead_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_terms_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function terms() {
+        return func_num_args() ? $this->link('cohead_terms_id', func_get_arg(0)) : $this->link('cohead_terms_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('cohead_warehous_id', func_get_arg(0)) : $this->link('cohead_warehous_id');
+    }
+
+   /**
+    * Getter / Setter for $cohead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cohead_curr_id', func_get_arg(0)) : $this->link('cohead_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults()
+    {
+        return  array(
+            'cohead_commission'=>0,
+             
+            'cohead_misc' => 0,
+            'cohead_misc_accnt_id' => $this->sqlValue("NULL"), //FIXME << this must be fixed.
+            'cohead_terms_id' => $this->sqlValue("gettermsid('C.O.D.')"),
+            'cohead_type'=> '', // can be empty, 'O' or  'C' ... still need to know what they mean..
+            'cohead_custponumber'=> '', // is 'otherRefNum' in old stystm, however does not appear to be used.
+            'cohead_origin' => 'C', // customer?
+            'cohead_misc_descrip' => '',
+            'cohead_holdtype' => 'N',
+            'cohead_quote_number' => '',
+            'cohead_status'=>'U', // 'U" == unconfirmed open? c=closed..
+             // look at the api schema - there is a stored procudure to get the default in there.
+            'cohead_shipform_id' => $this->sqlValue("
+                                ( SELECT shipform_id FROM
+                                        shipform WHERE shipform_name
+                                    IN ('STD-PACKING-LIST', 'SO-PackList') LIMIT 1)
+                                "),
+            
+            'cohead_freight' => 0,
+            
+        ); 
+        
+        
+    }
+    /**
+     * fetch all items
+     */
+    function items($what=false)
+    {
+        $i = $this->factory('coitem');
+        $i->coitem_cohead_id = $this->cohead_id;
+        $i->orderBy('coitem_linenumber ASC');
+        return $i->fetchAll($what);
+        
+    }
+    function countItems($what=false)
+    {
+        $i = $this->factory('coitem');
+        $i->coitem_cohead_id = $this->cohead_id;
+        //$i->orderBy('coitem_linenumber ASC');
+        return $i->count();
+        
+    }
+    
+    function shipheads($what=false)
+    {
+        $i = $this->factory('shiphead');
+        if (!$this->cohead_id) {
+            return array();
+        }
+        $i->order($this);
+        
+        return $i->fetchAll($what);
+        
+    }
+    function cobmiscs($what=false)
+    {
+        $i = $this->factory('cobmisc');
+        if (!$this->cohead_id) {
+            return array();
+        } 
+        $i->cohead($this);
+        return $i->fetchAll($what);
+        
+    }
+    function invcheads($what=false)
+    {
+        $i = $this->factory('invchead');
+        if (!$this->cohead_id) {
+            return array();
+        }
+        $i->invchead_ordernumber = $this->cohead_number;
+        
+        return $i->fetchAll($what);
+        
+    }
+    
+    /**
+     * fetch a line
+     */
+    function line($line)
+    {
+        $i = $this->factory('coitem');
+        $i->coitem_cohead_id = $this->cohead_id;
+        return $i->get('coitem_linenumber' , $line) ? $i : false;
+         
+    }
+    
+    
+    
+    function applyFilters($q, $au,$roo)
+    {
+        
+        if(isset($q['_stockLevel'])){
+            $co = clone ($this);
+            if (!$co->get($q['_stockLevel'])) {
+                $roo->jerr('no valid cohead?');
+            }
+            $co->stockLevel($roo);
+            $roo->jerr("oops");
+        }
+        
+        if (isset($q['_fill_shipvoid'])) {
+            $this->shipvoidfill($roo,$q);
+            $roo->jerr("oops");
+        }
+        
+        if (!empty($q['_apply_fifo'])) {
+            $id = (int)$q['_apply_fifo'];
+            $this->query("
+                SELECT invfifo_apply_gl_cohead($id, true)
+           ");
+            $roo->jok("DONE");
+        
+        }
+        if (!empty($q['_run_void_fix'])) {
+            $id = (int)$q['_run_void_fix'];
+            $x = clone ($this);
+            $x->query("
+                UPDATE invfifo SET invfifo_void = 0 where invfifo_cohead_id = {$id}
+            ");
+            
+            
+            $this->query("
+                SELECT invfifo_cohead_void_flag({$id}, coitem_itemsite_id) FROM coitem where coitem_cohead_id = {$id}
+            ");
+        
+            $roo->jok("DONE");
+        
+        }
+        
+        if (!empty($q['_fill_shipto'])) {
+            $co = clone($this);
+            $co->applyFilters(array(), $au, $roo);
+            if (!$co->get($q['_fill_shipto'])) {
+                $roo->jerr('no valid cohead?');
+            }
+            $co->fillshipto($roo,$q);
+            $roo->jerr("oops");
+        }
+        
+        if(!empty($q['_fill_location'])){
+            $co = clone($this);
+            $co->applyFilters(array(), $au, $roo);
+            if (!$co->get($q['_fill_location'])) {
+                $roo->jerr('no valid cohead?');
+            }
+            
+            // check shippment
+            $shipment = DB_DataObject::factory('shiphead');
+            $shipment->whereAdd('shiphead_shipdate IS NOT NULL');
+            if($shipment->get('shiphead_order_id' , $co->pid())){
+                $roo->jerr('Shipments exist!');
+            }
+            
+            // check invoice
+            $invoice = DB_DataObject::factory('cobmisc');
+            if($invoice->get('cobmisc_cohead_id', $co->pid())){
+                $roo->jerr('Invoice exist!');
+            }
+            
+            $co->filllocation($roo,$q);
+            $roo->jerr("oops");
+        }
+        
+        
+        if (isset($q['_print'])) {
+            $this->get( $q['cohead_id']);
+            $this->toPDF($roo);
+        }
+        if (isset($q['_excel'])) {
+            $this->get( $q['cohead_id']);
+            $this->toExcel($roo);
+            
+        } 
+        if (!empty($q['_has_multiple_ship'])) {
+            return $this->applyFiltersShipCheck($q, $roo);
+        }
+        
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['query']['cohead_number'])) {
+            $v = $this->escape($q['query']['cohead_number']);
+            $this->whereAdd("cohead_number ILIKE '$v%'");
+        }
+        
+        $this->selectAdd("gettaxtypeid('Taxable') AS default_taxtype_id");
+        
+        $discount_id = 0;
+        $i = DB_DataObject::Factory('item');
+        if ($i->get('item_number', 'Z-LIST-DISCOUNT')) { 
+            $itemsite = $i->itemsite();
+            $discount_id = $itemsite->pid();
+        }
+        
+        $this->selectAdd("
+            (SELECT
+                    COALESCE(MAX(coitem_linenumber), 0)
+                FROM
+                    coitem
+                WHERE
+                    coitem_cohead_id = cohead_id
+                AND
+                    coitem_itemsite_id != {$discount_id}
+            ) AS cohead_max_linenumber
+                         
+        ");
+        
+        $this->selectAdd("
+            COALESCE( (SELECT taxrate_percent FROM taxrate WHERE taxrate_tax_id IN 
+                (SELECT taxass_tax_id FROM taxass WHERE
+                    taxass_taxzone_id = cohead.cohead_taxzone_id
+                    AND taxrate_effective < NOW() AND taxrate_expires > NOW()
+                )
+            ), 0) as taxzone_rate
+        ");            
+        
+        
+        //-- deliveries..
+        $this->selectAdd("
+            (select array_to_string(array_agg(location_name), ', ') FROM
+                    (select
+                            distinct(location_name) as location_name
+                        from
+                            coitem
+                        LEFT JOIN
+                            location
+                        on
+                            coitem_location_src=location_id
+                        WHERE
+                            coitem_cohead_id = cohead_id ) x
+            ) as cohead_src_locations
+        ");
+        
+        // why was this removed - it's needed for the sales order order details page 
+        $this->selectAdd("
+                         
+              calcsalesordersubtotal(cohead_id::integer) as cohead_subtotal,
+              
+              calcsalesordertax(cohead_id::integer) as cohead_tax,
+      
+              calcsalesorderamt(cohead_id::integer) as cohead_total,
+               calcsalesordersubtotal(cohead_id::integer)
+                    - calcsalesordershipped(cohead_id::integer)
+                    - calcsalesorderunshipable(cohead_id::integer) as cohead_unshipped,
+               calcsalesordersubtotal(cohead_id::integer) - calcsalesorderinvoiced(cohead_id::integer)                 as cohead_uninvoiced
+              
+        ");
+        
+        
+           //DB_DataObject::debugLevel(1);
+        $this->joinAddBillAddr();
+        $this->joinAddShipAddr();
+        
+        $this->selectAdd("
+            (SELECT
+                COALESCE(shipto_id,0)
+                    FROM
+                        shiptoinfo
+                    LEFT JOIN
+                        addr
+                    ON shipto_addr_id = addr_id
+                    WHERE
+                        shipto_cntct_id = cohead_shipto_cntct_id
+                        AND 
+                        shipto_addr_id = addr_id
+                LIMIT 1
+            ) as shipto_id
+            
+        ");
+        
+        
+        if (isset($q['viewtype'])) {
+            $vt = $q['viewtype'];
+            if (substr($vt,0,2) == 'MY') {
+                $vt = substr($vt,2);
+                $this->whereAdd('cohead_salesrep_id = ' . $au->salesrep()->pid());
+            }
+            
+            switch ($vt) {
+                
+                case 'OPEN':
+                    $this->whereAddIn('cohead_status', array( 'O', 'U'), 'string');
+                    break;
+                case 'CLOSED':    
+                    $this->cohead_status = 'C';
+                    break;
+                
+                case 'VOID':    
+                    $this->cohead_status = 'X'; //????
+                    break;
+                
+                case 'ALL':
+                    $this->whereAdd("cohead_status != 'X'");
+                    break;
+                
+                case 'DRAFTSHIP':
+                    $this->whereAdd("(
+                        SELECT
+                            count(shipitem_id)
+                        FROM
+                            shipitem
+                        LEFT JOIN
+                            shiphead
+                        ON
+                            shipitem_shiphead_id = shiphead_id
+                        WHERE
+                                shiphead_order_id = cohead_id
+                            AND
+                                shiphead_shipped = false
+                        ) > 0
+                    ");
+                    break;
+                case 'SHIPPOSTBUG':
+                    // gltrans with unposted.
+                    $gl = DB_DataObject::factory('gltrans');
+                    
+                    $gl->selectAdd();
+                    $gl->selectAdd("distinct(split_part(gltrans_docnumber,'-', 1)) as num");
+                    $gl->whereAdd('NOT gltrans_posted');
+                    $nums = $gl->fetchAll('num');
+                    
+                    $this->whereAddIn('cohead_number', $nums,'string');
+                    
+                
+                    break;
+                
+                case 'INCOMPLETE':
+                    $this->whereAdd("
+                            calcsalesorderqty(cohead_id::integer) = 0
+                            OR
+                            calcsalesordersubtotal(cohead_id::integer)  - calcsalesordershipped(cohead_id::integer)     - calcsalesorderunshipable(cohead_id::integer) != 0
+                            OR
+                            calcsalesorderqty(cohead_id::integer) - calcsalesordershippedqty(cohead_id::integer) - calcsalesorderunshipableqty(cohead_id::integer)  !=0
+                            OR 
+                            calcsalesorderqty(cohead_id::integer) - calcsalesorderinvoicedqty(cohead_id::integer) !=0
+                            OR
+                            calcsalesordersubtotal(cohead_id::integer)  - calcsalesorderinvoiced(cohead_id::integer)   !=0
+                 
+                 
+              
+                 
+                 
+                    ");
+                    break;
+                
+                
+                
+                case 'SHIPQTYBUG':
+                    
+                    // this will take quite a while!?
+                    if (empty($q['cohead_orderdate'])) {
+                        $roo->jerr("pick a month");
+                    }
+                    //unset($this->cohead_orderdate);
+                    
+                    //$this->whereAdd();
+                    
+                    $f = date('Y-m-01', strtotime($q['cohead_orderdate']));
+                    
+                    $roo->sessionState(0);
+                    $this->whereAdd("
+                        cohead_id IN (SELECT cohead_id FROM 
+                                (SELECT cohead_id FROM cohead where cohead_orderdate > '$f' AND cohead_orderdate  < '$f'::date + INTERVAL '1 MONTH') x
+                                WHERE
+                                x_dragon_cohead_test_shipping_qty(cohead_id) != 0
+                               
+                        )
+                            
+                    ");
+                    return false; // prevent default filtering?
+                    break;
+                
+                case 'FIFOBUG':
+                    $this->cohead_fifo_has_error = 1;
+                    break;
+                
+                
+                case 'REALALL':
+                    // everything
+                    break;
+                default:
+                    $roo->jerr("INVALID view");
+                    
+            }
+            
+        }
+        
+        if(!empty($q['_fromdate'])){
+            $this->whereAdd("cohead_orderdate >= '{$q['_fromdate']}'");
+        }
+        
+        if(!empty($q['_todate'])){
+            $this->whereAdd("cohead_orderdate <= '{$q['_todate']}'");
+        }
+        
+        if(!empty($q['_count_order'])){
+            $this->selectAdd();
+            $this->selectAdd('count(cohead_id) AS order_totals');
+        }
+     
+    }
+    
+    function joinAddBillAddr()
+    {
+        $this->_join .= '
+            LEFT JOIN addr AS billaddr ON ( join_cohead_billto_cntct_id_cntct_id.cntct_addr_id = billaddr.addr_id)
+        ';
+        $this->selectAs(DB_DataObject::Factory('addr'), 'cohead_billto_cntct_id_cntct_addr_id_%s', 'billaddr');
+        
+        
+    }
+     function joinAddShipAddr()
+    {
+        $this->_join .= '
+             LEFT JOIN addr AS shipaddr ON ( join_cohead_shipto_cntct_id_cntct_id.cntct_addr_id = shipaddr.addr_id)
+        ';
+        $this->selectAs(DB_DataObject::Factory('addr'), 'cohead_shipto_cntct_id_cntct_addr_id_%s', 'shipaddr');
+        
+        
+    }
+    
+    
+    
+    
+    function applyFiltersShipCheck($q, $roo)
+    {
+        //DB_DataObject::DebugLevel(1);
+        $ch = DB_Dataobject::factory('cohead');
+        if (empty($q['cohead_id']) || !$ch->get($q['cohead_id'])) {
+            $roo->jerr("Invalid order id");
+        }
+        $ci = DB_DataObject::Factory('coitem');
+        $ci->coitem_cohead_id = $ch->pid();
+        $ci->selectAdd();
+        $ci->selectAdd("
+            distinct(coitem_location_src) as coitem_location_src,
+            coitem_shipto_id,
+            (SELECT location_name from location where location_id = coitem_location_src) as coitem_location_src_name,
+            (SELECT shipto_name from shiptoinfo where shipto_id = coitem_shipto_id) as coitem_shipto_id_name
+            
+                       ");
+        $ci->groupBy('coitem_location_src, coitem_shipto_id');
+        // exclude kits
+        //DB_DataObject::DebugLevel(1);
+        $ci->whereAdd("
+            'P' = (SELECT item_type FROM item WHERE item_id = (
+                        SELECT itemsite_item_id FROM
+                            itemsite WHERE itemsite_id = coitem_itemsite_id))
+                      ");
+        
+        $ar = $ci->fetchAll(false,false, 'toArray');
+        if (empty($ar)) {
+            $roo->jerr("No order lines found");
+        }
+        foreach($ar as $r) {
+            if (empty($r['coitem_location_src']) || empty($r['coitem_shipto_id'])) {
+                //$ci = DB_DataObject::Factory('coitem');
+                //$ci->get($r['coitem_id']);
+                
+                
+                $roo->jerr("a line  is missing source location or ship to location\n"  );
+            }
+        }
+        $roo->jdata($ar);
+        
+         
+    }
+    
+    function toRooArray($req)
+    {
+        
+        $ret = $this->toArray();
+        // seaching for order id's does not include id..
+        if (!$this->cohead_id) {
+            return $ret;
+        }
+        
+        $l = $this->factory('cohead');
+        $l->selectAdd();
+        $l->selectAdd("
+                         
+            calcsalesordersubtotal(cohead_id::integer) - calcsalesorderlistdiscount(cohead_id::integer) as cohead_subtotal,
+            calcsalesorderlistdiscount(cohead_id::integer) as   cohead_list_discount,
+            calcsalesordertax(cohead_id::integer) as cohead_tax,
+      
+            calcsalesorderamt(cohead_id::integer) as cohead_total,
+            calcsalesordersubtotal(cohead_id::integer)  - calcsalesordershipped(cohead_id::integer)     - calcsalesorderunshipable(cohead_id::integer)    as cohead_unshipped,
+            calcsalesordersubtotal(cohead_id::integer)  - calcsalesorderinvoiced(cohead_id::integer)            as cohead_uninvoiced,
+            
+             calcsalesorderqty(cohead_id::integer) as cohead_qtyordered,
+            calcsalesorderqty(cohead_id::integer) - calcsalesordershippedqty(cohead_id::integer)
+                    - calcsalesorderunshipableqty(cohead_id::integer)  as cohead_qtyunshipped,
+            calcsalesorderqty(cohead_id::integer) - calcsalesorderinvoicedqty(cohead_id::integer) as cohead_qtyuninvoiced 
+            
+              
+        ");
+        
+        
+        //print_R($this);
+        $l->get($this->pid());
+        $x = $l->toArray('%s', true);
+        $ret = $ret + $x;
+        return $ret; 
+        
+        
+        
+        
+    }
+    
+    function toRooSingleArray($req)
+    {
+        $ret = $this->toArray();
+        $ret['shipto_id'] = $this->cohead_shipto_id ? $this->cohead_shipto_id : 0;
+        if (empty($this->cohead_shipto_id)) {
+            
+            $ship = $this->shipto_cntct();
+        
+            $addr = $ship->addr();
+            
+            $cust = $this->cust();
+                
+                // see if we have a matching shipto..
+            $sh = DB_DataObject::Factory('shiptoinfo');
+            $sh->shipto_cntct_id = $ship->cntct_id;
+            $sh->shipto_addr_id = $addr->addr_id;
+            if ($sh->find(true)) {
+                $ret['shipto_id'] = $sh->pid();
+            }
+        }
+        return $ret;
+        
+        
+    }
+    
+    
+    function nextNumber()
+    {
+        //DB_DataObject::debugLevel(1);
+        $curr = $this->curr()->curr_abbr;
+        
+        $cp = DB_DataObject::factory('cohead');
+        switch ($curr) {
+            case 'USD':
+                $pr = 'US';
+                $cp->whereAdd(" cohead_number   similar to 'US[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            case 'HKD':
+                $pr = 'HK';
+                $cp->whereAdd(" cohead_number   similar  to 'HK[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            case 'SGD':
+                $pr = 'SG';
+                $cp->whereAdd(" cohead_number   similar  to 'SG[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            case 'RMB':
+                $pr = 'CN';
+                $cp->whereAdd(" cohead_number   similar  to 'CN[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            case 'MYR':
+                $pr = 'MY';
+                $cp->whereAdd(" cohead_number   similar  to 'MY[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            case 'AUD':
+                $pr = 'AU';
+                $cp->whereAdd(" cohead_number   similar  to 'AU[0-9][0-9][0-9][0-9][0-9]'");
+                break;
+            
+            default:
+               $pr = 'OT';
+               $cp->whereAdd(" cohead_number  similar to 'OT[0-9][0-9][0-9][0-9][0-9]'");
+               break;
+        }
+        
+        
+        $cp->orderBy('cohead_number DESC');
+        $cp->limit(1);
+        $res = $cp->fetchAll('cohead_number');
+        if (empty($res)) {
+            $np = '9999';
+        } else {
+            $last = $res[0];
+            $np = substr($last,strlen($pr)) *1;
+        }
+        return $pr . sprintf('%04d', ($np+1));
+         
+        
+        
+    }
+    
+    
+    function updateAddress($roo=false)
+    {
+        // copy ship and bill address details into body..
+        //$roo->jerr(print_R($this->toArray()));
+        $ship = $this->shipto_cntct();
+       
+        
+        if ($ship->cntct_id) {
+            // set's id...
+            $this->setFrom($ship->toArray('cohead_shipto_%s'));
+            
+            $addr = $ship->addr();
+            //if (!$addr->addr_id) { // fill in empty...
+             //    $addr->setFrom($addr->toArray('%s'));
+            // }
+            //if ($addr->addr_id) {
+                $this->setFrom(array(
+                   'cohead_shiptoname' => $ship->cntct_name,
+                   'cohead_shiptoaddress1' => $addr->addr_line1,
+                   'cohead_shiptoaddress2' => $addr->addr_line2,
+                   'cohead_shiptoaddress3' => $addr->addr_line3,
+                   'cohead_shiptocity' => $addr->addr_city,
+                   'cohead_shiptostate' =>  $addr->addr_state,
+                   'cohead_shiptozipcode' =>  $addr->addr_postalcode,
+                   'cohead_shiptocountry'  =>  $addr->addr_country,
+                   'cohead_shiptophone' => $ship->cntct_phone,
+               ));
+            //}
+            
+            // it also needs to fix shipto..
+            $shipto = $this->shipto();
+            
+            
+            
+            if (!$shipto->shipto_id
+                    ||
+                    $shipto->shipto_cntct_id != $ship->cntct_id
+                    ||
+                    $shipto->shipto_addr_id != $addr->addr_id
+                    ) {
+                
+                //$roo->Jerr("update shipto");
+                // update or replace..
+                //DB_DataObject::debugLevel(1);
+                $cust = $this->cust();
+                
+                // see if we have a matching shipto..
+                $sh = DB_DataObject::Factory('shiptoinfo');
+                $sh->shipto_cntct_id = $ship->cntct_id;
+                $sh->shipto_addr_id = $addr->addr_id;
+                if ($sh->find(true)) {
+                    //$roo->Jerr("setting to " .$sh->pid() . ' cust='. $this->cust()->pid() );
+                    $this->cohead_shipto_id = $sh->pid();
+                   // DB_DataObject::DebugLevel(1);
+                } else {
+                    //$sh->setFrom($sh->defaults());
+                    $sh->setFrom(array(
+                        'shipto_cust_id' => $this->cohead_cust_id,
+                        'shipto_name' => $ship->cntct_name . ' ' . $addr->addr_line1,
+                        
+                        'shipto_salesrep_id'=> $this->cohead_salesrep_id,
+                        'shipto_active' => true,
+                        'shipto_adefault' => false,
+                        'shipto_shipchrg_id' => $cust->cust_shipchrg_id,
+                        'shipto_taxzone_id' => $cust->cust_taxzone_id,
+                        'shipto_shipform_id' => $cust->cust_shipform_id,
+                        'shipto_commission' => 0,
+                        'shipto_shipzone_id' => $sh->defaultShipZone(),
+                        
+                    ));
+                    
+                    
+                    
+                    $sh->genNum();
+                    //die("not yet");
+                    $this->cohead_shipto_id = $sh->insert();
+                }
+                
+            }
+            
+            
+        }  
+        
+        $bill = $this->billto_cntct();
+        //print_r($bill);exit;
+        
+        if ($bill->cntct_id) {
+            
+            $this->setFrom($bill->toArray('cohead_billto_%s'));
+            $this->cohead_billto_cntct_id = $bill->cntct_id;
+            
+            $addr = $bill->addr();
+            //if (!$addr->addr_id) { // fill in empty...
+            //    $addr->setFrom($addr->toArray('%s'));
+            //}
+            //var_dump($addr);
+                $this->setFrom(array(
+                   'cohead_billtoname' =>       $bill->cntct_name,
+                   'cohead_billtoaddress1' =>    $addr->addr_line1,
+                   'cohead_billtoaddress2' =>   $addr->addr_line2,
+                   'cohead_billtoaddress3' =>    $addr->addr_line3,
+                   'cohead_billtocity' =>       $addr->addr_city,
+                   'cohead_billtostate' =>      $addr->addr_state,
+                   'cohead_billtozipcode' =>     $addr->addr_postalcode,
+                   'cohead_billtocountry'  =>    $addr->addr_country,
+                   
+               ));
+            //}
+            
+            //print_R($this);exit;
+        }
+        //$roo->jerr(print_R($this->toArray()));
+    
+    }
+    
+    function fixMisc()
+    {
+        //if (empty($this->cohead_misc) || !empty($this->cohead_misc_accnt_id)) {
+        //    return;
+        //}
+        if (empty($this->cohead_id)) {
+            return;
+        }
+        $co = DB_DataObject::factory('cohead');
+        $co->query("
+              select max(findardiscountaccount(cohead_cust_id)) as accnt_id
+                from
+                cohead
+                WHERE
+                 cohead_id = {$this->cohead_id}
+         
+            
+        ");
+        $co->fetch();
+        if (empty($co->accnt_id) or $co->accnt_id < 1) {
+            $this->jerr("Can not find discount account");
+            return;
+        }
+        $this->cohead_misc_accnt_id =  $co->accnt_id;
+        //$sa = DB_DataObject::factory('salesaccnt');
+       // $sa->get($co->accnt_id);
+        //$this->cohead_misc_accnt_id =  $sa->salesaccnt_sales_accnt_id;
+        
+         
+    }
+    
+    function updateDiscount($roo)
+    {
+        $item = DB_DataObject::factory('item');
+        if (!$item->get('item_number','Z-LIST-DISCOUNT')) {
+            return;
+        }
+        
+        // this feature is not enabled in HK.
+        $db = substr($this->database(),-2);
+        if ($db == 'hk') {
+            return;
+        }
+        
+        $is = $item->itemsite();
+        
+        $co = DB_DataObject::factory('coitem');
+        $co->coitem_cohead_id = $this->pid();
+        
+        $co->selectAdd();
+        
+        $co->coitem_itemsite_id != $is->pid();
+        
+        $co->selectAdd('SUM(
+                       ROUND( coitem_custprice * coitem_qtyord, 2)
+                       -
+                       ROUND (coitem_price * coitem_qtyord,2)
+                    ) as pretax_discount ');
+        
+        $co->whereAdd('coitem_custprice > coitem_price');
+        
+        $pretax_discount = 0;
+        
+        if ($co->find(true)) {
+            $pretax_discount = $co->pretax_discount;
+        }
+        
+        $this->cohead_pretax_discount = empty($pretax_discount) ? 0 : $pretax_discount * -1;
+        $this->cohead_misc = $this->cohead_posttax_discount + empty($pretax_discount) ? 0 : $pretax_discount * -1;
+    }
+    
+    
+    function beforeInsert($req,$roo)
+    {
+        
+        if (isset($req['_copy_cohead_id'])) {
+            return $this->copyOrder($roo, $req['_copy_cohead_id'], $req['scheddate']);
+        }
+        
+        foreach($this->defaults() as $k=>$v) {
+            if (!isset($this->$k)) {
+                $this->$k = $v;
+            }
+        }
+        // handle automatic numbering..
+        if (empty($this->cohead_number) || $this->cohead_number == 'Automatic') {
+            $this->cohead_number = $this->nextNumber();
+        }
+        if (!empty($req['_shipto_same']) && !empty($this->cohead_billto_cntct_id)) {
+            $this->cohead_shipto_cntct_id = $this->cohead_billto_cntct_id;
+        }
+        
+        // this probably needs doing after Update...????
+      
+        if (empty($this->cohead_shipto_id)) {
+            unset($this->cohead_shipto_id);// = $this->sqlValue('NULL');
+        }
+        
+        if (isset($this->cohead_display_salesrep_id) && empty($this->cohead_display_salesrep_id)) {
+            $this->cohead_display_salesrep_id = $this->sqlValue('NULL');
+         // address is filled in by triggers..  
+        }
+       // $this->updateAddress();
+    }
+    
+    
+    function onInsert($req, $roo)
+    {
+        $old = clone($this);
+        $this->updateAddress($roo);
+        $this->fixMisc();
+        $this->update($old);
+
+    }
+    
+    
+    function beforeUpdate($old,$req,$roo)
+    {
+        //throw new Exception('oops');
+        //print_R($this->toArray());exit;
+        
+        
+        if (!empty($req['_close'])) {
+            if ($this->close()) {
+                $roo->jok('CLOSED');
+            }
+            $roo->jerr("Order can not be closed - invoiced or shipped quantities do no match");
+            
+        }
+        if (!empty($req['_reopen'])) {
+            if ($this->reopen()) {
+                $roo->jok('REOPENED');
+            }
+            $roo->jerr("Order can not be reopened - accounting period is closed."); // will not happen at present
+            
+        }
+        
+         if (!empty($req['_void'])) {
+            if ($this->void()) {
+                $roo->jok('VOID');
+            }
+            $roo->jerr("Order can not be void - it has some invoiced or shipped products, void them first.");
+            
+        }
+        if (!empty($req['_unvoid']))
+        {
+            if ($old->cohead_status != 'X') {
+                $roo->jerr("Order is already open");
+            }
+            
+            if ($old->reopen()) {
+                $roo->jok('UNVOID');
+            }
+            $roo->jerr("Order can not be reopened - accounting period is closed."); // will not happen at present
+            
+        }
+        // fix when I broke the UI...
+        if (empty($old->cohead_number) && empty($req['cohead_number'])) {
+            $this->cohead_number = $this->nextNumber();
+        }
+        
+        
+        if (!empty($req['_shipto_same']) && !empty($this->cohead_billto_cntct_id)) {
+            $this->cohead_shipto_cntct_id = $this->cohead_billto_cntct_id;
+        }
+        //print_R($this->toArray());exit;
+        if (isset($this->cohead_display_salesrep_id) && empty($this->cohead_display_salesrep_id)) {
+            $this->cohead_display_salesrep_id = $this->sqlValue('NULL');
+         // address is filled in by triggers..  
+        }
+        
+                //DB_DataObject::debugLevel(1);
+        $this->updateAddress($roo);
+        $this->updateDiscount($roo);
+        $this->fixMisc();
+        
+        
+    }
+    
+    function relatedWhere()
+    {
+        return  array(
+            'coitem' => $this->items('coitem_id'),
+            'cobmisc' => $this->cobmiscs('cobmisc_id'),
+            'shiphead' => $this->shipheads('shiphead_id'),
+            'invchead' => $this->invcheads('invchead_id'),
+        );
+        
+    }
+    
+    
+    
+    function copyOrder($roo, $id, $date)
+    {
+        $date = date('Y-m-d', strtotime($date));
+        $id = (int)$id;
+        if (empty($id)) {
+            $roo->jerr("no order specified");
+        }
+        
+        $orig  = clone($this);
+        $orig->get($id);
+        
+        $x = clone($this);
+        $x->query("SELECT copySO($id, '$date') as result");
+        $x->fetch();
+        if (empty($x->result)) {
+            $roo->jerr("copy sales order returned {$x->result}");
+        }
+        // update the tx number..
+        
+        
+        
+        
+        $nid = $x->result;
+        
+        $x = clone($this);
+        $x->query("ALTER TABLE cohead DISABLE TRIGGER USER");
+        
+        $x = clone($this);
+        $x->get($nid);
+        $xx = clone($x);
+        $num = $x->nextNumber();
+        // copy our odd stuff..
+        $x->setFrom(array(
+            'cohead_number' => $num,
+            'cohead_targetdate' => $date,
+            'cohead_location_src' => $orig->cohead_location_src,
+            'cohead_shipto_cntct_id' => $orig->cohead_shipto_cntct_id,
+            'cohead_billto_cntct_id' => $orig->cohead_billto_cntct_id,
+            'cohead_salesrep_id' => $roo->authUser->salesrep()->pid(),
+            'cohead_display_salesrep_id' => $orig->cohead_display_salesrep_id,
+        ));
+        
+         
+        $x->update($xx);
+        
+        $x = clone($this);
+        $x->query("
+            UPDATE coitem set
+                coitem_location_src = (SELECT
+                            cf.coitem_location_src
+                        FROM coitem cf
+                        WHERE
+                                cf.coitem_linenumber = coitem_linenumber
+                            AND
+                                cf.coitem_subnumber = coitem_subnumber
+                            AND
+                                cf.coitem_cohead_id = $id
+                        LIMIT 1
+                    ),
+                    
+                coitem_shipto_id =(SELECT
+                            cf.coitem_shipto_id
+                        FROM coitem cf
+                        WHERE
+                                cf.coitem_linenumber = coitem_linenumber
+                            AND
+                                cf.coitem_subnumber = coitem_subnumber
+                            AND
+                                cf.coitem_cohead_id = $id
+                        LIMIT 1
+                    )
+            WHERE
+                coitem_cohead_id = $nid
+            
+        ");
+        
+        // fill in all the coitem_location_src and coitem_shipto_id
+           
+        
+        
+        
+        
+        $xx = clone($this);
+        $xx->query("ALTER TABLE cohead ENABLE TRIGGER USER");
+        $x = clone($this);
+        $x->get($nid);
+        
+        $roo->jok($x->toRooArray(array()));
+        exit;
+        
+        
+        
+    }
+    
+    
+    function void()
+    {
+        
+        $t = $this->factory('cohead');
+        $t->selectAdd();
+        $t->selectAdd('cohead_id,
+           
+                calcsalesordershipped(cohead_id::integer)                 as cohead_shipped,
+                calcsalesorderinvoiced(cohead_id::integer)                 as cohead_invoiced,
+                COALESCE((SELECT SUM(shipitem_qty) FROM shipitem
+                    WHERE
+                        shipitem_orderitem_id IN (SELECT coitem_id FROM coitem where coitem_cohead_id = cohead_id)
+                        
+                ),0) as shipitem_shipped,
+                     
+                COALESCE((
+                        SELECT SUM(cobill_qty) FROM cobill
+                    WHERE
+                        cobill_coitem_id IN (SELECT coitem_id FROM coitem where coitem_cohead_id = cohead_id)
+                        
+                ), 0) as cobill_billed,
+                
+                 COALESCE((SELECT SUM(ABS(coitem_qtyreserved)) FROM coitem WHERE coitem_cohead_id  = cohead_id
+                        
+                ), 0) as coitem_reserved
+                
+        ');
+        $t->get($this->cohead_id);
+         
+        if ( (((int) $t->shipitem_shipped) != 0 ) || (((int) $t->cohead_invoiced) != 0 ) ) {
+            return false;
+        }
+        if ( (((int) $t->cohead_shipped) != 0 ) || (((int) $t->cobill_billed) != 0 ) ) {
+            return false;
+        }
+        //var_dump($t->coitem_reserved);
+        //$roo->jerr("reserved? " . $t->coitem_reserved);
+        //if ( (((int) $t->coitem_reserved) != 0 )  ) {
+        //    return false;
+       // }
+        
+        // do a qty check..
+        // void everything..
+        
+        $t = $this->factory('cohead');
+        $t->query("UPDATE coitem SET coitem_status = 'X' WHERE coitem_cohead_id = {$this->cohead_id}");
+        $t = $this->factory('cohead');
+        $t->query("UPDATE cohead SET cohead_status = 'X' WHERE cohead_id = {$this->cohead_id}");
+        return true;
+        
+                
+        
+        
+        /// 
+        
+        
+    }
+    
+    
+    function reopen()
+    {
+        // no checks..
+        
+        // we should check accounting period...
+        
+        $t = $this->factory('cohead');
+        $t->query("UPDATE coitem SET coitem_status = 'O' WHERE coitem_cohead_id = {$this->cohead_id}");
+        $t = $this->factory('cohead');
+        $t->query("UPDATE cohead SET cohead_status = 'O' WHERE cohead_id = {$this->cohead_id}");
+        
+        return true;
+        
+        
+        
+    }
+    
+    
+    function close()
+    {
+        // can it be closed??
+        
+        $t = $this->factory('cohead');
+        $t->selectAdd();
+        $t->selectAdd('cohead_id,
+                
+            calcsalesordersubtotal(cohead_id::integer) as cohead_subtotal,
+            
+            calcsalesordersubtotal(cohead_id::integer)  - calcsalesordershipped(cohead_id::integer)
+                    - calcsalesorderunshipable(cohead_id::integer)    as cohead_unshipped,
+                    
+            calcsalesordersubtotal(cohead_id::integer)  - calcsalesorderinvoiced(cohead_id::integer)
+                    as cohead_uninvoiced,
+            
+            calcsalesorderqty(cohead_id::integer) as cohead_qtyordered,
+            calcsalesorderqty(cohead_id::integer) - calcsalesordershippedqty(cohead_id::integer)
+                    - calcsalesorderunshipableqty(cohead_id::integer)  as cohead_qtyunshipped,
+            calcsalesorderqty(cohead_id::integer) - calcsalesorderinvoicedqty(cohead_id::integer) as cohead_qtyuninvoiced 
+            
+            
+            
+            
+        ');
+        $t->get($this->cohead_id);
+        if ( ((int) $t->cohead_qtyordered) == 0 )  {
+            return false;
+        }
+        if ( (((int) $t->cohead_unshipped) != 0 ) && (((int) $t->cohead_uninvoiced) != 0 ) ) {
+            return false;
+        }
+        
+        $t = $this->factory('cohead');
+        $t->query("UPDATE coitem SET coitem_status = 'C' WHERE coitem_cohead_id = {$this->cohead_id}");
+        $t = $this->factory('cohead');
+        $t->query("UPDATE cohead SET cohead_status = 'C' WHERE cohead_id = {$this->cohead_id}");
+        return true;
+        
+        
+    }
+    
+    
+    function toPDF($roo)
+    {
+        $db = str_replace('.php', '', array_pop(explode('/',$roo->baseURL)));
+        $template = 'SalesOrderAcknowledgement';
+        if($db == 'au'){
+            $template = 'SalesOrderAcknowledgement-au';
+        }
+        require_once 'Pman/Xtuple/Print.php';
+        $x = new Pman_Xtuple_Print();
+        $x->toPdf(array(
+             'param' => "sohead_id:integer='{$this->cohead_id}'",
+             //'loadfromdb' => 'SalesOrderAcknowledgement',
+             'template' => $template, //'Invoice-' . $db,
+            
+        ), 'SalesOrder-' . $this->cohead_number);
+        
+        exit;
+    }
+    function toExcel($roo)
+    {
+        
+        $ci = DB_DataObject::factory('coitem');
+        $ci->autoJoin();
+        $ci->coitem_cohead_id  = $this->pid();
+        $ci->orderBy('coitem_linenumber ASC, coitem_subnumber ASC');
+        $ci->applyFilters(array(  ), $roo->authUser, $roo);
+        $data  = $ci->fetchAll();
+        //echo '<PRE>';print_r($data);
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+       $x = new Pman_Core_SimpleExcel(
+            $data,
+                                      
+            array(
+           'formats' => array(
+                //'name': array('Align'=>'left'),
+            ),
+            'workbook' => 'Sales Order' . $this->cohead_number, 
+            'head'  => array(
+                array("","","","", "Sales Order"),
+                array("","", "","","S/O#", $this->cohead_number),
+                array("","", "","","Customer P/O#", $this->cohead_custponumber),
+                array("Attention:","", "","","S/O Date#", $this->cohead_orderdate),
+                array($this->cust()->cust_name,"","","", "Scheduled Date#", $this->cohead_targetdate),
+                array($this->billto_cntct()->cntct_name,"","","", "Terms", $this->terms()->terms_descrip),
+                array(),
+                array(),
+                array(),
+            ),
+            
+            
+            'cols' =>  array(
+                array( 
+                    'dataIndex' => 'coitem_linenumber',
+                    'header'  => 'Item#',
+                    'width'  => 75,
+                    'txtrenderer' => function( $v, $worksheet, $row, $col, $o) {
+                         if ($o->coitem_subnumber * 1 > 0) {
+                            return "{$v}.{$o->coitem_subnumber}";
+                        }
+                        return $v; 
+                    }
+                ),
+                array(
+                    'header' => 'Item Code',
+                    'width' => 75,
+                    'dataIndex' => 'item_number',
+                    
+                ),
+                array(
+                 'dataIndex' => 'coitem_location_src_location_name',
+                                'header' => 'From',
+                                'width' => 75,
+                ),
+                array(
+                 'dataIndex' => 'coitem_shipto_id_shipto_name',
+                                'header' => 'To',
+                                'width' => 75,
+                                
+                ),array(
+                 'header' => 'Item Description',
+                                'width' => '150.00',
+                                'dataIndex' => 'item_descrip1',
+                               
+                ),array(
+                    'dataIndex' => 'coitem_qtyord',
+                    'header' => 'Qty',
+                    'width' => 50,
+                    //format => 'align-right'
+                ),
+                array(
+                    'dataIndex' => 'coitem_custprice',
+                    'header' => 'List Price',
+                    'width' => 80,
+                ),
+                array(
+                    'dataIndex' => 'coitem_price',
+                    'header' => 'Sale Price',
+                    'width' => 80,
+                ),
+                array(
+                    'dataIndex' => 'calc_subtotal',
+                    'header' => 'Subtotal',
+                    'width' => 80,
+                ),
+                array(
+                    'dataIndex' => 'calc_tax',
+                    'header' => 'Tax',
+                    'width' => 80,
+                ),
+                
+                
+                array(
+                    'dataIndex' => 'calc_total',
+                    'header' => 'Total',
+                    'width' => 80,
+                ),
+                
+                //array(
+                //        dataIndex : 'coitem_unitcost_in_order_cur',
+                //                header : 'Unit Cost',
+                //                width : 50,
+                //),
+                
+            ),
+            'foot' => array(
+                
+                
+            )
+        ));     
+            
+        $x->send($this->cohead_number.'-'.date('Y-m-d').'.xls');   
+            
+        
+        
+        
+    }
+    // flag all the voided shipments as void..
+    function shipvoidfill($roo, $q)
+    {
+        
+        
+        $lquery = "cohead_orderdate > '2012-01-01'";
+        //$lquery = '1=1';
+        $iquery = '1=1';
+        
+        $after = 'true';
+         
+        $t = clone($this);
+        $t->whereAdd(" $iquery AND $lquery");
+        $total = $t->count();
+        
+        $cache = '/tmp/shipvoidfill.'. $this->database() . date('-Y-m-d');
+        if (empty($q['offset'])  && file_exists($cache)) {
+            $q['offset'] = trim(file_get_contents($cache));
+        }
+        
+        
+        
+        $offset = empty($q['offset']) ? 0 : (int) $q['offset'];
+        
+        if ($offset > $total) {
+            $roo->jerr("DONE"); //???
+        }
+        
+        
+        $limit = 2;
+        //if ($offset > 1500) { // this was sg...
+        //    $limit = 100;
+       // }
+        $this->query("
+            SELECT invfifo_cohead_void_flag_order(cohead_id) FROM (
+                SELECT
+                        cohead_id
+                    FROM
+                        cohead
+   
+                    WHERE
+                        $lquery
+                        AND
+                        $iquery
+                    ORDER BY
+                        cohead_id DESC
+                    LIMIT
+                        $limit OFFSET $offset
+                ) x;
+        ");
+        file_put_contents($cache, $offset); // put the last offset, so we can continue
+        
+        
+        $roo->jok(array('total' => $total, 'limit'=>$limit, 'offset' => $offset));
+        
+        
+        
+    }
+    
+    function fillshipto($roo)
+    {
+        
+        if (empty($this->shipto_id)) {
+            $roo->jerr("order shipto is empty shipto_id?");
+        }
+        $items = $this->items();
+        foreach($items as $item) {
+            if (!empty($item->coitem_shipto_id)) {
+                continue; // ignore filled in values.
+            }
+            $ii = clone($item);
+            $item->coitem_shipto_id = $this->shipto_id;
+            $item->update($ii);
+        }
+        $roo->jok("updated");
+        
+    }
+    
+    function filllocation($roo, $q)
+    {
+        if (empty($this->cohead_location_src) && empty($q['_location_id'])) {
+            $roo->jerr("empty location?");
+        }
+        $items = $this->items();
+        foreach($items as $item) {
+            $ii = clone($item);
+            $item->coitem_location_src = empty($q['_location_id']) ? $this->cohead_location_src : $q['_location_id'];
+            $item->update($ii);
+        }
+        $roo->jok("updated");
+        
+    }
+    
+    function stockLevel($roo)
+    {
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->autoJoin();
+        $coitem->joinAddItem();
+        $coitem->coitem_cohead_id = $this->cohead_id;
+        
+        $items = $coitem->fetchAll();
+        $i = array();
+        foreach ($items as $item){
+            $ii = array(
+                'item' => $item->itemsite_id_item_number, 
+                'loc'=> $item->coitem_location_src_location_name,
+                'id'=> $item->coitem_linenumber . ($item->coitem_subnumber ? ('.' + $item->coitem_subnumber) : '')
+            );
+            
+            $i[] = (object) $ii;
+        }
+        
+        $itemloc = DB_DataObject::factory('itemloc');
+        $itemloc->availQty($roo,$i, array('curr_name' => $this->cohead_curr_id_curr_name));
+    }
+    
+    
+    
+    /**
+     * long running transactions need to lock tables, otherwise concurrent queries will get errors with
+     * deadlocks.
+     *
+     */
+    function lockTables()
+    {
+        static $locked = false;
+        
+        // prevent double calling..
+        if ($locked) {
+            return;
+        }
+        
+        $tables = array(
+            'invdetail',
+            'invfifo',
+            'invhist',
+            'gltrans',
+            'trialbal',
+            'itemloc',
+            
+        );
+        $giveup = time() + 60;
+        $ready = false;
+        //DB_DataObject::debugLevel(1);
+        // wait for no locks??!
+        $res = array();
+        while (!$ready && time() < $giveup) {
+            $d = DB_DataObjecT::factory('cohead');
+            $d->query("
+                SELECT
+                    count(pg_class.relname) as nlocks
+        
+                    from
+                        pg_stat_activity,pg_locks
+                    left  outer join
+                        pg_class
+                    on
+                        (pg_locks.relation = pg_class.oid)  
+                    where
+                        pg_locks.pid=pg_stat_activity.procpid
+                    AND
+                        pg_stat_activity.datname = '{$d->database()}'
+                   AND
+                    pg_class.relname IN ('".implode("','", $tables) ."') 
+       
+        
+              ");
+            $d->fetch();
+            $res[] = $d->nlocks;
+            if (empty($d->nlocks)) {
+                $ready =true;
+                break;
+            }
+            sleep(1);
+        }
+        if (!$ready) {
+            HTML_FlexyFramework::get()->page->jerr("{$d->database()} -
+                server is busy trying to perform another task, please try again in a few minutes
+                " . implode($res, ','));
+        }
+        $locked = true;
+        $d = DB_DataObjecT::factory('cohead');
+        foreach( $tables as $tbl) {
+             $d->query( "LOCK  TABLE $tbl    IN EXCLUSIVE MODE  ");
+            
+            
+        }
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Cohist.php b/DataObjects/Cohist.php
new file mode 100644 (file)
index 0000000..0c9574f
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Table Definition for cohist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cohist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cohist';              // table name
+    public $cohist_id;                       // int4(4)  not_null default_nextval%28%28cohist_cohist_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cohist_cust_id;                  // int4(4)  
+    public $cohist_itemsite_id;              // int4(4)  
+    public $cohist_shipdate;                 // date(4)  
+    public $cohist_shipvia;                  // text(-1)  
+    public $cohist_ordernumber;              // text(-1)  
+    public $cohist_orderdate;                // date(4)  
+    public $cohist_invcnumber;               // text(-1)  
+    public $cohist_invcdate;                 // date(4)  
+    public $cohist_qtyshipped;               // numeric(-1)  
+    public $cohist_unitprice;                // numeric(-1)  
+    public $cohist_shipto_id;                // int4(4)  
+    public $cohist_salesrep_id;              // int4(4)  
+    public $cohist_duedate;                  // date(4)  
+    public $cohist_imported;                 // bool(1)  default_false
+    public $cohist_billtoname;               // text(-1)  
+    public $cohist_billtoaddress1;           // text(-1)  
+    public $cohist_billtoaddress2;           // text(-1)  
+    public $cohist_billtoaddress3;           // text(-1)  
+    public $cohist_billtocity;               // text(-1)  
+    public $cohist_billtostate;              // text(-1)  
+    public $cohist_billtozip;                // text(-1)  
+    public $cohist_shiptoname;               // text(-1)  
+    public $cohist_shiptoaddress1;           // text(-1)  
+    public $cohist_shiptoaddress2;           // text(-1)  
+    public $cohist_shiptoaddress3;           // text(-1)  
+    public $cohist_shiptocity;               // text(-1)  
+    public $cohist_shiptostate;              // text(-1)  
+    public $cohist_shiptozip;                // text(-1)  
+    public $cohist_commission;               // numeric(-1)  
+    public $cohist_commissionpaid;           // bool(1)  
+    public $cohist_unitcost;                 // numeric(-1)  
+    public $cohist_misc_type;                // bpchar(-1)  
+    public $cohist_misc_descrip;             // text(-1)  
+    public $cohist_misc_id;                  // int4(4)  
+    public $cohist_doctype;                  // text(-1)  
+    public $cohist_promisedate;              // date(4)  
+    public $cohist_ponumber;                 // text(-1)  
+    public $cohist_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $cohist_sequence;                 // int4(4)  
+    public $cohist_taxtype_id;               // int4(4)  
+    public $cohist_taxzone_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $cohist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('cohist_taxtype_id', func_get_arg(0)) : $this->link('cohist_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $cohist_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('cohist_taxzone_id', func_get_arg(0)) : $this->link('cohist_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $cohist_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cohist_curr_id', func_get_arg(0)) : $this->link('cohist_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['_sums'])) {
+            $this->applyFilterSums($q,$roo);
+            return;
+        }
+        
+        
+    }
+    
+    function applyFilterSums($q,$roo)
+    {
+        if (empty($q['cust_id'])) {
+            $roo->jerr("Customer ID not set");
+        }
+        if (empty($q['startDate'])) {
+            $roo->jerr("No start date");   
+        }
+        if (empty($q['endDate'])) {
+            $roo->jerr("No start date");   
+        }
+        $this->cohist_cust_id = $q['cust_id'];
+        $this->whereAdd("
+            (cohist_invcdate >= '" .date('Y-m-d', strtotime($q['startDate'])) ."') 
+            AND
+            (cohist_invcdate <= '" .date('Y-m-d', strtotime($q['endDate'])) ."') 
+        ");
+    
+        $this->selectAdd();
+        
+        $this->selectAdd("
+            (SELECT curr_symbol from curr_symbol where curr_base LIMIT 1 ) as total_basecurr,
+            sum(currtobase(cohist_curr_id, cohist_unitprice, cohist_invcdate) * cohist_qtyshipped) AS total_value,
+            sum(cohist_qtyshipped) AS total_shipped,
+            count(distinct(cohist_ordernumber)) AS total_orders
+        ");
+        ;
+    }
+    
+    
+    
+    
+}
diff --git a/DataObjects/Cohisttax.php b/DataObjects/Cohisttax.php
new file mode 100644 (file)
index 0000000..8bd7c91
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for cohisttax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cohisttax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cohisttax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Coitem.php b/DataObjects/Coitem.php
new file mode 100644 (file)
index 0000000..2a80411
--- /dev/null
@@ -0,0 +1,903 @@
+<?php
+/**
+ * Table Definition for coitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Coitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'coitem';              // table name
+    public $coitem_id;                       // int4(4)  not_null default_nextval%28%28coitem_coitem_id_seq%29%3A%3Aregclass%29 primary_key
+    public $coitem_cohead_id;                // int4(4)  unique_key multiple_key
+    public $coitem_linenumber;               // int4(4)  not_null unique_key multiple_key
+    public $coitem_itemsite_id;              // int4(4)  
+    public $coitem_status;                   // bpchar(-1)  
+    public $coitem_scheddate;                // date(4)  
+    public $coitem_promdate;                 // date(4)  
+    public $coitem_qtyord;                   // numeric(-1)  not_null
+    public $coitem_unitcost;                 // numeric(-1)  not_null
+    public $coitem_price;                    // numeric(-1)  not_null
+    public $coitem_custprice;                // numeric(-1)  not_null
+    public $coitem_qtyshipped;               // numeric(-1)  not_null
+    public $coitem_order_id;                 // int4(4)  
+    public $coitem_memo;                     // text(-1)  
+    public $coitem_imported;                 // bool(1)  default_false
+    public $coitem_qtyreturned;              // numeric(-1)  
+    public $coitem_closedate;                // timestamptz(8)  
+    public $coitem_custpn;                   // text(-1)  
+    public $coitem_order_type;               // bpchar(-1)  
+    public $coitem_close_username;           // text(-1)  
+    public $coitem_lastupdated;              // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $coitem_substitute_item_id;       // int4(4)  
+    public $coitem_created;                  // timestamp(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $coitem_creator;                  // text(-1)  default_%22current_user%22%28%29
+    public $coitem_prcost;                   // numeric(-1)  
+    public $coitem_qty_uom_id;               // int4(4)  not_null
+    public $coitem_qty_invuomratio;          // numeric(-1)  not_null
+    public $coitem_price_uom_id;             // int4(4)  not_null
+    public $coitem_price_invuomratio;        // numeric(-1)  not_null
+    public $coitem_warranty;                 // bool(1)  not_null default_false
+    public $coitem_cos_accnt_id;             // int4(4)  
+    public $coitem_qtyreserved;              // numeric(-1)  not_null default_0.0
+    public $coitem_subnumber;                // int4(4)  not_null default_0 unique_key multiple_key
+    public $coitem_firm;                     // bool(1)  not_null default_false
+    public $coitem_taxtype_id;               // int4(4)  
+    public $coitem_location_src;
+    public $coitem_shipto_id;
+    
+   /**
+    * Getter / Setter for $coitem_cohead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cohead() {
+        return func_num_args() ? $this->link('coitem_cohead_id', func_get_arg(0)) : $this->link('coitem_cohead_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_cos_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cos_accnt() {
+        return func_num_args() ? $this->link('coitem_cos_accnt_id', func_get_arg(0)) : $this->link('coitem_cos_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('coitem_itemsite_id', func_get_arg(0)) : $this->link('coitem_itemsite_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('coitem_price_uom_id', func_get_arg(0)) : $this->link('coitem_price_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_qty_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qty_uom() {
+        return func_num_args() ? $this->link('coitem_qty_uom_id', func_get_arg(0)) : $this->link('coitem_qty_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_substitute_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function substitute_item() {
+        return func_num_args() ? $this->link('coitem_substitute_item_id', func_get_arg(0)) : $this->link('coitem_substitute_item_id');
+    }
+
+   /**
+    * Getter / Setter for $coitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('coitem_taxtype_id', func_get_arg(0)) : $this->link('coitem_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults()
+    {
+        
+        return array(
+            'coitem_qty_uom_id' => $this->sqlValue("( SELECT uom_id FROM uom WHERE uom_name = 'EA' LIMIT 1)"),
+            'coitem_price_uom_id' => $this->sqlValue("( SELECT uom_id FROM uom WHERE uom_name = 'EA' LIMIT 1)"),
+            'coitem_qty_invuomratio' => 1,
+            'coitem_price_invuomratio' => 1,
+            'coitem_taxtype_id' => $this->sqlValue("gettaxtypeid('Taxable'::text)"),  
+            'coitem_order_id' => 0,
+            'coitem_qtyreserved' => 0,
+            'coitem_qtyreturned' => 0,
+            'coitem_qtyshipped' => 0,
+            'coitem_warranty' => false,
+            'coitem_closedate' => $this->sqlValue('NULL'),
+            //'coitem_lastupdated' => $this->sqlValue('NULL'),
+            'coitem_status' => 'O', /// C = closed,  O = open.,
+            'coitem_cos_accnt_id' => $this->sqlValue('NULL'),
+            
+            'coitem_substitute_item_id' => $this->sqlValue('NULL'), 
+            'coitem_firm' => false,
+            'coitem_shipto_id' => $this->sqlValue('NULL'),
+            'coitem_location_src' => $this->sqlValue('NULL'),
+            'coitem_unitcost' => 0,
+             
+            
+        );
+    }
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (!empty($q['_totals']) && !empty($q['coitem_cohead_id']) ) {
+            
+            
+            $item = DB_DataObject::factory('item');
+            $isid = 0;
+            $itid = 0;
+            if ($item->get('item_number','Z-LIST-DISCOUNT')) {
+                $itid = $item->pid();
+               $is = $item->itemsite();
+               $isid = $is->pid();
+            }
+            
+            //does this order have any list discounts.
+            
+            $t = $this->factory($this->tableName());
+            $t->coitem_cohead_id = $q['coitem_cohead_id'];
+            $t->coitem_item_id = $itid;
+            $has_discount = $t->count();
+            
+            
+            $t = $this->factory($this->tableName());
+            $t->coitem_cohead_id = $q['coitem_cohead_id'];
+            $t->autoJoin();
+            $t->selectAdd();
+            
+            
+            if ($has_discount) {
+                $t->selectAdd("
+                     SUM(ROUND(coitem_qtyord * coitem_price,2))  + calcsalesorderlistdiscount(coitem_cohead_id) as  total_sub 
+          
+                ");
+            } else {
+                $t->selectAdd("
+                      SUM(ROUND(coitem_qtyord * coitem_price,2))  as  total_sub 
+                              
+                ");
+            }
+            $t->selectAdd("
+                          
+                          
+                ROUND(SUM(coitem_qtyord),0) AS total_qty,
+                
+             
+                ROUND(SUM(calculatetax(
+                    join_coitem_cohead_id_cohead_id.cohead_taxzone_id,
+                    coitem_taxtype_id,
+                    join_coitem_cohead_id_cohead_id.cohead_orderdate::date,
+                    join_coitem_cohead_id_cohead_id.cohead_curr_id,
+                    coitem_qtyord * coitem_price
+                )),2)  as total_tax,
+               
+                
+                ROUND(SUM(ROUND(coitem_qtyord * coitem_price, 2) +  calculatetax(
+                    join_coitem_cohead_id_cohead_id.cohead_taxzone_id,
+                    coitem_taxtype_id,
+                    join_coitem_cohead_id_cohead_id.cohead_orderdate::date,
+                    join_coitem_cohead_id_cohead_id.cohead_curr_id,
+                    coitem_qtyord * coitem_price
+                )),2)  as total_total,
+                
+                calcsalesorderlistdiscount(coitem_cohead_id) as   total_list_discount
+                 
+            ");
+            $t->whereAdd('coitem_itemsite_id != '. $isid);
+            $t->groupBy('coitem_cohead_id');
+            $t->find(true);
+            $roo->jdata($t->toArray('%s', true));
+            exit;
+            
+        }
+        if (!empty($_REQUEST['_without_list_discount'])) {
+            $item = DB_DataObject::factory('item');
+           
+            if ($item->get('item_number','Z-LIST-DISCOUNT')) {
+               $is = $item->itemsite();
+               $this->whereAdd('coitem_itemsite_id != '. $is->pid());
+               
+           }
+        }
+        
+        if (!empty($q['_hk_xfer'])) {
+            $this->buildAllXfer($roo, $q['_hk_xfer']);
+            $roo->jok('ok');
+            
+        }
+        $tbl = $this->tableName();
+        //DB_DataObject::DebugLevel(1);
+        // add the join for items...
+        $item = DB_DataObject::Factory('item');
+        
+        $this->_join .= "\n INNER JOIN item AS join_coitem_item ON
+            join_coitem_itemsite_id_itemsite_id.itemsite_item_id = join_coitem_item.item_id";
+        $this->selectAs($item, '%s', 'join_coitem_item');
+        
+        $this->_extra_cols = empty($this->_extracols) ? array() : $this->_extracols;
+        $this->_extra_cols[] = 'item_number';
+        
+        //Db_DAtaObject::debugLevel(1);
+        $this->selectAdd( "(
+                SELECT uom_descrip FROM uom where uom_id=coitem_qty_uom_id LIMIT 1)
+                as coitem_qty_uom_id_descrip"
+        );
+        
+         $this->selectAddShipinfo(
+                    isset($q['shiphead_id']) ? $q['shiphead_id'] : 0
+        );
+        
+        $this->selectAddBillInfo(
+                isset($q['cobmisc_id']) ? $q['cobmisc_id'] : 0
+        );
+        // $this->selectAddAvail(
+        //        isset($q['coitem_cohead_id']) ? $q['coitem_cohead_id'] : 0
+        //);
+        // available??
+        
+        
+        // exclude kit parts from shipping lists.
+        if (!empty($q['_stocked_only']) || (!empty($q['coitem_shipto_id']) && !empty($q['query']['coitem_location_src']))) { 
+            
+            $this->whereAdd("
+                true = (SELECT itemsite_stocked FROM
+                            itemsite WHERE itemsite_id = coitem_itemsite_id)
+                AND
+                'K' != (SELECT item_type FROM item WHERE item_id = (
+                        SELECT itemsite_item_id FROM
+                            itemsite WHERE itemsite_id = coitem_itemsite_id))
+                      ");
+        
+        }
+        
+        
+        if (!empty($q['query']['coitem_location_src'])) {
+            $loc = (int)$q['query']['coitem_location_src'];
+            
+            $shiphead_id = isset($q['shiphead_id']) ? (int) $q['shiphead_id'] : 0;
+        
+            $this->whereAdd("
+                {$tbl}.coitem_location_src  = $loc
+                OR
+                coitem_id IN (SELECT shipitem_orderitem_id FROM
+                        shipitem
+                        WHERE
+                        shipitem_shiphead_id = $shiphead_id
+                    )
+            ");
+            
+            
+            
+        }
+        //DB_DataObject::DebugLevel(1);
+        $this->selectAdd("
+            currtocurr(baseCurrId(), join_coitem_cohead_id_cohead_id.cohead_curr_id, coitem_unitcost, NOW()::date ) as 
+                coitem_unitcost_in_order_cur,
+                
+            coitem_qtyord * coitem_price as calc_subtotal,
+            calculatetax(
+                join_coitem_cohead_id_cohead_id.cohead_taxzone_id,
+                coitem_taxtype_id,
+                join_coitem_cohead_id_cohead_id.cohead_orderdate::date,
+                join_coitem_cohead_id_cohead_id.cohead_curr_id,
+                coitem_qtyord * coitem_price
+            )   as calc_tax,
+           
+            
+            (coitem_qtyord * coitem_price) +  calculatetax(
+                join_coitem_cohead_id_cohead_id.cohead_taxzone_id,
+                coitem_taxtype_id,
+                join_coitem_cohead_id_cohead_id.cohead_orderdate::date,
+                join_coitem_cohead_id_cohead_id.cohead_curr_id,
+                coitem_qtyord * coitem_price
+            )  as calc_total,
+            
+            CASE WHEN coitem_custprice != 0.0 THEN 
+                ROUND( ( 100.0 - ( coitem_price / coitem_custprice )  * 100.00), 2)
+            ELSE
+                0.0
+            END
+            as coitem_linedisc
+            
+        ");
+        if (!empty($q['coitem_cohead_id'])) {
+            $cohead = DB_DataObject::Factory('cohead');
+            $cohead->get($q['coitem_cohead_id']);
+            
+            $cust = $cohead->cust();
+            $pl = $cust->priceList();
+            $curr = false;
+            if ($pl) {
+                $curr =  $pl->curr();
+            }
+            if ($curr) {
+                $this->selectAdd("
+                    
+                    (SELECT currtocurr({$curr->pid()}, {$cohead->curr()->pid()},
+                        ipsitem_price,
+                        '{$cohead->cohead_targetdate}')
+                        FROM ipsitem
+                        WHERE
+                            ipsitem_item_id = join_coitem_item.item_id
+                            AND
+                            ipsitem_ipshead_id={$pl->pid()}
+                        )
+                        as customer_price_each
+                    
+                ");
+                  
+             } else {
+                $this->selectAdd("
+                    0 as customer_price_each
+                    
+                ");
+                
+                
+            } 
+        }
+        
+        
+        if(!empty($q['_with_profit'])){
+            $this->selectAdd("
+                (SELECT 
+                    ABS(SUM(currtocurr(basecurrid(), join_coitem_cohead_id_cohead_id.cohead_curr_id,invdetail_qty * invfifo_landedunitcost, invhist_transdate::date)))
+                 FROM
+                    invdetailview
+                 WHERE 
+                    invhist_ordnumber LIKE join_coitem_cohead_id_cohead_id.cohead_number || '%'
+                    AND
+                    invfifo_void = 0
+                    AND
+                    coitem_itemsite_id = invhist_itemsite_id
+                 GROUP BY invhist_itemsite_id
+                ) AS calc_cost_total
+            ");
+            
+        }
+        
+        
+    }
+    
+    
+    
+    function selectAddAvail($id)
+    {
+        
+        $id = $id * 1;
+        if ($id) {
+            
+            // available excluding ones on sales orders..
+            $this->selectAdd("
+                ROUND(COALESCE(
+                
+                
+                        qtyavailable(coitem_itemsite_id, join_coitem_cohead_id_cohead_id.cohead_targetdate)
+                        + allocatedForSo(coitem_itemsite_id, startOfTime(), join_coitem_cohead_id_cohead_id.cohead_targetdate)
+                        
+                        , 0 ),0) as avail_qty 
+                 
+            ");
+            
+        } else {
+            // no reference
+            $this->selectAdd("
+                'n/a' as avail_qty
+                 
+                
+            ");
+            
+        }
+        
+    }
+    
+    
+    function reserved()
+    {
+        $sh = DB_DAtaObject::factory('shipitem');
+        $sh->shipitem_orderitem_id = $this->pid();
+        $sh->selectAdd();
+        $sh->selectAdd('COALESCE(SUM(shipitem_qty),0) as total_shipitem');
+        $sh->find(true);
+        return $sh->total_shipitem - $this->coitem_qtyshipped;
+        
+    }
+    
+    
+    function selectAddShipinfo($id)
+    {
+      
+        // need to find remaining..
+        $id = $id * 1;
+        if ($id) {
+            $this->selectAdd("
+                COALESCE((SELECT  SUM(shipitem_qty) FROM shipitem
+                    WHERE
+                        shipitem_shiphead_id = $id
+                        AND
+                        shipitem_orderitem_id = coitem_id
+                        
+                ),0)  as shipitem_qty,
+                
+                COALESCE((SELECT  SUM(shipitem_qty) FROM shipitem
+                    WHERE
+                        shipitem_shiphead_id != $id
+                        AND
+                        shipitem_orderitem_id = coitem_id
+                     
+                ),0 )  as shipitem_shipped
+            ");
+            
+        } else {
+            // no reference
+            $this->selectAdd("
+                0 as shipitem_qty,
+                
+                COALESCE((SELECT SUM(shipitem_qty) FROM shipitem
+                    WHERE
+                        shipitem_orderitem_id = coitem_id
+                        
+                ),0) as shipitem_shipped
+                
+                
+                
+            ");
+            
+            
+            
+            
+        }
+        
+        
+        
+        
+        
+    }
+    function selectAddBillinfo($id)
+    {
+       
+  // need to find remaining..
+        $id = $id * 1;
+        if ($id) {
+            $this->selectAdd("
+                COALESCE((SELECT  SUM(cobill_qty) FROM cobill
+                    WHERE
+                        cobill_cobmisc_id = $id
+                        AND
+                        cobill_coitem_id = coitem_id
+                        
+                ), 0) as  cobill_qty,
+                
+                COALESCE((SELECT  SUM(cobill_qty) FROM cobill
+                    WHERE
+                        cobill_cobmisc_id != $id
+                        AND
+                        cobill_coitem_id = coitem_id
+                     
+                ), 0 ) as cobill_billed
+                
+            
+            ");
+            
+        } else {
+            // no reference
+            $this->selectAdd("
+                0 as cobill_qty,
+                
+                COALESCE((SELECT SUM(cobill_qty) FROM cobill
+                    WHERE
+                        cobill_coitem_id = coitem_id
+                        
+                ), 0) as cobill_billed
+                
+                
+                
+            ");
+            
+            
+            
+            
+        }
+        
+        
+        
+        
+        
+    }
+    function joinAddItem()
+    {
+        $this->_join .= '
+            LEFT JOIN
+                item  as join_item
+            ON
+                join_coitem_itemsite_id_itemsite_id.itemsite_item_id = join_item.item_id
+        ';
+        $item = DB_DataObject::Factory('item');
+        $this->selectAs($item, 'itemsite_id_%s', 'join_item');
+        
+    }
+    
+    
+    
+    function beforeInsert($req, $roo)
+    {   
+        foreach($this->defaults() as $k=>$v) {
+            if (empty($this->$k)) {
+                $this->$k = $v;
+            }
+        }
+        if (empty($this->coitem_custprice)) {
+            $this->coitem_custprice = $this->coitem_price;
+        }
+        $this->coitem_warranty = false;
+        
+        //$this->coitem_status = $this->cohead()->cohead_status;
+        //print_R($this);$this->jerr("not yet");;
+        
+    }
+    
+     
+    
+    function beforeUpdate($old, $req, $roo)
+    {
+        foreach($this->defaults() as $k=>$v) {
+            if (empty($this->$k)) {
+                $this->$k = $v;
+            }
+        
+        }
+        
+        // price is the list price...
+        if (empty($this->coitem_custprice)) {
+            $this->coitem_custprice = $this->coitem_price;
+        }
+        
+        
+        
+        unset($this->coitem_lastupdated);
+        if (!$this->coitem_shipto_id) {
+            $this->coitem_shipto_id = $this->sqlValue('NULL');
+        }
+        if (!$this->coitem_location_src) {
+            $this->coitem_location_src = $this->sqlValue('NULL');
+        }
+        $this->coitem_warranty = false;
+        //print_R(array(
+        //    $req['coitem_qtyord'],
+        //    $old->coitem_qtyord,
+        //    $old->coitem_qtyreserved
+        //    
+        //)); exit;
+        //print_R($req);print_R($this);print_R($old);exit;
+        if (isset($req['coitem_qtyord']) && ($req['coitem_qtyord'] != $old->coitem_qtyord)  &&  $old->reserved() > 0.0) {
+            $roo->jerr("stock is reserved, you can not change the quantity - void the reserved shipment first");
+        }
+        // make sure this does not get changed..
+        unset($this->coitem_qtyreserved);
+        unset($this->coitem_qtyreturned);
+        //unset($this->coitem_qtyreturned); 
+        
+        
+        
+        //$this->coitem_status = $this->cohead()->cohead_status;
+        
+        
+    }
+    
+    
+    
+    
+    function onInsert($request,$roo)
+    {
+        $this->updateKitParts($roo);
+        $this->updatePretaxDiscount($roo);        
+    }
+
+    function onUpdate($old, $request,$roo)
+    {
+        $this->updateKitParts($roo);
+        $this->updatePretaxDiscount($roo);
+    }
+    
+    function onDelete($req, $roo)
+    {
+        $this->updatePretaxDiscount($roo);
+    }
+    
+    function updateKitParts($roo)
+    {
+        $i = $this->itemsite()->item();
+        //$roo->jerr(print_R($i, true));
+        if ($i->item_type != 'K') {
+            return;
+        }
+        // kit -- update the child locations.
+        $co = DB_DataObject::factory('coitem');
+        $co->coitem_cohead_id = $this->coitem_cohead_id;        
+        $co->coitem_linenumber = $this->coitem_linenumber;
+        $co->whereAdd('coitem_subnumber > 0');
+        $co->find();
+        while ($co->fetch()) {
+            $cc = clone($co);
+            $co->coitem_location_src = $this->coitem_location_src;
+            $co->coitem_shipto_id = $this->coitem_shipto_id;
+            $co->update($cc);
+        }
+        
+        
+        
+    }
+    
+    
+    
+    function beforeDelete($deps, $roo)
+    {
+        // this should probably do more checks..
+        
+        if (!empty($this->coitem_qtyreserved) && $this->coitem_qtyreserved > 0.0) {
+            $roo->jerr("item has draft shipments - void or remove that line first.");
+        }
+        
+       
+        if ($this->reserved() > 0.0) {
+            $roo->jerr("stock is reserved, you can not change the quantity - void the reserved shipment first");
+        }
+       
+        $i = $this->itemsite()->item();
+        
+        if ($i->item_type == 'K') {
+            
+            // if any of these items have been shipped, then deleting is not possible
+            // so we have to flag them as cancelled..
+            $void = false; 
+            $co = DB_DataObject::factory('coitem');
+            $co->coitem_cohead_id = $this->coitem_cohead_id;        
+            $co->coitem_linenumber = $this->coitem_linenumber;
+            $co->whereAdd('coitem_subnumber > 0');
+            $co->find(true);
+            while ($co->fetch()) {
+                $cc = DB_DataObject::factory('coitem');
+                $cc->query("SELECT deleteSoItem({$co->pid()}) AS  result");
+                $cc->fetch();
+                if (!empty($cc->result) && $cc->result < 0) {
+                    $void = true;
+                    $cc = clone($co);
+                    if ($cc->coitem_status !='X' ) {
+                        $cc->coitem_status = 'C';
+                        $cc->update($co);
+                    }
+                    
+                }
+                 
+                
+            }
+            if ($void) {
+                $old = clone($this);
+                $this->coitem_status ='C';
+                $this->update($old);
+                $roo->jok("Voided");
+            }
+        }
+        
+        
+    }
+    
+    
+    
+    function updatePretaxDiscount($roo)
+    {
+        // see if we have a list item discount
+        $item = DB_DataObject::factory('item');
+        if (!$item->get('item_number','Z-LIST-DISCOUNT')) {
+            
+            return;
+        }
+        
+        // this feature is not enabled in HK.
+        $db = substr($this->database(),-2);
+        if ($db == 'hk') {
+            return;
+        }
+        
+        $is = $item->itemsite();
+        
+        // what is the pretax discount
+        //DB_DataObject::debugLevel(1);
+        
+        $co = DB_DataObject::factory('coitem');
+        $co->coitem_cohead_id = $this->coitem_cohead_id;
+        
+        $co->selectAdd();
+        
+        $co->coitem_itemsite_id != $is->pid();
+        
+        // calc is important -- sum of one - sum of the other..
+        $co->selectAdd('SUM(
+                       ROUND( coitem_custprice * coitem_qtyord, 2)
+                       -
+                       ROUND (coitem_price * coitem_qtyord,2)
+                    ) as pretax_discount ');
+        
+        $co->whereAdd('coitem_custprice > coitem_price');
+        
+        $pretax_discount = 0;
+        if ($co->find(true)) {
+            $pretax_discount = $co->pretax_discount;
+        }
+        
+        // determine if we have a line item for the discount.
+        $co = DB_DataObject::factory('coitem');
+        $co->coitem_cohead_id = $this->coitem_cohead_id;
+        $co->coitem_itemsite_id = $is->pid();
+        
+        $matches= $co->count();
+        
+        if ((empty($pretax_discount) ||  ($pretax_discount == 0.0))   && $matches) {
+            $co->find(true);
+            $co->delete();
+        }
+        if (empty($pretax_discount) ||  ($pretax_discount == 0.0)) {
+            return;
+        }
+        
+        
+        
+        if (!$co->count()) {
+            $co->coitem_qtyord = 1;
+            $co->coitem_custprice = $pretax_discount;
+            $co->coitem_price = $pretax_discount;
+            $co->coitem_linenumber = 99999;
+            $co->coitem_taxtype_id = $this->sqlValue("gettaxtypeid('Taxfree'::text)");
+            
+            $co->beforeInsert(array(),$roo );
+            $co->insert();
+            return;
+        } 
+        $co->find(true);
+        
+        $cc = clone($co);
+        $co->coitem_taxtype_id = $this->sqlValue("gettaxtypeid('Taxfree'::text)");
+        $co->coitem_qtyord = 1;
+        $co->coitem_linenumber = 99999;
+        $co->coitem_custprice = $pretax_discount;
+        $co->coitem_price = $pretax_discount;
+        $co->beforeUpdate($cc,array(), $roo);
+        $co->update($cc);
+        
+        
+        
+    }
+    
+    
+    
+     
+    
+    function buildAllXfer($roo, $id)
+    {
+        //$roo->jerr("still testing");
+        // logic needs thought here..
+        
+        
+        //DB_DataObject::debugLevel(1);
+        $ch = DB_DataObject::factory('cohead');
+        $ch->get($id);
+        
+        $cur = DB_DataObject::factory('curr_symbol');
+        $cur->get('curr_abbr', 'HKD');
+        if ($ch->cohead_curr_id != $cur->pid()) {
+            $roo->jerr("currency has to be HKD for transfer {$ch->cohead_curr_id} != {$cur->pid()}");
+        }
+        
+        // fetch all the stock available..
+        $co  = DB_DataObject::factory('coitem');
+        foreach($co->defaults() as $k=>$v) {
+            $co->$k = $v;
+        }
+        $co->coitem_cohead_id = $id;
+        
+        
+        $il = DB_DataObject::Factory('itemloc');
+        $il->whereAdd('itemloc_qty > 0');
+        // if sg has stock..
+        // --> hk has to buy it...
+        // -> sg has to sell it to
+        // -> HK has to create a CM for this.
+        // ->  NO PURCHASE LOCAL..
+        // -> NO INVOICE in HK
+        
+        
+        // in our standard scenario
+        // an invoice/so..
+        //  SG sells to somebody.
+        //  it buys it from HK..
+        // 
+        
+        
+        
+        $il->find();
+        $add =array();
+        $items = array();
+        $i = 0;
+        while ($il->fetch()) {
+            $i++;
+            $cc = clone($co);
+            $in = $il->itemsite()->item()->item_number;
+            $items[$in] = isset($items[$in]) ? $items[$in] : 0;
+            $items[$in] += abs($il->itemloc_qty);
+            
+            $cc->item_number = $in;
+            $cc->setFrom(array(
+                  
+                
+                'coitem_linenumber' => $i,
+                'coitem_itemsite_id' => $il->itemloc_itemsite_id,
+                'coitem_scheddate' => $ch->cohead_targetdate,
+                'coitem_qtyord' =>  abs($il->itemloc_qty),
+                //'coitem_unitcost' => 
+                //'coitem_price' =>
+                //'coitem_custprice' =>
+                //'coitem_subnumber' =>
+                'coitem_location_src' => $il->itemloc_location_id,
+                'coitem_shipto_id' => $ch->cohead_shipto_id,
+            ));
+            $add[] = $cc;
+            
+        }
+        // fetch the prices..
+        $po = DB_DataObject::Factory('pohead');
+        $prices = $po->fetchXferPrices($roo, $items);
+        //$roo->jerr(json_encode($prices));
+        foreach($add as $cc) {
+            if (!isset($prices[$cc->item_number])) {
+                $roo->jerr("no price available for {$cc->item_number}");
+            }
+            $p = $prices[$cc->item_number];
+            $cc->setFrom(array(
+                'coitem_unitcost' => $p,
+                'coitem_price' => $p,
+                'coitem_custprice' => $p,
+                
+                
+            ));
+            $cc->insert();
+        }
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Comment.php b/DataObjects/Comment.php
new file mode 100644 (file)
index 0000000..733e47b
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Table Definition for comment
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Comment extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'comment';             // table name
+    public $comment_id;                      // int4(4)  not_null default_nextval%28%28%22comment_comment_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $comment_source_id;               // int4(4)  multiple_key
+    public $comment_date;                    // timestamptz(8)  
+    public $comment_user;                    // text(-1)  
+    public $comment_text;                    // text(-1)  
+    public $comment_cmnttype_id;             // int4(4)  
+    public $comment_source;                  // text(-1)  multiple_key
+    public $comment_public;                  // bool(1)  
+
+    
+   /**
+    * Getter / Setter for $comment_cmnttype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cmnttype() {
+        return func_num_args() ? $this->link('comment_cmnttype_id', func_get_arg(0)) : $this->link('comment_cmnttype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Company.php b/DataObjects/Company.php
new file mode 100644 (file)
index 0000000..f616801
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Table Definition for company
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Company extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'company';             // table name
+    public $company_id;                      // int4(4)  not_null default_nextval%28company_company_id_seq%29 primary_key
+    public $company_number;                  // text(-1)  unique_key
+    public $company_descrip;                 // text(-1)  
+    public $company_external;                // bool(1)  not_null default_false
+    public $company_server;                  // text(-1)  
+    public $company_port;                    // int4(4)  
+    public $company_database;                // text(-1)  
+    public $company_curr_id;                 // int4(4)  
+    public $company_yearend_accnt_id;        // int4(4)  
+    public $company_gainloss_accnt_id;       // int4(4)  
+    public $company_dscrp_accnt_id;          // int4(4)  
+    public $company_unrlzgainloss_accnt_id;    // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $company_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('company_curr_id', func_get_arg(0)) : $this->link('company_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $company_dscrp_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function dscrp_accnt() {
+        return func_num_args() ? $this->link('company_dscrp_accnt_id', func_get_arg(0)) : $this->link('company_dscrp_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $company_gainloss_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function gainloss_accnt() {
+        return func_num_args() ? $this->link('company_gainloss_accnt_id', func_get_arg(0)) : $this->link('company_gainloss_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $company_unrlzgainloss_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function unrlzgainloss_accnt() {
+        return func_num_args() ? $this->link('company_unrlzgainloss_accnt_id', func_get_arg(0)) : $this->link('company_unrlzgainloss_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $company_yearend_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function yearend_accnt() {
+        return func_num_args() ? $this->link('company_yearend_accnt_id', func_get_arg(0)) : $this->link('company_yearend_accnt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Coship.php b/DataObjects/Coship.php
new file mode 100644 (file)
index 0000000..47caea8
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Table Definition for coship
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Coship extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'coship';              // table name
+    public $coship_id;                       // int4(4)  
+    public $coship_coitem_id;                // int4(4)  
+    public $coship_shipdate;                 // timestamptz(8)  
+    public $coship_qty;                      // numeric(-1)  
+    public $coship_transdate;                // timestamptz(8)  
+    public $coship_shipped;                  // bool(1)  
+    public $coship_invoiced;                 // bool(1)  
+    public $coship_cosmisc_id;               // int4(4)  
+    public $coship_trans_username;           // text(-1)  
+    public $coship_invcitem_id;              // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Cosmisc.php b/DataObjects/Cosmisc.php
new file mode 100644 (file)
index 0000000..69045c9
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Table Definition for cosmisc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cosmisc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cosmisc';             // table name
+    public $cosmisc_id;                      // int4(4)  
+    public $cosmisc_cohead_id;               // int4(4)  
+    public $cosmisc_shipvia;                 // text(-1)  
+    public $cosmisc_freight;                 // numeric(-1)  
+    public $cosmisc_notes;                   // text(-1)  
+    public $cosmisc_shipdate;                // date(4)  
+    public $cosmisc_shipchrg_id;             // int4(4)  
+    public $cosmisc_shipform_id;             // int4(4)  
+    public $cosmisc_shipped;                 // bool(1)  
+    public $cosmisc_sfstatus;                // bpchar(-1)  
+    public $cosmisc_tracknum;                // text(-1)  
+    public $cosmisc_number;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Costcat.php b/DataObjects/Costcat.php
new file mode 100644 (file)
index 0000000..bfe379f
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Table Definition for costcat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Costcat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'costcat';             // table name
+    public $costcat_id;                      // int4(4)  not_null default_nextval%28%28costcat_costcat_id_seq%29%3A%3Aregclass%29 primary_key
+    public $costcat_code;                    // text(-1)  
+    public $costcat_descrip;                 // text(-1)  
+    public $costcat_asset_accnt_id;          // int4(4)  
+    public $costcat_liability_accnt_id;      // int4(4)  
+    public $costcat_adjustment_accnt_id;     // int4(4)  
+    public $costcat_matusage_accnt_id;       // int4(4)  
+    public $costcat_purchprice_accnt_id;     // int4(4)  
+    public $costcat_laboroverhead_accnt_id;    // int4(4)  
+    public $costcat_scrap_accnt_id;          // int4(4)  
+    public $costcat_invcost_accnt_id;        // int4(4)  
+    public $costcat_wip_accnt_id;            // int4(4)  
+    public $costcat_shipasset_accnt_id;      // int4(4)  
+    public $costcat_mfgscrap_accnt_id;       // int4(4)  
+    public $costcat_transform_accnt_id;      // int4(4)  
+    public $costcat_freight_accnt_id;        // int4(4)  
+    public $costcat_toliability_accnt_id;    // int4(4)  
+    public $costcat_exp_accnt_id;            // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $costcat_exp_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function exp_accnt() {
+        return func_num_args() ? $this->link('costcat_exp_accnt_id', func_get_arg(0)) : $this->link('costcat_exp_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $costcat_toliability_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function toliability_accnt() {
+        return func_num_args() ? $this->link('costcat_toliability_accnt_id', func_get_arg(0)) : $this->link('costcat_toliability_accnt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Costelem.php b/DataObjects/Costelem.php
new file mode 100644 (file)
index 0000000..a865f98
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for costelem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Costelem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'costelem';            // table name
+    public $costelem_id;                     // int4(4)  not_null default_nextval%28%28costelem_costelem_id_seq%29%3A%3Aregclass%29 primary_key
+    public $costelem_type;                   // text(-1)  
+    public $costelem_sys;                    // bool(1)  
+    public $costelem_po;                     // bool(1)  
+    public $costelem_active;                 // bool(1)  
+    public $costelem_exp_accnt_id;           // int4(4)  
+    public $costelem_cost_item_id;           // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Costhist.php b/DataObjects/Costhist.php
new file mode 100644 (file)
index 0000000..a0bf4e6
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Table Definition for costhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Costhist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'costhist';            // table name
+    public $costhist_id;                     // int4(4)  not_null default_nextval%28%28%22costhist_costhist_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $costhist_item_id;                // int4(4)  
+    public $costhist_costelem_id;            // int4(4)  
+    public $costhist_type;                   // bpchar(-1)  
+    public $costhist_date;                   // timestamptz(8)  
+    public $costhist_oldcost;                // numeric(-1)  
+    public $costhist_newcost;                // numeric(-1)  
+    public $costhist_lowlevel;               // bool(1)  
+    public $costhist_oldcurr_id;             // int4(4)  default_basecurrid%28%29
+    public $costhist_newcurr_id;             // int4(4)  default_basecurrid%28%29
+    public $costhist_username;               // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $costhist_newcurr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function newcurr() {
+        return func_num_args() ? $this->link('costhist_newcurr_id', func_get_arg(0)) : $this->link('costhist_newcurr_id');
+    }
+
+   /**
+    * Getter / Setter for $costhist_oldcurr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function oldcurr() {
+        return func_num_args() ? $this->link('costhist_oldcurr_id', func_get_arg(0)) : $this->link('costhist_oldcurr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Costupdate.php b/DataObjects/Costupdate.php
new file mode 100644 (file)
index 0000000..d5c9a5e
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for costupdate
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Costupdate extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'costupdate';          // table name
+    public $costupdate_item_id;              // int4(4)  unique_key
+    public $costupdate_lowlevel_code;        // int4(4)  not_null default_1
+    public $costupdate_item_type;            // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Country.php b/DataObjects/Country.php
new file mode 100644 (file)
index 0000000..e06401d
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for country
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Country extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'country';             // table name
+    public $country_id;                      // int4(4)  not_null default_nextval%28country_country_id_seq%29 primary_key
+    public $country_abbr;                    // bpchar(-1)  unique_key
+    public $country_name;                    // text(-1)  unique_key
+    public $country_curr_abbr;               // bpchar(-1)  
+    public $country_curr_name;               // text(-1)  
+    public $country_curr_number;             // bpchar(-1)  
+    public $country_curr_symbol;             // varchar(-1)  
+    public $country_qt_number;               // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au)
+    {
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['query']['country_name'])) {
+            $v = $this->escape($q['query']['country_name']);
+            $this->whereAdd("country_name ILIKE '$v%'");
+        }
+        
+        
+    }
+}
diff --git a/DataObjects/Creditmemoeditlist.php b/DataObjects/Creditmemoeditlist.php
new file mode 100644 (file)
index 0000000..972dbd8
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for creditmemoeditlist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Creditmemoeditlist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'creditmemoeditlist';    // table name
+    public $orderid;                         // int4(4)  
+    public $itemid;                          // int4(4)  
+    public $documentnumber;                  // text(-1)  
+    public $cust_number;                     // text(-1)  
+    public $billtoname;                      // text(-1)  
+    public $ordernumber;                     // text(-1)  
+    public $linenumber;                      // int4(4)  
+    public $item;                            // text(-1)  
+    public $itemdescrip;                     // text(-1)  
+    public $iteminvuom;                      // text(-1)  
+    public $qtytobill;                       // text(-1)  
+    public $price;                           // text(-1)  
+    public $extprice;                        // text(-1)  
+    public $sence;                           // text(-1)  
+    public $account;                         // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Creditmemoitem.php b/DataObjects/Creditmemoitem.php
new file mode 100644 (file)
index 0000000..f3be440
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Table Definition for creditmemoitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Creditmemoitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'creditmemoitem';      // table name
+    public $cmitem_id;                       // int4(4)  
+    public $cmitem_cmhead_id;                // int4(4)  
+    public $cmitem_linenumber;               // int4(4)  
+    public $cmitem_itemsite_id;              // int4(4)  
+    public $cmitem_qtycredit;                // numeric(-1)  
+    public $cmitem_qtyreturned;              // numeric(-1)  
+    public $cmitem_unitprice;                // numeric(-1)  
+    public $cmitem_comments;                 // text(-1)  
+    public $cmitem_rsncode_id;               // int4(4)  
+    public $cmitem_taxtype_id;               // int4(4)  
+    public $cmitem_qty_uom_id;               // int4(4)  
+    public $cmitem_qty_invuomratio;          // numeric(-1)  
+    public $cmitem_price_uom_id;             // int4(4)  
+    public $cmitem_price_invuomratio;        // numeric(-1)  
+    public $cmitem_raitem_id;                // int4(4)  
+    public $item_id;                         // int4(4)  
+    public $qty;                             // numeric(-1)  
+    public $unitprice;                       // numeric(-1)  
+    public $extprice;                        // numeric(-1)  
+    public $baseextprice;                    // numeric(-1)  
+    public $tax;                             // numeric(-1)  
+    public $unitcost;                        // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Crmacct.php b/DataObjects/Crmacct.php
new file mode 100644 (file)
index 0000000..362cd92
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Table Definition for crmacct
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Crmacct extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'crmacct';             // table name
+    public $crmacct_id;                      // int4(4)  not_null default_nextval%28crmacct_crmacct_id_seq%29 primary_key
+    public $crmacct_number;                  // text(-1)  
+    public $crmacct_name;                    // text(-1)  
+    public $crmacct_active;                  // bool(1)  default_true
+    public $crmacct_type;                    // bpchar(-1)  
+    public $crmacct_cust_id;                 // int4(4)  
+    public $crmacct_competitor_id;           // int4(4)  
+    public $crmacct_partner_id;              // int4(4)  
+    public $crmacct_prospect_id;             // int4(4)  
+    public $crmacct_vend_id;                 // int4(4)  
+    public $crmacct_cntct_id_1;              // int4(4)  
+    public $crmacct_cntct_id_2;              // int4(4)  
+    public $crmacct_parent_id;               // int4(4)  
+    public $crmacct_notes;                   // text(-1)  
+    public $crmacct_taxauth_id;              // int4(4)  
+    public $crmacct_owner_username;          // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $crmacct_cntct_id_1
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct1() {
+        return func_num_args() ? $this->link('crmacct_cntct_id_1', func_get_arg(0)) : $this->link('crmacct_cntct_id_1');
+    }
+
+   /**
+    * Getter / Setter for $crmacct_cntct_id_2
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct2() {
+        return func_num_args() ? $this->link('crmacct_cntct_id_2', func_get_arg(0)) : $this->link('crmacct_cntct_id_2');
+    }
+
+   /**
+    * Getter / Setter for $crmacct_cust_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cust() {
+        return func_num_args() ? $this->link('crmacct_cust_id', func_get_arg(0)) : $this->link('crmacct_cust_id');
+    }
+
+   /**
+    * Getter / Setter for $crmacct_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('crmacct_parent_id', func_get_arg(0)) : $this->link('crmacct_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $crmacct_prospect_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prospect() {
+        return func_num_args() ? $this->link('crmacct_prospect_id', func_get_arg(0)) : $this->link('crmacct_prospect_id');
+    }
+
+   /**
+    * Getter / Setter for $crmacct_taxauth_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxauth() {
+        return func_num_args() ? $this->link('crmacct_taxauth_id', func_get_arg(0)) : $this->link('crmacct_taxauth_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Curr_rate.php b/DataObjects/Curr_rate.php
new file mode 100644 (file)
index 0000000..b857657
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Table Definition for curr_rate
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Curr_rate extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'curr_rate';           // table name
+    public $curr_rate_id;                    // int4(4)  not_null default_nextval%28curr_rate_curr_rate_id_seq%29 primary_key
+    public $curr_id;                         // int4(4)  not_null unique_key multiple_key
+    public $curr_rate;                       // numeric(-1)  not_null
+    public $curr_effective;                  // date(4)  not_null unique_key multiple_key
+    public $curr_expires;                    // date(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function id() {
+        return func_num_args() ? $this->link('curr_id', func_get_arg(0)) : $this->link('curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function initDatabase()
+    {
+        $c = DB_DataObject::Factory('curr_symbol');
+        foreach($c->fetchAll('curr_id', 'curr_name') as $id=>$name) {
+            $cr = DB_DataObject::Factory('curr_rate');
+            $cr->curr_id = $id;
+            if ($cr->count()) {
+                continue;
+            }
+            // we do not have arate .. create one..
+            $rate = $this->loadDefaultRate($name);
+            
+            $cr = DB_DataObject::Factory('curr_rate');
+            $cr->setFrom(array(
+                'curr_id'  => $id,
+                'curr_rate'  => $rate,
+                'curr_effective'  => '1970-01-01',
+                'curr_expires'  => '2100-01-01'
+                
+            ));
+            $cr->insert(); 
+            
+        }
+          
+    }
+    var $rates = array();
+    function loadRates()
+    {
+        
+        static $rates = false;
+        
+        if (!empty($rates)) {
+            return $rates;
+        }
+        $target = ini_get('session.save_path').'/eurofxref-daily.xml';
+        if (!file_exists($target) || filemtime($target) < (time() - 60*60*24)) {
+            $f = @file_get_contents('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
+            
+            if (!strlen($f)) {
+                // use our emergency copy..
+                die("can not get rates");
+                
+            } 
+            file_put_contents($target,$f);
+            
+        }
+        $rates = array();
+        $dom = simplexml_load_file($target);
+        $rates ['EUR'] = 1.0;
+        $rates ['TWD'] = 46.7008412;
+        $rates ['VND'] = 26405.3;
+        
+        
+       
+        foreach($dom->Cube->Cube->Cube as $c) {
+           //echo '<PRE>';print_r($c );
+            $rates [(string)$c['currency']] = (string)$c['rate'];
+        }
+        $rates ['RMB'] = $rates['CNY'] ;
+        return $rates;
+    }
+    function loadDefaultRate($from)
+    {
+        $cur= DB_DataObject::Factory('curr_symbol');
+        $cur = $cur->base();
+        $rates = $this->loadRates();
+        
+        $to = $cur->curr_name;
+        
+        //var_dump($from);var_dump($to);
+        
+        $rate = isset($rates[$from]) ? $rates[$from] : 1;
+        //echo '<PRE>';print_R($rates);
+        $base = (1.0 / $rate) * 1;
+  
+        return 1.0 / ($rates[$to] * $base);
+    
+    }
+    
+    
+    
+}
diff --git a/DataObjects/Curr_symbol.php b/DataObjects/Curr_symbol.php
new file mode 100644 (file)
index 0000000..36574de
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Table Definition for curr_symbol
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Curr_symbol extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'curr_symbol';         // table name
+    public $curr_id;                         // int4(4)  not_null default_nextval%28curr_symbol_curr_id_seq%29 primary_key
+    public $curr_base;                       // bool(1)  not_null default_false
+    public $curr_name;                       // varchar(-1)  not_null unique_key
+    public $curr_symbol;                     // varchar(-1)  not_null
+    public $curr_abbr;                       // varchar(-1)  not_null unique_key
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function base()
+    {
+        static $base = false;
+        if (!$base) {
+            $do = DB_DataObject::factory('curr_symbol');
+            $do->curr_base = true;
+            $do->find(true);
+            $base= $do;
+            
+        }
+        return $base;
+    }
+    
+    
+    function importFromArray($roo, $currencies)
+    {   
+        foreach ($currencies as $curr){
+            if(is_array($curr)){
+                $curr = $curr['name'];
+            }
+            $cs = DB_DataObject::Factory($this->tableName());
+            $cs->get('curr_abbr', $curr);
+            
+            $cs->setFrom(array(
+                'curr_base' => false,
+                'curr_name' => $curr,
+                'curr_symbol' => $curr,
+                'curr_abbr'=> $curr,  
+                
+            ));
+            $cs->curr_id ? $cs->update() : $cs->insert();
+            
+        }
+        
+    }
+    
+    function setBase($roo, $base)
+    {
+        $curr = DB_DataObject::factory('curr_symbol');
+        if(!$curr->get('curr_abbr', $base)){
+            $roo->jerr("Missing currency $base");
+        }
+        
+        $curr = DB_DataObject::Factory($this->tableName());
+        $curr->query('UPDATE curr_symbol SET curr_base = false');
+        $curr = DB_DataObject::Factory($this->tableName());
+        $curr->query("UPDATE curr_symbol SET curr_base = true WHERE curr_abbr='$base'");
+    }
+}
diff --git a/DataObjects/Cust.php b/DataObjects/Cust.php
new file mode 100644 (file)
index 0000000..1058573
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Table Definition for cust
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Cust extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'cust';                // table name
+    public $cust_id;                         // int4(4)  
+    public $cust_active;                     // bool(1)  
+    public $cust_custtype_id;                // int4(4)  
+    public $cust_salesrep_id;                // int4(4)  
+    public $cust_commprcnt;                  // numeric(-1)  
+    public $cust_name;                       // text(-1)  
+    public $cust_address1;                   // text(-1)  
+    public $cust_address2;                   // text(-1)  
+    public $cust_address3;                   // text(-1)  
+    public $cust_city;                       // text(-1)  
+    public $cust_state;                      // text(-1)  
+    public $cust_zipcode;                    // text(-1)  
+    public $cust_contact;                    // text(-1)  
+    public $cust_phone;                      // text(-1)  
+    public $cust_fax;                        // text(-1)  
+    public $cust_email;                      // text(-1)  
+    public $cust_corraddress1;               // text(-1)  
+    public $cust_corraddress2;               // text(-1)  
+    public $cust_corraddress3;               // text(-1)  
+    public $cust_corrcity;                   // text(-1)  
+    public $cust_corrstate;                  // text(-1)  
+    public $cust_corrzipcode;                // text(-1)  
+    public $cust_corrcontact;                // text(-1)  
+    public $cust_corrphone;                  // text(-1)  
+    public $cust_corrfax;                    // text(-1)  
+    public $cust_corremail;                  // text(-1)  
+    public $cust_creditlmt;                  // int4(4)  
+    public $cust_creditrating;               // text(-1)  
+    public $cust_financecharge;              // bool(1)  
+    public $cust_backorder;                  // bool(1)  
+    public $cust_partialship;                // bool(1)  
+    public $cust_terms_id;                   // int4(4)  
+    public $cust_discntprcnt;                // numeric(-1)  
+    public $cust_taxzone_id;                 // int4(4)  
+    public $cust_balmethod;                  // bpchar(-1)  
+    public $cust_ffshipto;                   // bool(1)  
+    public $cust_shipform_id;                // int4(4)  
+    public $cust_shipvia;                    // text(-1)  
+    public $cust_blanketpos;                 // bool(1)  
+    public $cust_shipchrg_id;                // int4(4)  
+    public $cust_creditstatus;               // bpchar(-1)  
+    public $cust_comments;                   // text(-1)  
+    public $cust_ffbillto;                   // bool(1)  
+    public $cust_country;                    // text(-1)  
+    public $cust_corrcountry;                // text(-1)  
+    public $cust_usespos;                    // bool(1)  
+    public $cust_number;                     // text(-1)  
+    public $cust_dateadded;                  // date(4)  
+    public $cust_exported;                   // bool(1)  
+    public $cust_emaildelivery;              // bool(1)  
+    public $cust_ediemail;                   // text(-1)  
+    public $cust_edisubject;                 // text(-1)  
+    public $cust_edifilename;                // text(-1)  
+    public $cust_ediemailbody;               // text(-1)  
+    public $cust_autoupdatestatus;           // bool(1)  
+    public $cust_autoholdorders;             // bool(1)  
+    public $cust_edicc;                      // text(-1)  
+    public $cust_ediprofile_id;              // int4(4)  
+    public $cust_preferred_warehous_id;      // int4(4)  
+    public $cust_curr_id;                    // int4(4)  
+    public $cust_creditlmt_curr_id;          // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Custform.php b/DataObjects/Custform.php
new file mode 100644 (file)
index 0000000..e2a6810
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for custform
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Custform extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'custform';            // table name
+    public $custform_id;                     // int4(4)  not_null default_nextval%28%28%22custform_custform_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $custform_custtype_id;            // int4(4)  
+    public $custform_custtype;               // text(-1)  
+    public $custform_invoice_report_id;      // int4(4)  
+    public $custform_creditmemo_report_id;    // int4(4)  
+    public $custform_quote_report_id;        // int4(4)  
+    public $custform_packinglist_report_id;    // int4(4)  
+    public $custform_statement_report_id;    // int4(4)  
+    public $custform_sopicklist_report_id;    // int4(4)  
+    public $custform_invoice_report_name;    // text(-1)  
+    public $custform_creditmemo_report_name;    // text(-1)  
+    public $custform_quote_report_name;      // text(-1)  
+    public $custform_packinglist_report_name;    // text(-1)  
+    public $custform_statement_report_name;    // text(-1)  
+    public $custform_sopicklist_report_name;    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Custgrp.php b/DataObjects/Custgrp.php
new file mode 100644 (file)
index 0000000..0f109cb
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for custgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Custgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'custgrp';             // table name
+    public $custgrp_id;                      // int4(4)  not_null default_nextval%28%28%22custgrp_custgrp_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $custgrp_name;                    // text(-1)  
+    public $custgrp_descrip;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Custgrpitem.php b/DataObjects/Custgrpitem.php
new file mode 100644 (file)
index 0000000..d656b62
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for custgrpitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Custgrpitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'custgrpitem';         // table name
+    public $custgrpitem_id;                  // int4(4)  not_null default_nextval%28%28%22custgrpitem_custgrpitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $custgrpitem_custgrp_id;          // int4(4)  
+    public $custgrpitem_cust_id;             // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Custinfo.php b/DataObjects/Custinfo.php
new file mode 100644 (file)
index 0000000..2c1261e
--- /dev/null
@@ -0,0 +1,968 @@
+<?php
+/**
+ * Table Definition for custinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Custinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'custinfo';            // table name
+    public $cust_id;                         // int4(4)  not_null default_nextval%28%28cust_cust_id_seq%29%3A%3Aregclass%29 primary_key
+    public $cust_active;                     // bool(1)  not_null
+    public $cust_custtype_id;                // int4(4)  
+    public $cust_salesrep_id;                // int4(4)  
+    public $cust_commprcnt;                  // numeric(-1)  
+    public $cust_name;                       // text(-1)  
+    public $cust_creditlmt;                  // int4(4)  
+    public $cust_creditrating;               // text(-1)  
+    public $cust_financecharge;              // bool(1)  
+    public $cust_backorder;                  // bool(1)  not_null
+    public $cust_partialship;                // bool(1)  not_null
+    public $cust_terms_id;                   // int4(4)  
+    public $cust_discntprcnt;                // numeric(-1)  not_null
+    public $cust_balmethod;                  // bpchar(-1)  not_null
+    public $cust_ffshipto;                   // bool(1)  not_null
+    public $cust_shipform_id;                // int4(4)  
+    public $cust_shipvia;                    // text(-1)  
+    public $cust_blanketpos;                 // bool(1)  not_null
+    public $cust_shipchrg_id;                // int4(4)  not_null
+    public $cust_creditstatus;               // bpchar(-1)  not_null
+    public $cust_comments;                   // text(-1)  
+    public $cust_ffbillto;                   // bool(1)  not_null
+    public $cust_usespos;                    // bool(1)  not_null
+    public $cust_number;                     // text(-1)  unique_key unique_key
+    public $cust_dateadded;                  // date(4)  default_%28now%29%3A%3Adate
+    public $cust_exported;                   // bool(1)  default_false
+    public $cust_emaildelivery;              // bool(1)  default_false
+    public $cust_ediemail;                   // text(-1)  
+    public $cust_edisubject;                 // text(-1)  
+    public $cust_edifilename;                // text(-1)  
+    public $cust_ediemailbody;               // text(-1)  
+    public $cust_autoupdatestatus;           // bool(1)  not_null
+    public $cust_autoholdorders;             // bool(1)  not_null
+    public $cust_edicc;                      // text(-1)  
+    public $cust_ediprofile_id;              // int4(4)  
+    public $cust_preferred_warehous_id;      // int4(4)  not_null default_%28-1%29
+    public $cust_curr_id;                    // int4(4)  default_basecurrid%28%29
+    public $cust_creditlmt_curr_id;          // int4(4)  default_basecurrid%28%29
+    public $cust_cntct_id;                   // int4(4)  
+    public $cust_corrcntct_id;               // int4(4)  
+    public $cust_soemaildelivery;            // bool(1)  default_false
+    public $cust_soediemail;                 // text(-1)  
+    public $cust_soedisubject;               // text(-1)  
+    public $cust_soedifilename;              // text(-1)  
+    public $cust_soediemailbody;             // text(-1)  
+    public $cust_soedicc;                    // text(-1)  
+    public $cust_soediprofile_id;            // int4(4)  
+    public $cust_gracedays;                  // int4(4)  
+    public $cust_ediemailhtml;               // bool(1)  not_null default_false
+    public $cust_soediemailhtml;             // bool(1)  not_null default_false
+    public $cust_taxzone_id;                 // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $cust_creditlmt_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function creditlmt_curr() {
+        return func_num_args() ? $this->link('cust_creditlmt_curr_id', func_get_arg(0)) : $this->link('cust_creditlmt_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('cust_curr_id', func_get_arg(0)) : $this->link('cust_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('cust_cntct_id', func_get_arg(0)) : $this->link('cust_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_corrcntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function corrcntct() {
+        return func_num_args() ? $this->link('cust_corrcntct_id', func_get_arg(0)) : $this->link('cust_corrcntct_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_custtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function custtype() {
+        return func_num_args() ? $this->link('cust_custtype_id', func_get_arg(0)) : $this->link('cust_custtype_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('cust_salesrep_id', func_get_arg(0)) : $this->link('cust_salesrep_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_shipform_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipform() {
+        return func_num_args() ? $this->link('cust_shipform_id', func_get_arg(0)) : $this->link('cust_shipform_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('cust_taxzone_id', func_get_arg(0)) : $this->link('cust_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $cust_terms_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function terms() {
+        return func_num_args() ? $this->link('cust_terms_id', func_get_arg(0)) : $this->link('cust_terms_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    public function crmacct() {
+        $c = DB_DataObject::factory('crmacct');
+        $c->get('crmacct_cust_id',  $this->cust_id);
+        return $c;
+    }
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if(isset($q['_filterTop'])){
+            $top = $this->filterTop();
+            $roo->jok($top);
+        }
+        
+        if (isset($q['_with_lastyear_total'])) {
+            
+            // this is the figure that displays next to the customer, the number of sales of selected brand if _with_lastyear total is not empty..
+            // it should be based on the selected brand.
+            $brandStr = '';
+            $groupStr = '';
+            if(!empty($q['_charass_brand_value'])){
+                $brand_ids = implode(',', DB_DataObject::factory('charass')->lookupIds('I', 'BRAND', $q['_charass_brand_value']));
+                $brandStr = "AND invcitem_item_id IN ({$brand_ids})";
+                
+            }
+            if(!empty($q['_charass_group_value'])){
+                $group_ids = implode(',', DB_DataObject::factory('charass')->lookupIds('I', 'PRODUCTGROUP', $q['_charass_group_value']));
+                $groupStr = "AND invcitem_item_id IN ({$group_ids})";
+            }
+            $this->selectAdd();
+            $this->selectAdd("
+                cust_id,
+                cust_name,
+                (SELECT 
+                        ROUND(COALESCE(SUM(invcitem_billed),0))
+                    FROM  
+                        invcitem 
+                    LEFT JOIN
+                        invchead 
+                    ON
+                        invcitem_invchead_id = invchead_id
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        invcitem_item_id = itemsite_item_id
+                    WHERE 
+                        invchead_cust_id = cust_id 
+                        AND
+                        extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
+                        AND 
+                        itemsite_stocked = TRUE
+                        $brandStr
+                        $groupStr  
+                ) as lastyear_total
+            ");
+            
+            $this->whereAddIn('cust_id', $this->filterTop(), 'int');
+            
+            $this->orderBy("lastyear_total DESC");
+        }
+        
+        if (isseT($_REQUEST['_report'])) {
+            $this->applyFiltersReport($roo, $_REQUEST['_report'], $_REQUEST['date_from'],$_REQUEST['date_to'] );
+            return $this->jerr("oops");
+        }
+        
+        if (!empty($q['search']['_country'])) {
+            $this->whereAdd("join_cust_addr_id.addr_country LIKE '{$this->escape($q['search']['_country'])}%'");
+        }
+        
+        if (!empty($q['query']['cust_name'])) {
+            $v = $this->escape($q['query']['cust_name']);
+            $this->whereAdd("cust_name ILIKE '%$v%' OR cust_number ILIKE '%$v%'");
+        }
+        if (!empty($q['search']['cust_name'])) {
+            $v = $this->escape($q['search']['cust_name']);
+            $this->whereAdd("cust_name ILIKE '%$v%' OR cust_number ILIKE '%$v%'");
+        }
+        if (!empty($q['query']['cust_name_begin'])) {
+            $v = $this->escape($q['query']['cust_name_begin']);
+            $this->whereAdd("cust_name ILIKE '$v%'");
+        }
+        
+        
+        
+        if (!empty($q['search']['orders_since'])) {
+            $dt = date('Y-m-d',  strtotime($q['search']['orders_since']));
+            $this->whereAdd("cust_id IN (SELECT cohead_cust_id FROM cohead where  cohead_orderdate > ' $dt')");
+        }
+        if (!empty($q['search']['no_orders_since'])) {
+            $dt = date('Y-m-d',  strtotime($q['search']['no_orders_since']));
+            $this->whereAdd("cust_id NOT IN (SELECT cohead_cust_id FROM cohead where  cohead_orderdate > ' $dt')");
+        }
+        
+        if (!empty($q['search']['with_orders_since'])) {
+            $this->selectAdd("(SELECT max(cohead_orderdate ) FROM cohead where  cohead_cust_id = cust_id) as last_order");
+        }
+        if (!empty($q['search']['with_address'])) {
+            $this->selectAddAddresses();
+        }
+        if (!empty($q['cust_active'])) {
+            $this->whereAdd('cust_id IN (SELECT distinct(aropen_cust_id) FROM aropen)');
+             
+        }
+        
+        if (!empty($q['_with_char'])) {
+            $ch = DB_DAtaObject::Factory('char');
+            $ch->char_customers = 1;
+            
+            if (!$ch->count() < 2) {
+                $ch->initDatabase();
+            }
+            $ch->find();
+            while ($ch->fetch()) {
+                $nm = 'cust_char_' . strtolower(preg_replace('/[^a-z]+/i','_', $ch->char_name));
+                
+                if (!empty($q[$nm])) {
+                    $this->whereAdd("
+                        charass_getvalue('C', cust_id, '{$ch->char_name}') = '{$this->escape($q[$nm])}'
+                    ");
+                }
+                
+                
+                $this->selectAdd("
+                    charass_getvalue('C', cust_id, '{$ch->char_name}') as $nm
+                ");
+                if (!empty($q['sort']) && $q['sort'] == $nm) {
+                    $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
+                    $this->orderBy("charass_getvalue('C', cust_id, '{$ch->char_name}') $dir");
+                }
+            }
+             
+        }
+        
+        if(isset($q['_with_group_data'])){
+            $this->autoJoinCoheadLastSale();
+        }
+        
+        if (!empty($q['sort']) && $q['sort'] == 'cntct_addr_country') {
+            $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
+            $this->orderBy(" cntct_addr_country $dir ");
+        }
+        
+        if (!empty($q['search']['with_balance'])) {
+            // this exclude cash receipts which have not been applied.
+            //DB_DataObject::DebugLevel(1);
+            $this->selectAdd("
+                (SELECT
+                    COALESCE(
+                        SUM(
+                           currtocurr(
+                                aropen_curr_id,
+                               cust_curr_id ,
+                                CASE WHEN (aropen_doctype IN ('C', 'R')) THEN
+                                        (aropen_amount - aropen_paid) * -1.0
+                                    ELSE
+                                        (aropen_amount - aropen_paid)
+                                    END,
+                                aropen_distdate
+                            )
+                        )
+                        ,0.0)
+                    FROM aropen
+                    WHERE
+                        aropen_cust_id = cust_id
+                        AND
+                        aropen_open
+                ) as balance
+            ");
+        
+        }
+        
+        
+        $l = DB_DataObject::factory('location')->defaultConfigLocation();
+        $this->selectAdd("
+            {$l->pid()} AS default_location_id,
+            '{$this->escape($l->location_name)}' AS default_location_name
+        ");
+        
+        $this->selectAdd(" 
+            (SELECT ipsass_ipshead_id FROM ipsass WHERE ipsass_cust_id = cust_id ORDER BY ipsass_id ASC LIMIT 1) as ipshead_id,
+            (SELECT ipshead_name FROM ipshead WHERE ipshead_id = 
+                (SELECT ipsass_ipshead_id FROM ipsass WHERE ipsass_cust_id = cust_id ORDER BY ipsass_id ASC LIMIT 1)
+            ) as ipshead_id_name
+        ");
+        
+        
+    }
+    
+    function autoJoinCoheadLastSale()
+    {
+        $this->_join .= "
+            LEFT JOIN
+                cohead AS join_cust_cohead_id
+            ON
+                join_cust_cohead_id.cohead_cust_id = cust_id
+                AND
+                join_cust_cohead_id.cohead_id = (SELECT cohead_id FROM cohead WHERE cohead_cust_id = cust_id ORDER BY cohead_orderdate DESC LIMIT 1)
+            ";
+
+        $add = DB_DataObject::Factory('cohead');
+        $this->selectAs($add, 'cust_%s', 'join_cust_cohead_id');
+    }
+    
+    function selectAddAddresses()
+    {   
+        // not sure where this is used. -- looks like only customertab..
+        //DB_DAtaObject::DebugLevel(1);
+        
+        $this->_join .= "
+            LEFT JOIN
+                addr   join_cust_addr_id
+                
+            ON
+                join_cust_addr_id.addr_id = join_cust_cntct_id_cntct_id.cntct_addr_id";
+        
+        $add = DB_DataObject::Factory('addr');
+        $this->selectAs($add, 'cntct_%s', 'join_cust_addr_id');
+        
+        return;
+         
+    }
+    function onUpdate($old,$req,$roo)
+    {
+        // update includes information on ship addresses.
+        
+        // we need to sync this up with shiptoinfo..
+        
+        if (isset($req['shiplist'])) {
+            $ar = explode(',', $req['shiplist']);
+            $this->updateShipList($ar);
+            
+        }
+        if (isset($req['ipshead_id'])) {
+            $this->updatePriceList($req['ipshead_id']);
+        }
+        
+        $this->updateCharass($req);
+    }
+    
+    function char($str) {
+        
+        $ca = DB_DAtaObject::factory('charass');
+        $ca->query("SELECT
+                charass_getvalue(
+                   'C',
+                   {$this->pid()},
+                   '".$this->escape($str). "'
+                ) as result");
+        $ca->fetch();
+        return empty($ca->result) ? '' : $ca->result;
+        
+    }
+    
+    function defaults()
+    {
+        $curr = DB_DataObject::factory('curr_symbol')->base();    
+        $ret = array(
+            'cust_custtype_id' =>  $this->sqlValue("fetchmetricvalue('DefaultCustType'::text)"),
+            'cust_salesrep_id'  =>  $this->sqlValue("fetchmetricvalue('DefaultSalesRep'::text)"),
+            'cust_commprcnt' => 0,
+            'cust_creditrating'  =>  $this->sqlValue("fetchmetrictext('SOCreditRate'::text)"),
+            'cust_active' => true,
+             
+            'cust_backorder' => true,  // must accept partial and backorder..
+            'cust_partialship' => true,
+            'cust_discntprcnt' => 0,
+            'cust_balmethod'  =>'B',
+            
+            'cust_ffshipto' => true, //  
+            'cust_shipform_id' => $this->sqlValue("fetchmetricvalue('DefaultShipFormId'::text)"),
+             
+            'cust_shipvia' => $this->sqlValue("fetchdefaultshipvia()"),
+            'cust_blanketpos' => false,
+            
+            'cust_shipchrg_id' => -1,
+            'cust_creditstatus' => 'G',
+            'cust_comments' => '',
+            'cust_ffbillto' => true,
+            
+            'cust_usespos' => false, // uses purchase orders'
+            
+            'cust_autoupdatestatus' => false,
+            'cust_autoholdorders' => false,
+            
+            //'cust_preferred_warehous_id' => -1, // default warehouse...
+            
+            //'cust_cntct_id' => -1, /// created later by 
+            //'cust_corrcntct_id' => -1,
+           // 'cust_taxzone_id' => 'taxzone_id',
+            'cust_gracedays' => 0,
+            'cust_terms_id' => $this->sqlValue("fetchmetricvalue('DefaultTerms'::text)"),
+            'cust_curr_id' =>   $curr->pid(),//// currency
+            'cust_creditlmt_curr_id' => $this->sqlValue("getcurrid('HKD'::text)"),/// currency again?
+           
+        );
+        return $ret;
+        
+        
+    }
+    function beforeInsert($req,$roo)
+    {
+        $defs = $this->defaults() ;
+        foreach($defs as $k=>$v) {
+            if (!isset($req[$k])) {
+                $this->$k = $v;
+            }
+            if (in_array($k, array( 'cust_creditlmt_curr_id', 'cust_curr_id')) && empty($r[$k])) {
+                $this->$k = $v;
+            }
+             
+        }
+        if ($this->cust_creditlmt_curr_id != $this->cust_curr_id) {
+            $this->cust_creditlmt_curr_id = $this->cust_curr_id;
+        }
+        if (empty($this->cust_cntct_id)) {
+            $this->cust_cntct_id = $this->sqlValue('NULL');
+        }
+        if($this->cust_number){
+            $this->custNumberDupeCheck($roo);
+        }
+    }
+    function beforeUpdate($old, $q, $roo)
+    {
+        if ($old->cust_curr_id != $this->cust_curr_id) {
+            $this->cust_creditlmt_curr_id = $this->cust_curr_id;
+        }
+        if (empty($this->cust_cntct_id)) {
+            $this->cust_cntct_id = $this->sqlValue('NULL');
+        }
+        if(isset($q['cust_number']) && $old->cust_number != $q['cust_number']) {
+            $this->custNumberDupeCheck($roo);
+        }
+    }
+    
+    
+    function onInsert($req,$roo)
+    {
+        // update includes information on ship addresses.
+        
+        // we need to sync this up with shiptoinfo..
+        $c = DB_DataObject::factory('custinfo');
+        $c->cust_name = $this->cust_name;
+        if($c->count() > 1){
+            $roo->jerr('Customer name already exists!');
+        }
+        $c = DB_DataObject::factory('custinfo');
+        $c->cust_number = $this->cust_number;
+        if($c->count() > 1){
+            $roo->jerr('Customer number already exists!');
+        }
+        
+        
+        if (isset($req['shiplist'])) {
+            $ar = explode(',', $req['shiplist']);
+            $this->updateShipList($ar);
+            
+        }
+        if (isset($req['ipshead_id'])) {
+            $this->updatePriceList($req['ipshead_id']);
+        }
+        
+        $this->updateCharass($req);
+
+    }
+    
+    function  findInternal($int_name, $cur)
+    {
+        
+        //DB_DataObject::DebugLevel(1);
+        $ve = $this->factory($this->tableName());
+        $ve->cust_curr_id = $cur->pid();
+        $ve->whereAdd(" charass_getvalue('C',
+                        cust_id,
+                        'INTERNALCOMPANY') = '{$this->escape($int_name)}'");
+        // fixme INTERNALCOMPANY must  be added to contacts
+        $matches = $ve->count();
+        if (!$matches || $matches > 1) {
+            return false;
+        }
+        $ve->find(true);
+        return $ve;
+    }
+    
+    
+    /**
+     * create or return the default contact..
+     * if none exists.. try and find one..
+     * @return Pman_Xtuple_DataObjects_Cntct the contact..
+     */ 
+    function defaultContact($order = false)
+    {
+        if ($this->cust_cntct_id) {
+            return $this->cntct();
+        }
+        if (empty($order)) { 
+            $order = array('ba', 'ca');
+        }
+        
+        
+        $crm = $this->crmacct();
+        $cnt = $this->cntct();
+        $cnt->cntct_crmacct_id = $crm->crmacct_id;
+        
+        // we could be smarter and look for 'default *'
+        
+        foreach($order as $pr) {
+            // prefer ba..
+            $c = clone($cnt);
+            $c->whereAdd("cntct_number' like '{$pr}-%'");
+            if ($cnt->count()) {
+                $cnt->find(true);
+                $old = clone($this);
+                $this->cust_cntct_id = $cnt->cntct_id;
+                $this->update($old);
+                return $cnt;
+            }
+        }
+        
+        $c = clone($cnt);
+        // finally anybody else..
+        if ($cnt->count()) {
+            $cnt->find(true);
+            $old = clone($this);
+            $this->cust_cntct_id = $cnt->cntct_id;
+            $this->update($old);
+            return $cnt;
+        }
+        //
+        $c = clone($cnt);
+        //create a dummy address..... = since there are no contacts that has to be created as well.
+        throw new Exception("no default contact");
+        /*
+        
+    public $cntct_addr_id;                   // int4(4)  
+    public $cntct_first_name;                // text(-1)  
+    public $cntct_last_name;                 // text(-1)  
+    public $cntct_honorific;                 // text(-1)  
+    public $cntct_initials;                  // text(-1)  
+    public $cntct_active;                    // bool(1)  default_true
+    public $cntct_phone;                     // text(-1)  
+    public $cntct_phone2;                    // text(-1)  
+    public $cntct_fax;                       // text(-1)  
+    public $cntct_email;                     // text(-1)  
+    public $cntct_webaddr;                   // text(-1)  
+    public $cntct_notes;                     // text(-1)  
+    public $cntct_title;                     // text(-1)  
+    public $cntct_number;                    // text(-1)  not_null unique_key
+    public $cntct_middle;                    // text(-1)  
+    public $cntct_suffix;                    // text(-1)  
+    public $cntct_owner_username;            // text(-1)  
+    public $cntct_name;     
+        */
+        
+        
+        
+        
+        
+        
+    }
+    
+    
+    function updateShipList($contacts)
+    {
+        // find all the current shipping contacts.
+        //DB_DataObject::debugLevel(1);
+        $sh = DB_DataObject::factory('shiptoinfo');
+        $sh->shipto_cust_id= $this->cust_id;
+        $sh->shipto_active = true;
+        $exist = $sh->fetchAll();
+        
+        
+        
+        // new contacts..
+        $c = DB_DataObject::factory('cntct');
+        $c->whereAddIn('cntct_id', $contacts,'int');
+        $cnts = $c->fetchAll();
+        
+        
+        // insert if not referenced...
+        $used = array();
+        
+        foreach($cnts as $c) {
+            
+            $sh = $c->shipto();
+            
+            
+            if (!$sh->shipto_id) {
+                // then a shipinfo does not exist..
+                $sh = DB_DataObject::factory('shiptoinfo');
+                $sh = $sh->createFromCustomerContact($this, $c);
+                $used[] = $sh->shipto_id;
+                continue;
+            }
+            // dumb postgres...
+            //if ($sh->shipto_active && $sh->shipto_active != 'f') {
+                
+               
+            //    $used[] = $sh->shipto_id;
+            //    continue;
+            //}
+            $ss = clone($sh);
+            $sh->shipto_active = true;
+            $sh->shipto_name =  $c->cntct_name;
+            $sh->update($ss);
+            $used[] = $sh->shipto_id;
+            
+            // skip... - updating..
+        }
+        
+        // look at exist, and see if we can delete unused items..
+        foreach($exist as $sh) {
+            if (in_array($sh->shipto_id, $used)) {
+                continue;
+            }
+            $ss = clone($sh);
+            $sh->shipto_active = false;
+            $sh->update($ss);
+            
+        }
+        
+        
+    }
+    function priceList()
+    {
+        
+        $p = DB_DataObject::Factory('ipsass');
+        $p->ipsass_cust_id = $this->pid();
+        $old = $p->fetchAll();
+        if (empty($old)) {
+            return false;
+        }
+        $ipsass = $old[0];
+        $ipshead = DB_DataObject::Factory('ipshead');
+        $ipshead->get($old[0]->ipsass_ipshead_id);
+        return $ipshead;
+    }
+    
+    
+    function updatePriceList($ipshead)
+    {
+        
+        if (empty($ipshead)) {
+            return false;
+        }
+        // get the current ones..
+        $p = DB_DataObject::Factory('ipsass');
+        $p->ipsass_cust_id = $this->pid();
+        $old = $p->fetchAll();
+        foreach($old as $o) {
+            if ($o->ipsass_ipshead_id != $ipshead) {
+                $o->delete();
+                continue;
+            }
+            return; // got it and no change.. // does not handle multiple..
+        }
+        $p = DB_DataObject::Factory('ipsass');
+        $p->ipsass_cust_id = $this->pid();
+        $p->ipsass_ipshead_id = $ipshead;
+        $p->insert();
+    }
+    
+    function postListFilter($ar, $au, $q)
+    {   
+        if(isset($q['_my_json'])){
+            if(!count($ar)){
+                return;
+            }
+            require_once 'pear/System.php';
+            $tmpdir  = System::mktemp("-d abitodocx");
+            $path = $tmpdir . '/Customers-' . $q['search']['_country'] . '-' . date('Y-m-d') . '.json';
+            header("Content-Disposition: attachment; filename=\"".basename($path)."\";" );
+            echo json_encode($ar);
+            exit;
+        }
+        if (isset($q['_with_lastyear_total'])) {
+            
+            $old_ar = $ar;
+            
+            $always_display = DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'always display');
+            
+            foreach ($old_ar as $k => $v){
+                if(in_array($v['cust_id'], $always_display)){ // put 'always display' cust into the top list
+                    unset($ar[$k]);
+                    array_unshift($ar, $old_ar[$k]);
+                }
+            }
+            
+            $all_total = $this->totalSales($q['_charass_brand_value'],$q['_charass_group_value']);
+            
+            $allcompanies = array(
+              'cust_id' => '-1',
+              'cust_name' => 'All Companies',
+              'lastyear_total' => $all_total,
+              'view_type' => 'All'
+            );
+            
+            if(count($ar) == 0){
+                array_unshift($ar,$allcompanies);
+                return $ar;
+            }
+            
+            $top_total = 0;
+            foreach ($ar as $a){
+                $top_total += $a['lastyear_total'];
+            }
+            
+            $line = array(
+                'cust_id' => '-2',
+                'cust_name' => '----------Others----------',
+                'lastyear_total' => $all_total - $top_total,
+                'view_type' => 'others'
+            );
+            array_push($ar, $line);
+            array_unshift($ar, $allcompanies);
+            
+            return $ar;
+        }
+        
+        if(isset($q['_with_group_data'])){
+            $new_ar = array();
+            foreach ($ar as $a){
+                $addBillAddress = array();
+                $addShipAddress = array();
+                
+                $cols = array('address1', 'address2', 'address3', 'city', 'state', 'country');
+                
+                foreach ($cols as $col){
+                    if($a['cust_cohead_billto' . $col] != ''){
+                        $addBillAddress[] = $a['cust_cohead_billto' . $col];
+                    }
+                    if($a['cust_cohead_shipto' . $col] != ''){
+                        $addShipAddress[] = $a['cust_cohead_shipto' . $col];
+                    }
+                }
+                $a['cust_bill_info'] = implode("\r\n", $addBillAddress);
+                $a['cust_ship_info'] = implode("\r\n", $addShipAddress);
+                $new_ar[] = $a;
+            }
+            return $new_ar;
+        }
+        
+        return $ar;
+    }
+    
+    function topCustomerIdsBySalesQty()
+    {
+        $c = DB_DataObject::factory('custinfo');
+        $c->selectAdd();
+        $c->selectAdd("
+            cust_id,
+            (SELECT 
+                    ROUND(COALESCE(SUM(invcitem_billed),0))
+                FROM  
+                    invcitem 
+                LEFT JOIN
+                    invchead 
+                ON
+                    invcitem_invchead_id = invchead_id 
+                LEFT JOIN
+                    itemsite
+                ON
+                    invcitem_item_id = itemsite_item_id
+                
+                WHERE 
+                    invchead_cust_id = cust_id 
+                    AND
+                    extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
+                    AND
+                    itemsite_stocked = TRUE
+                    
+            ) as lastyear_total
+        ");
+        $c->orderBy('lastyear_total DESC');
+        
+        $c->find();
+        $total = 0;
+        $total_sales = $this->totalSales();
+        $ids = array();
+        while($c->fetch()){
+            if($total > ceil($total_sales * 0.8)){
+                break;
+            }
+            $total += $c->lastyear_total;
+            $ids[] = $c->cust_id;
+        }
+        return $ids;
+    }
+    
+    function totalSales($brand = '', $group = '')
+    {
+        $ic = DB_DataObject::factory('invcitem');
+        $ic->autoJoin();
+        $ic->_join = "
+            LEFT JOIN
+                invchead 
+            ON
+                invcitem_invchead_id = invchead_id 
+            LEFT JOIN
+                itemsite
+            ON
+                invcitem_item_id = itemsite_item_id
+        ";
+        $ic->selectAdd();
+        $ic->selectAdd("
+            ROUND(COALESCE(SUM(invcitem_billed),0)) as total_sales
+        ");
+        $ic->whereAdd("
+            extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
+            AND
+            itemsite_stocked = TRUE
+        ");
+        if(!empty($brand)){
+            $brand_ids = DB_DataObject::factory('charass')->lookupIds('I', 'BRAND', $brand);
+            $ic->whereAddIn('invcitem_item_id', $brand_ids, 'int');
+        }
+        if(!empty($group)){
+            $group_ids = DB_DataObject::factory('charass')->lookupIds('I', 'PRODUCTGROUP', $group);
+            $ic->whereAddIn('invcitem_item_id', $group_ids, 'int');
+        }
+        $ic->find(true);
+        return $ic->total_sales;
+    }
+    
+    function custNumberDupeCheck($roo)
+    {
+        $custinfo = DB_DataObject::factory('custinfo');
+        if($this->cust_id){
+            $custinfo->cust_number = $this->cust_number;
+        }
+        $custinfo->whereAdd("
+            cust_number = '{$this->escape($this->cust_number)}'
+        ");
+        if($custinfo->count()){
+            $roo->jerr("Customer code {$this->cust_number} already exists!"); 
+        }
+    }
+    
+    function updateCharass($req)
+    {
+        if (isset($req['cust_char_internalcompany'])) {
+            // update the char...
+            $ca = DB_DAtaObject::factory('charass');
+            $ca->query("SELECT
+                    charass_setvalue(
+                       'C',{$this->pid()},
+                       'INTERNALCOMPANY', '{$this->escape($req['cust_char_internalcompany'])}'
+                    );");
+            
+            
+        }
+        if (isset($req['cust_char_salesforecast'])) {
+            // update the char...
+            $ca = DB_DAtaObject::factory('charass');
+            $ca->query("SELECT
+                    charass_setvalue(
+                       'C',{$this->pid()},
+                       'SALESFORECAST', '{$this->escape($req['cust_char_salesforecast'])}'
+                    );");
+            
+            
+        }
+        if (isset($req['cust_char_au_post_accno'])) {
+            // update the char...
+            $ca = DB_DAtaObject::factory('charass');
+            $ca->query("SELECT
+                    charass_setvalue(
+                       'C',{$this->pid()},
+                       'AU-POST-ACCNO', '{$this->escape($req['cust_char_au_post_accno'])}'
+                    );");
+            
+            
+        }
+    }
+    
+    function filterTop()
+    {
+        $top = $this->topCustomerIdsBySalesQty();
+        $top = array_merge($top , DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'always display'));
+        $top = array_diff($top , DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'hide'));
+        
+        return $top;
+        
+    }
+    
+    function priceListCurrency($roo)
+    {
+        $ipsass = DB_DataObject::Factory('ipsass'); 
+                
+        if (!$ipsass->get('ipsass_cust_id', $this->pid())){
+            $roo->jerr("Customer {$this->cust_name} does not have a pricelist associated with it.");
+        }
+        
+        $ipshead = DB_DataObject::factory('ipshead');
+        
+        if(!$ipshead->get($ipsass->ipsass_ipshead_id)){
+            $roo->jerr("Cound not find the pricelist for {$this->cust_name}");
+        }
+        
+        $curr = DB_DataObject::factory('curr_symbol');
+        if(!$curr->get($ipshead->ipshead_curr_id)){
+            $roo->jerr("Cound not find currency id : {$ipshead->ipshead_curr_id}");
+        }
+        
+        return $curr;
+    }
+    
+}
+
diff --git a/DataObjects/Custtype.php b/DataObjects/Custtype.php
new file mode 100644 (file)
index 0000000..5341aa2
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Table Definition for custtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Custtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'custtype';            // table name
+    public $custtype_id;                     // int4(4)  not_null default_nextval%28%28custtype_custtype_id_seq%29%3A%3Aregclass%29 primary_key
+    public $custtype_code;                   // text(-1)  not_null unique_key
+    public $custtype_descrip;                // text(-1)  not_null
+    public $custtype_char;                   // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    static $_defaults = array(
+            array(
+                'custtype_code' => 'NORMAL',
+                'custtype_descrip' => 'Normal Customer',
+                'custtype_char' => false,
+            ),
+            array(
+                'custtype_code' => 'INTERNALCOMPANY',
+                'custtype_descrip' => 'Internal Company',
+                'custtype_char' => false,
+            ), 
+            array(
+                'custtype_code' => 'ONLINE',
+                'custtype_descrip' => 'Online Customer',
+                'custtype_char' => false,
+            ),        
+    );
+    
+    
+    function initDatabase()
+    {
+        
+        foreach(self::$_defaults as $data) {
+            
+            $d = DB_DataObject::Factory('custtype');
+            $d->custtype_code = $data['custtype_code'];
+            if ($d->count()) {
+                continue;
+            }
+            $d = DB_DataObject::Factory('custtype');
+            $d->setFrom($data);
+            $d->insert();
+        }
+        
+    }
+    
+}
diff --git a/DataObjects/Dept.php b/DataObjects/Dept.php
new file mode 100644 (file)
index 0000000..239912d
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for dept
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Dept extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'dept';                // table name
+    public $dept_id;                         // int4(4)  not_null default_nextval%28dept_dept_id_seq%29 primary_key
+    public $dept_number;                     // text(-1)  not_null unique_key
+    public $dept_name;                       // text(-1)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Destination.php b/DataObjects/Destination.php
new file mode 100644 (file)
index 0000000..500f5ed
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for destination
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Destination extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'destination';         // table name
+    public $destination_id;                  // int4(4)  not_null default_nextval%28%28%22destination_destination_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $destination_name;                // text(-1)  
+    public $destination_city;                // text(-1)  
+    public $destination_state;               // text(-1)  
+    public $destination_comments;            // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Docass.php b/DataObjects/Docass.php
new file mode 100644 (file)
index 0000000..a3f61bd
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for docass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Docass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'docass';              // table name
+    public $docass_id;                       // int4(4)  not_null default_nextval%28docass_docass_id_seq%29 primary_key
+    public $docass_source_id;                // int4(4)  not_null
+    public $docass_source_type;              // text(-1)  not_null
+    public $docass_target_id;                // int4(4)  not_null
+    public $docass_target_type;              // text(-1)  not_null default_URL
+    public $docass_purpose;                  // bpchar(-1)  not_null default_S
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Docinfo.php b/DataObjects/Docinfo.php
new file mode 100644 (file)
index 0000000..471a6f3
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for docinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Docinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'docinfo';             // table name
+    public $id;                              // int4(4)  
+    public $target_number;                   // text(-1)  
+    public $target_type;                     // text(-1)  
+    public $target_id;                       // int4(4)  
+    public $source_type;                     // text(-1)  
+    public $source_id;                       // int4(4)  
+    public $name;                            // text(-1)  
+    public $description;                     // text(-1)  
+    public $purpose;                         // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Dragon_report.php b/DataObjects/Dragon_report.php
new file mode 100644 (file)
index 0000000..2a2bc3f
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Table Definition for empgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Dragon_report extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'dragon_report';              // table name
+    public $id;                       // int4(4)  not_null default_nextval%28empgrp_empgrp_id_seq%29 primary_key
+    public $name;                     // text(-1)  not_null unique_key
+    public $query;                  // text(-1)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function applyFilters($q, $au, $roo) 
+    {
+        if (!empty($q['query']['report'])) {
+            $this->runReport($roo, $q);
+        }
+        
+        $roo->jerr("not yet!");
+        
+    }
+    
+    
+    function runReport($roo,$q)
+    {
+        $args = $q['query'];
+        
+        if (empty($args['currency'])) {
+            $args['currency'] = DB_DAtaObject::factory('curr_symbol')->base()->curr_name;
+        }
+        //var_Dump($q);exit;
+       
+       
+        $cachekey = md5(json_encode(array(
+               'args' => $args,
+               'baseURL' =>$roo->baseURL
+                                        
+        )));
+        
+        if (empty($q['_debug'])) {
+            $roo->jdataCache($cachekey);
+        }
+        
+        $report = strtolower($args['report']);
+        $file = dirname(__FILE__).'/../sqlreports/'. $report. '.sql';
+        if (!file_exists($file)) {
+            $roo->jerr("no such file - ". $file);
+        }
+        $sql = file_get_contents($file);
+        if (!preg_match_all('/\$([a-z_]+)/i', $sql, $matches)) {
+           // $roo->jerr("NO arguments");
+        }
+        
+        $sql = preg_replace('/^\s*\-\-.*$/m','', $sql);
+        
+        $rep = array();
+        //echo '<PRE>';print_R($matches);
+        foreach($matches[0] as $i=> $m) {
+            $rep[$matches[1][$i]] = $m;
+        
+        }
+        
+        foreach($rep as $k=>$v) {
+            if (!isset($args[$k])) {
+                $roo->jerr("missing argument query[$k]");
+            }
+            
+            $sql = str_replace($v, is_numeric($args[$k]) ? $args[$k] : $this->escape($args[$k]), $sql );
+            
+            
+        }
+        // this is very succeptable to sql injections!!!!
+        // need a better condom...
+        //print_r($sql);
+        $do = $this->factory($this->tableName());
+        $do->query($sql);
+        $ret = array();
+        while($do->fetch()) {
+            $ret[] = $do->toArray('%s', true);
+        }
+        
+        $roo->jdata($ret,false,array(), $cachekey);
+        
+        
+        
+        
+        
+        
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Emp.php b/DataObjects/Emp.php
new file mode 100644 (file)
index 0000000..044bdf9
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Table Definition for emp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Emp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'emp';                 // table name
+    public $emp_id;                          // int4(4)  not_null default_nextval%28emp_emp_id_seq%29 primary_key
+    public $emp_code;                        // text(-1)  not_null unique_key
+    public $emp_number;                      // text(-1)  not_null unique_key
+    public $emp_active;                      // bool(1)  not_null default_true
+    public $emp_cntct_id;                    // int4(4)  
+    public $emp_warehous_id;                 // int4(4)  
+    public $emp_mgr_emp_id;                  // int4(4)  
+    public $emp_wage_type;                   // text(-1)  not_null
+    public $emp_wage;                        // numeric(-1)  
+    public $emp_wage_curr_id;                // int4(4)  default_basecurrid%28%29
+    public $emp_wage_period;                 // text(-1)  not_null
+    public $emp_dept_id;                     // int4(4)  
+    public $emp_shift_id;                    // int4(4)  
+    public $emp_notes;                       // text(-1)  
+    public $emp_image_id;                    // int4(4)  
+    public $emp_username;                    // text(-1)  
+    public $emp_extrate;                     // numeric(-1)  
+    public $emp_extrate_period;              // text(-1)  not_null
+    public $emp_startdate;                   // date(4)  default_%28now%29%3A%3Adate
+
+    
+   /**
+    * Getter / Setter for $emp_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('emp_cntct_id', func_get_arg(0)) : $this->link('emp_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_dept_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function dept() {
+        return func_num_args() ? $this->link('emp_dept_id', func_get_arg(0)) : $this->link('emp_dept_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_image_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function image() {
+        return func_num_args() ? $this->link('emp_image_id', func_get_arg(0)) : $this->link('emp_image_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_mgr_emp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function mgr_emp() {
+        return func_num_args() ? $this->link('emp_mgr_emp_id', func_get_arg(0)) : $this->link('emp_mgr_emp_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_shift_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shift() {
+        return func_num_args() ? $this->link('emp_shift_id', func_get_arg(0)) : $this->link('emp_shift_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_wage_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function wage_curr() {
+        return func_num_args() ? $this->link('emp_wage_curr_id', func_get_arg(0)) : $this->link('emp_wage_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $emp_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('emp_warehous_id', func_get_arg(0)) : $this->link('emp_warehous_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Empgrp.php b/DataObjects/Empgrp.php
new file mode 100644 (file)
index 0000000..33cc6eb
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for empgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Empgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'empgrp';              // table name
+    public $empgrp_id;                       // int4(4)  not_null default_nextval%28empgrp_empgrp_id_seq%29 primary_key
+    public $empgrp_name;                     // text(-1)  not_null unique_key
+    public $empgrp_descrip;                  // text(-1)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Empgrpitem.php b/DataObjects/Empgrpitem.php
new file mode 100644 (file)
index 0000000..0b7a633
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Table Definition for empgrpitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Empgrpitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'empgrpitem';          // table name
+    public $empgrpitem_id;                   // int4(4)  not_null default_nextval%28empgrpitem_empgrpitem_id_seq%29 primary_key
+    public $empgrpitem_empgrp_id;            // int4(4)  not_null
+    public $empgrpitem_emp_id;               // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $empgrpitem_emp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function emp() {
+        return func_num_args() ? $this->link('empgrpitem_emp_id', func_get_arg(0)) : $this->link('empgrpitem_emp_id');
+    }
+
+   /**
+    * Getter / Setter for $empgrpitem_empgrp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function empgrp() {
+        return func_num_args() ? $this->link('empgrpitem_empgrp_id', func_get_arg(0)) : $this->link('empgrpitem_empgrp_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Evntlog.php b/DataObjects/Evntlog.php
new file mode 100644 (file)
index 0000000..f8f5af3
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for evntlog
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Evntlog extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'evntlog';             // table name
+    public $evntlog_id;                      // int4(4)  not_null default_nextval%28%28evntlog_evntlog_id_seq%29%3A%3Aregclass%29 primary_key
+    public $evntlog_evnttime;                // timestamptz(8)  
+    public $evntlog_evnttype_id;             // int4(4)  
+    public $evntlog_ord_id;                  // int4(4)  
+    public $evntlog_dispatched;              // timestamptz(8)  
+    public $evntlog_action;                  // text(-1)  
+    public $evntlog_warehous_id;             // int4(4)  
+    public $evntlog_number;                  // text(-1)  
+    public $evntlog_newvalue;                // numeric(-1)  
+    public $evntlog_oldvalue;                // numeric(-1)  
+    public $evntlog_newdate;                 // date(4)  
+    public $evntlog_olddate;                 // date(4)  
+    public $evntlog_ordtype;                 // bpchar(-1)  
+    public $evntlog_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Evntnot.php b/DataObjects/Evntnot.php
new file mode 100644 (file)
index 0000000..83225ab
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for evntnot
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Evntnot extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'evntnot';             // table name
+    public $evntnot_id;                      // int4(4)  not_null default_nextval%28%28evntnot_evntnot_id_seq%29%3A%3Aregclass%29 primary_key
+    public $evntnot_evnttype_id;             // int4(4)  
+    public $evntnot_warehous_id;             // int4(4)  
+    public $evntnot_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Evnttype.php b/DataObjects/Evnttype.php
new file mode 100644 (file)
index 0000000..6659287
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for evnttype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Evnttype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'evnttype';            // table name
+    public $evnttype_id;                     // int4(4)  not_null default_nextval%28%28evnttype_evnttype_id_seq%29%3A%3Aregclass%29 primary_key
+    public $evnttype_name;                   // text(-1)  
+    public $evnttype_descrip;                // text(-1)  
+    public $evnttype_module;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Expcat.php b/DataObjects/Expcat.php
new file mode 100644 (file)
index 0000000..fd978f6
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Table Definition for expcat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Expcat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'expcat';              // table name
+    public $expcat_id;                       // int4(4)  not_null default_nextval%28expcat_expcat_id_seq%29 primary_key
+    public $expcat_code;                     // text(-1)  unique_key
+    public $expcat_descrip;                  // text(-1)  
+    public $expcat_exp_accnt_id;             // int4(4)  
+    public $expcat_liability_accnt_id;       // int4(4)  
+    public $expcat_active;                   // bool(1)  
+    public $expcat_purchprice_accnt_id;      // int4(4)  
+    public $expcat_freight_accnt_id;         // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function fromAccnt($roo, $accnt)
+    {
+        $sa = DB_DataObject::Factory('expcat');
+        if (!$sa->get('expcat_exp_accnt_id'   ,$accnt->pid())) {
+            
+            
+                $sa->setFrom(array(
+                
+                    'expcat_code' => $accnt->accnt_descrip,
+                    'expcat_descrip' => $accnt->accnt_descrip,
+                    
+                    'expcat_exp_accnt_id'      =>  $accnt->pid(),
+                    
+                     // these are all the system codes.
+                    'expcat_liability_accnt_id'  => 95,
+                    'expcat_active'              => true,
+                    'expcat_purchprice_accnt_id' => 126,
+                    'expcat_freight_accnt_id'    => 98,
+
+                    
+                ));
+                $sa->insert();
+            
+        }
+        return $sa;
+    }
+    function initDatabase($roo)
+    {
+        $acc = DB_DataObject::Factory('accnt');
+        $acc->accnt_subaccnttype_code = 'EXP';
+        $acc->find();
+        while ($acc->fetch()) {
+            $this->fromAccnt($roo, $acc);
+        }
+    }
+    
+    function autoGenerateFromAccounts($roo)
+    {
+        $this->initDatabase();
+        
+        
+       
+    }
+}
diff --git a/DataObjects/Expense.php b/DataObjects/Expense.php
new file mode 100644 (file)
index 0000000..5950809
--- /dev/null
@@ -0,0 +1,423 @@
+<?php
+/**
+ * Table Definition for expense
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Expense extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'expense';             // table name
+    public $expense_id;                      // int4(4)  not_null default_nextval%28%28expense_id_seq%29%3A%3Aregclass%29 primary_key
+    public $expense_accnt_id;                // int4(4)  
+    public $expense_emp_id;                  // int4(4)  not_null
+    public $expense_number;                  // text(-1)  not_null
+    public $expense_trandate;                // timestamptz(8)  
+    public $expense_created;                 // timestamptz(8)  
+    public $expense_modified;                // timestamptz(8)  
+    public $expense_duedate;                 // timestamptz(8)  
+    public $expense_memo;                    // text(-1)  
+    public $expense_status;                  // text(-1)  
+    public $expense_advance;                 // numeric(-1)  default_0.000
+    public $expense_amount;                  // numeric(-1)  default_0.000
+    public $expense_tax;                     // numeric(-1)  default_0.000
+    public $expense_total;                   // numeric(-1)  default_0.000
+    public $expense_posted;                   // numeric(-1)  default_0.000
+    public $expense_comments;                 
+
+    
+   /**
+    * Getter / Setter for $expense_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function accnt() {
+        return $this->link('expense_accnt_id', func_get_args());
+    }
+
+   /**
+    * Getter / Setter for $expense_emp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function emp() {
+        return $this->link('expense_emp_id', func_get_args());
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        // alway sapply perms.
+        
+        if (!$roo->hasPerm('Xtuple.ExpensesAll','S')) {
+            $au->cntct(); /// make sure an employee exists..
+            
+            $this->expense_emp_id = $au->emp()->pid();
+            
+            
+        }
+        
+        $this->selectAdd("
+            (SELECT curr_name from curr_symbol where curr_id = basecurrid() LIMIT 1 ) as base_curr_name,
+            basecurrid()  as base_curr_id,
+            
+            (select expcat_id from expcat where expcat_descrip = 'Expenses' LIMIT 1) as  def_expcat_id,
+            (select expcat_descrip from expcat where expcat_descrip = 'Expenses' LIMIT 1) as  def_expcat_descrip,
+            
+            expense_amount as expense_amount_ro,
+            expense_tax as expense_tax_ro,
+            expense_total as expense_total_ro  
+            
+        ");
+        
+        if (!empty($q['_asExcel'])) {
+          //  DB_DataObject::debugLevel(1);
+            $this->expense_id = $q['expense_id'];
+            $this->find(true);
+            $this->toExcel($roo);
+        }
+        
+        
+        
+    }
+    function defaults() {
+        return array(
+            'expense_status' => 'Draft'
+        );
+    
+    }
+    function beforeInsert($request,$roo)
+    {
+        if (empty($this->expense_accnt_id)) {
+            $this->expense_accnt_id = $this->sqlValue('NULL');
+        }
+        // only needed on insert..
+        if (empty($this->expense_emp_id)) {
+            $this->expense_emp_id = $roo->authUser->emp()->pid();
+        }
+        foreach($this->defaults() as $k=>$v) {
+            if (empty($this->$k)) {
+                $this->$k = $v;
+            }
+        }
+    }
+    
+    
+    function onInsert()
+    {
+        $this->expense_number = "EXP-".strtoupper(substr($this->database(), -2)) . '-'. $this->pid() ;
+        $t = DB_DataObject::Factory('expense');
+        $t->query("UPDATE expense SET  expense_number = '{$this->expense_number}'
+                    WHERE expense_id = {$this->pid()}"
+        );
+        
+        
+    }
+    
+    function beforeUpdate($old, $request,$roo)
+    {
+        
+      
+        
+        if (empty($this->expense_accnt_id)) {
+            $this->expense_accnt_id = $this->sqlValue('NULL');
+        }
+        
+        
+        
+        if ($this->expense_posted) {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        if ($this->expense_status =='Paid In Full') {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        
+        
+    }
+    function onUpdate($old,$q, $roo)
+    {
+        
+        if (!empty($q['_post'])) {
+            $this->post($roo);
+        }
+        
+    }
+    
+    
+    function items()
+    {
+        $ci = DB_DataObject::factory('expitem');
+        $ci->autoJoin();
+        $ci->expitem_expense_id  = $this->pid();
+        $ci->orderBy('expitem_row ASC');
+        //$ci->applyFilters(array(  ), $roo->authUser, $roo);
+        return $ci->fetchAll();
+    }
+    
+    
+    function beforeDelete($dependants_array, $roo)
+    {
+        if ($this->expense_posted) {
+            $roo->jerr("you can not delete a posted expense");
+        }
+        
+        if ($this->expense_status =='Paid In Full') {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        
+        /// delete depenedants... 
+        if (strlen($this->expense_status ) && $this->expense_status != 'Draft') {
+            $roo->jerr("you can only delete draft expense reports");
+        }
+        // in theory check perms... - but not implemented...
+        
+        $ei = $this->items();
+        foreach($ei as $i) {
+            $i->delete();
+        }
+        return true;
+        
+        
+    }
+    
+    
+    function post($roo)
+    {
+        
+        if ($this->expense_status != 'Pending Accounting Approval') {
+            $roo->jerr("expenses are not pending approval by accounts");
+        }
+        
+        $xx = DB_DataObject::Factory('expense');
+        $xx->get($this->pid());
+        
+        // validate data...
+        if (empty($xx->expense_accnt_id)) {
+            $roo->jerr("no bank specified");
+        }
+        $items= $this->items() ;
+        // next... verify that the rows have accounts.
+        
+        $tot = 0.0;
+        foreach($items as $i) {
+            if (empty($i->expitem_expcat_id)) {
+                $roo->jerr("one of the lines is missing an expense category.");
+            }
+            
+            if (empty($i->expitem_memo)) {
+                $roo->jerr("one of the lines is missing a description.");
+            }
+            $tot = bcadd($tot, round($i->expitem_total,2), 2);
+           
+        }
+        
+        
+        $cur  = DB_DAtaObject::Factory('curr_symbol');
+        $base_cur = $cur->base();
+      
+        // finally try and post the thing..
+        
+        $cn = $base_cur->curr_name;
+        $vi = DB_DataObject::Factory('vendinfo');
+        $vi->vend_number = "STAFF-{$cn}";
+        if (!$vi->find(true)) {
+            $roo->jerr("An vendor account 'STAFF-{$cn}' does not exist");
+        }
+
+         
+        $taxtype  = DB_DataObject::Factory('taxtype');
+        $taxtype->get('taxtype_name', 'Taxable');
+          
+          
+        // verify that tax zone is correct.
+        
+        $taxzone = DB_DataObject::Factory('taxzone'); // we use vend info..
+        $taxzone->get('taxzone_code', 'NO TAX');
+        if ($taxzone->pid() == $vi->vend_taxzone_id && $this->expense_tax > 0.0) {
+            $roo->jerr("change the taxzone of the vendor 'STAFF-{$cn}' to not tax free ");
+        }
+       
+        $vohead = DB_DataObject::Factory('vohead');
+        $vohead ->query('SELECT fetchVoNumber() AS vouchernumber');
+        $vohead->fetch();
+        $vn = $vohead->vouchernumber;
+        
+        $vohead = DB_DataObject::Factory('vohead');
+            
+        $vohead->setFrom($vohead->defaults());
+        
+        $vohead->setFrom(array(
+            
+            
+            'vohead_number'=>  $vn ,
+            'vohead_invcnumber' => $this->expense_number,
+            'vohead_docdate'=>  $this->expense_trandate,
+            'vohead_distdate'=> $this->expense_trandate,
+            'vohead_duedate'=>  $this->expense_trandate,
+            
+            'vohead_amount'=>   $tot,
+            'vohead_terms_id'=> $vi->vend_terms_id,
+            'vohead_notes'=>    'Created from expense report',
+            'vohead_curr_id'=>  $base_cur->pid(),
+            //'vohead_pohead_id' => $po->pohead_id,
+            'vohead_vend_id' => $vi->pid(),
+            'vohead_taxtype_id'=> $taxtype->pid(),
+            'vohead_taxzone_id'=>$vi->vend_taxzone_id,
+            //'vohead_misc'=> 0
+                
+            
+            
+        ));
+        //$roo->jerr("total : $tot");
+        //$roo->jerr(print_R($this,true));
+        
+        $vohead->insert();
+           
+        
+        foreach($items as $i) {
+            $vodist = DB_DataObject::Factory('vodist');
+
+            $vodist->createFromExpItem($roo, $vohead, $i);
+        }
+        //$roo->jerr(print_r($vohead->distitems(),true));
+        
+        
+        if ($this->expense_tax > 0.0) {
+            $vodist = DB_DataObject::Factory('vodist');
+            $vodist->createFromExpTax($roo, $vohead, $this->expense_tax);
+        }
+        $vd = DB_DataObject::Factory('vodist');
+        $vd->query("SELECT postVoucher({$vohead->pid()},
+                    fetchJournalNumber('AP-VO'), TRUE) AS result");
+        $vd->fetch();
+        if (!$vd->result || $vd->result < 0) {
+            $roo->jerr("postVoucher() return $vd->result");
+        }
+        $old = clone($xx);
+        $xx->expense_posted = 1;
+        $xx->expense_status = 'Paid In Full';
+        $xx->update($old);
+        
+        $roo->jok("POSTED");
+        
+    }
+    
+    
+    function toExcel($roo)
+    {
+        
+         
+        //$ci->applyFilters(array(  ), $roo->authUser, $roo);
+        $data  = $this->items();
+        
+        $endrow = 11 + count($data);
+        
+        //echo '<PRE>';print_r($data);
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        //print_R($this);exit;
+        
+       $x = new Pman_Core_SimpleExcel(
+            $data,
+                                      
+            array(
+           'formats' => array(
+                'left' => array('Align'=>'left'),
+                'money' => array('NumFormat' => '$#,##0.00;[RED]-$#,##0.00'),
+                'date' => array('NumFormat' => 'D/M/YYYY', 'Align'=>'left'),
+                'header' => array('Size' => 16,  'Bold' => 1)
+            ),
+            'workbook' => 'Expense Report' . $this->expense_number, 
+            'head'  => array(
+                array("","","","","","", array("Expense Report", 'header')),
+                array("","","","", "","","Ref#", $this->expense_number),
+                array("","","","", "","","Employee:", $this->expense_emp_id_emp_name),
+                array("","","","", "","","Due:", array( Pman_Core_SimpleExcel::date($this->expense_trandate),'date')),
+                array("","","","", "","","Status:", $this->expense_status),
+                array("Summary:", $this->expense_memo),
+                array(),
+                array(),
+            ),
+            
+            
+            'cols' =>  array(
+                array( 
+                    'dataIndex' => 'expitem_row',
+                    'header'  => 'Line#',
+                    'width'  => 75,
+                    'format' => 'left',
+                ),
+                array(
+                    'header' => 'Date',
+                    'width' => 75,
+                    'dataIndex' => 'expitem_date',
+                    'format' => 'date'
+                ),
+                array(
+                 'dataIndex' => 'expitem_expcat_id_expcat_descrip',
+                                'header' => 'Category',
+                                'width' => 100,
+                ),
+                array(
+                 'dataIndex' => 'expitem_memo',
+                                'header' => 'Description',
+                                'width' =>150,
+                                
+                ),
+                array(
+                 'dataIndex' => 'expitem_curr_id_curr_name',
+                                'header' => 'Currency',
+                                'width' =>75,
+                                
+                ),
+                
+                array(
+                            'header' => 'Amount',
+                            'width' => 75,
+                            'dataIndex' => 'expitem_amount_fc',
+                            'format' => 'money' 
+                ),
+                array(
+                            'header' => 'Tax',
+                            'width' => 75,
+                            'dataIndex' => 'expitem_tax',
+                            'format' => 'money' 
+                ),array(
+                            'header' => 'Total (in base currency)',
+                            'width' => 75,
+                            'dataIndex' => 'expitem_total',
+                            'format' => 'money' 
+                ),
+                
+                 
+                
+            ),
+            'foot' => array(
+                array(),
+                 array("","","","","","", "Total", array(
+                        "=SUM(H11:H{$endrow})",
+                        "money"
+                )),
+                
+            )
+        ));     
+            
+        $x->send($this->expense_number.'-'.date('Y-m-d').'.xls');   
+            
+        
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Expitem.php b/DataObjects/Expitem.php
new file mode 100644 (file)
index 0000000..560426c
--- /dev/null
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Table Definition for expitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Expitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'expitem';             // table name
+    public $expitem_id;                      // int4(4)  not_null default_nextval%28%28expitem_id_seq%29%3A%3Aregclass%29 primary_key
+    public $expitem_expense_id;              // int4(4)  not_null
+    public $expitem_curr_id;                 // int4(4)  not_null
+    public $expitem_expcat_id;               // int4(4)  not_null
+    public $expitem_row;                     // int4(4)  not_null
+    public $expitem_amount;                  // numeric(-1)  default_0.000
+    public $expitem_amount_fc;               // numeric(-1)  default_0.000
+    public $expitem_tax;                     // numeric(-1)  default_0.000
+    public $expitem_total;                   // numeric(-1)  default_0.000
+    public $expitem_date;                    // timestamptz(8)  
+    public $expitem_is_billable;             // int4(4)  default_0
+    public $expitem_memo;                    // text(-1)  default_
+
+    
+   /**
+    * Getter / Setter for $expitem_expense_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function expense() {
+        return $this->link('expitem_expense_id', func_get_args());
+    }
+
+   /**
+    * Getter / Setter for $expitem_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return $this->link('expitem_curr_id', func_get_args());
+    }
+
+   /**
+    * Getter / Setter for $expitem_expcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function expcat() {
+        return $this->link('expitem_expcat_id', func_get_args());
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function beforeInsert($request,$roo)
+    {
+        if (!$this->expitem_expense_id) {
+            $roo->jerr("no expense set - system error");
+        }
+        $exp = $this->expense();
+        if ($exp->expense_posted || $exp->expense_status == 'Paid In Full') {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        // user can only edit it if it's draft.
+        if ($exp->expense_status != 'Draft' && !$roo->authUser->hasPerm('Xtuple.ExpensesAll', 'S')) {
+            $roo->jerr("you can not modify an expense line unless it is status draft - ask for managment to reject the expense report.");
+        }
+        
+        
+        if (empty($this->expitem_expcat_id)) {
+            $this->expitem_expcat_id = $this->sqlValue('NULL');
+        }
+        $this->updateTotalLine();
+        
+        
+    }
+    function beforeUpdate($old, $request,$roo)
+    {
+        $exp = $this->expense();
+        if ($exp ->expense_posted || $exp->expense_status == 'Paid In Full') {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        if ($exp->expense_status != 'Draft' && !$roo->authUser->hasPerm('Xtuple.ExpensesAll', 'S')) {
+            $roo->jerr("you can not modify an expense line unless it is status draft - ask for managment to reject the expense report.");
+        }
+        
+        
+        if (empty($this->expitem_expcat_id)) {
+            $this->expitem_expcat_id = $this->sqlValue('NULL');
+        } 
+        $this->updateTotalLine();
+    }
+    
+    function updateTotalLine()
+    {
+        
+        if (empty($this->expitem_date)) {
+            return;
+        }
+        // ?? could this use pure sql, rather than values??
+        // use the total, rather than this..
+        
+        $this->expitem_total = $this->sqlValue("
+                ROUND(currtobase({$this->expitem_curr_id}, {$this->expitem_amount_fc} + {$this->expitem_tax}, '{$this->expitem_date}'),2)
+        ");
+        
+    }
+    
+    function onInsert()
+    {
+        $this->updateTotals();
+    }
+    function onUpdate()
+    {
+        $this->updateTotals();
+    }
+    
+    function updateTotals()
+    {
+        $t = DB_DataObject::Factory('expense');
+        $t->query("
+            UPDATE
+                expense
+            SET
+                expense_amount = (SELECT  sum( expitem_total -  currtobase(expitem_curr_id,expitem_tax, expitem_date )) FROM expitem where expitem_expense_id = {$this->expitem_expense_id}),
+                expense_tax = (SELECT sum(currtobase(expitem_curr_id,expitem_tax, expitem_date )) FROM expitem where expitem_expense_id = {$this->expitem_expense_id}),
+                expense_total = (SELECT sum( expitem_total ) FROM expitem where expitem_expense_id = {$this->expitem_expense_id})
+            WHERE
+                expense_id = {$this->expitem_expense_id}
+        ");
+        
+         
+    }
+    function beforeDelete($dependants_array, $roo)
+    {
+        
+        $exp = $this->expense();
+        if ($exp ->expense_posted || $exp->expense_status == 'Paid In Full') {
+            $roo->jerr("you can not modify a posted expense");
+        }
+        if ($exp->expense_status != 'Draft' && !$roo->authUser->hasPerm('Xtuple.ExpensesAll', 'S')) {
+            $roo->jerr("you can not modify an expense line unless it is status draft - ask for managment to reject the expense report.");
+        }
+        
+        
+        
+        /// delete depenedants... 
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Filter.php b/DataObjects/Filter.php
new file mode 100644 (file)
index 0000000..79640a8
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for filter
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Filter extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'filter';              // table name
+    public $filter_id;                       // int4(4)  not_null default_nextval%28filter_filter_id_seq%29 primary_key
+    public $filter_screen;                   // text(-1)  not_null multiple_key
+    public $filter_value;                    // text(-1)  not_null
+    public $filter_username;                 // text(-1)  multiple_key
+    public $filter_name;                     // text(-1)  not_null multiple_key
+    public $filter_selected;                 // bool(1)  default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Flaccnt.php b/DataObjects/Flaccnt.php
new file mode 100644 (file)
index 0000000..06a0edd
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Table Definition for flaccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flaccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flaccnt';             // table name
+    public $flhead_type;                     // bpchar(-1)  
+    public $flitem_id;                       // int4(4)  
+    public $flitem_flhead_id;                // int4(4)  
+    public $flitem_flgrp_id;                 // int4(4)  
+    public $flitem_order;                    // int4(4)  
+    public $flitem_accnt_id;                 // int4(4)  
+    public $flitem_showstart;                // bool(1)  
+    public $flitem_showend;                  // bool(1)  
+    public $flitem_showdelta;                // bool(1)  
+    public $flitem_showbudget;               // bool(1)  
+    public $flitem_subtract;                 // bool(1)  
+    public $flitem_showstartprcnt;           // bool(1)  
+    public $flitem_showendprcnt;             // bool(1)  
+    public $flitem_showdeltaprcnt;           // bool(1)  
+    public $flitem_showbudgetprcnt;          // bool(1)  
+    public $flitem_prcnt_flgrp_id;           // int4(4)  
+    public $flitem_showdiff;                 // bool(1)  
+    public $flitem_showdiffprcnt;            // bool(1)  
+    public $flitem_showcustom;               // bool(1)  
+    public $flitem_showcustomprcnt;          // bool(1)  
+    public $flitem_custom_source;            // bpchar(-1)  
+    public $flitem_company;                  // text(-1)  
+    public $flitem_profit;                   // text(-1)  
+    public $flitem_number;                   // text(-1)  
+    public $flitem_sub;                      // text(-1)  
+    public $flitem_type;                     // bpchar(-1)  
+    public $flitem_subaccnttype_code;        // text(-1)  
+    public $accnt_id;                        // int4(4)  
+    public $accnt_type;                      // bpchar(-1)  
+    public $accnt_company;                   // text(-1)  
+    public $accnt_profit;                    // text(-1)  
+    public $accnt_number;                    // text(-1)  
+    public $accnt_sub;                       // text(-1)  
+    public $prj_id;                          // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Flcol.php b/DataObjects/Flcol.php
new file mode 100644 (file)
index 0000000..3bb19fc
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for flcol
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flcol extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flcol';               // table name
+    public $flcol_id;                        // int4(4)  not_null default_nextval%28flcol_flcol_id_seq%29 primary_key
+    public $flcol_flhead_id;                 // int4(4)  not_null
+    public $flcol_name;                      // text(-1)  
+    public $flcol_descrip;                   // text(-1)  
+    public $flcol_report_id;                 // int4(4)  
+    public $flcol_month;                     // bool(1)  
+    public $flcol_quarter;                   // bool(1)  
+    public $flcol_year;                      // bool(1)  
+    public $flcol_showdb;                    // bool(1)  
+    public $flcol_prcnt;                     // bool(1)  
+    public $flcol_priortype;                 // bpchar(-1)  
+    public $flcol_priormonth;                // bool(1)  
+    public $flcol_priorquarter;              // bool(1)  
+    public $flcol_prioryear;                 // bpchar(-1)  
+    public $flcol_priorprcnt;                // bool(1)  
+    public $flcol_priordiff;                 // bool(1)  
+    public $flcol_priordiffprcnt;            // bool(1)  
+    public $flcol_budget;                    // bool(1)  
+    public $flcol_budgetprcnt;               // bool(1)  
+    public $flcol_budgetdiff;                // bool(1)  
+    public $flcol_budgetdiffprcnt;           // bool(1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function report()
+    {
+        $report = DB_DataObject::factory('report');
+        $report->get($this->flcol_report_id);
+        return $report;
+    }
+}
diff --git a/DataObjects/Flgrp.php b/DataObjects/Flgrp.php
new file mode 100644 (file)
index 0000000..fc061b8
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Table Definition for flgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flgrp';               // table name
+    public $flgrp_id;                        // int4(4)  not_null default_nextval%28flgrp_flgrp_id_seq%29 primary_key
+    public $flgrp_flhead_id;                 // int4(4)  
+    public $flgrp_flgrp_id;                  // int4(4)  
+    public $flgrp_order;                     // int4(4)  
+    public $flgrp_name;                      // text(-1)  
+    public $flgrp_descrip;                   // text(-1)  
+    public $flgrp_subtotal;                  // bool(1)  not_null default_false
+    public $flgrp_summarize;                 // bool(1)  not_null default_false
+    public $flgrp_subtract;                  // bool(1)  not_null default_false
+    public $flgrp_showstart;                 // bool(1)  not_null default_true
+    public $flgrp_showend;                   // bool(1)  not_null default_true
+    public $flgrp_showdelta;                 // bool(1)  not_null default_true
+    public $flgrp_showbudget;                // bool(1)  not_null default_true
+    public $flgrp_showstartprcnt;            // bool(1)  not_null default_false
+    public $flgrp_showendprcnt;              // bool(1)  not_null default_false
+    public $flgrp_showdeltaprcnt;            // bool(1)  not_null default_false
+    public $flgrp_showbudgetprcnt;           // bool(1)  not_null default_false
+    public $flgrp_prcnt_flgrp_id;            // int4(4)  not_null default_%28-1%29
+    public $flgrp_showdiff;                  // bool(1)  not_null default_false
+    public $flgrp_showdiffprcnt;             // bool(1)  not_null default_false
+    public $flgrp_showcustom;                // bool(1)  not_null default_false
+    public $flgrp_showcustomprcnt;           // bool(1)  not_null default_false
+    public $flgrp_usealtsubtotal;            // bool(1)  not_null default_false
+    public $flgrp_altsubtotal;               // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function items()
+    {
+        $x = DB_DataObject::Factory('flitem');
+        $x->flitem_flgrp_id = $this->pid();
+        $x->orderBy('flitem_order ASC');
+        return $x->fetchAll();
+    }
+    
+    function groupAsArrays()
+    {
+        $groups = array();
+        $flgrp = DB_DataObject::factory('flgrp');
+        $flgrp->flgrp_flgrp_id = $this->pid();
+        $flgrp->find();
+        while ($flgrp->fetch()){
+            $groups[$flgrp->flgrp_name] = $flgrp->toArray();
+            $groups[$flgrp->flgrp_name]['groups'] = $flgrp->groupAsArrays();
+            $groups[$flgrp->flgrp_name]['items'] = $flgrp->itemsAsArrays();
+        }
+        return $groups;
+    }
+    
+    function itemsAsArrays()
+    {
+        $items = array();
+        $flitem = DB_DataObject::factory('flitem');
+        $flitem->flitem_flhead_id = $this->flgrp_flhead_id;
+        $flitem->flitem_flgrp_id = $this->pid();
+        $flitem->find();
+        while ($flitem->fetch()){
+            if($flitem->flitem_accnt_id > 0){
+                HTML_FlexyFramework::get()->page->jerr('item accnt id is set');
+            }
+            $items[$flitem->pid()] = $flitem->toArray();
+        }
+        return $items;
+    }
+}
diff --git a/DataObjects/Flhead.php b/DataObjects/Flhead.php
new file mode 100644 (file)
index 0000000..f72fc47
--- /dev/null
@@ -0,0 +1,288 @@
+<?php
+/**
+ * Table Definition for flhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flhead';              // table name
+    public $flhead_id;                       // int4(4)  not_null default_nextval%28flhead_flhead_id_seq%29 primary_key
+    public $flhead_name;                     // text(-1)  unique_key
+    public $flhead_descrip;                  // text(-1)  
+    public $flhead_showtotal;                // bool(1)  not_null default_false
+    public $flhead_showstart;                // bool(1)  not_null default_true
+    public $flhead_showend;                  // bool(1)  not_null default_true
+    public $flhead_showdelta;                // bool(1)  not_null default_true
+    public $flhead_showbudget;               // bool(1)  not_null default_true
+    public $flhead_showdiff;                 // bool(1)  not_null default_false
+    public $flhead_showcustom;               // bool(1)  not_null default_false
+    public $flhead_custom_label;             // text(-1)  
+    public $flhead_usealttotal;              // bool(1)  not_null default_false
+    public $flhead_alttotal;                 // text(-1)  
+    public $flhead_usealtbegin;              // bool(1)  not_null default_false
+    public $flhead_altbegin;                 // text(-1)  
+    public $flhead_usealtend;                // bool(1)  not_null default_false
+    public $flhead_altend;                   // text(-1)  
+    public $flhead_usealtdebits;             // bool(1)  not_null default_false
+    public $flhead_altdebits;                // text(-1)  
+    public $flhead_usealtcredits;            // bool(1)  not_null default_false
+    public $flhead_altcredits;               // text(-1)  
+    public $flhead_usealtbudget;             // bool(1)  not_null default_false
+    public $flhead_altbudget;                // text(-1)  
+    public $flhead_usealtdiff;               // bool(1)  not_null default_false
+    public $flhead_altdiff;                  // text(-1)  
+    public $flhead_type;                     // bpchar(-1)  not_null default_A
+    public $flhead_active;                   // bool(1)  not_null default_true
+    public $flhead_sys;                      // bool(1)  default_false
+    public $flhead_notes;                    // text(-1)  default_
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        //var_dump($q['period']);
+        if (!empty($q['mperiod'])) {
+            $this->runManualReport($roo, $q);
+        }
+        if (!empty($q['period'])) {
+            return $this->runReport($roo, $q);
+        }
+        if (!empty($q['_tree'])) {
+            $this->asTree($roo, $q);
+        }
+    }
+    
+    function toRooArray($q)
+    {   
+        if (!empty($q['_to_json'])) {
+            return $this->toJsonTree();
+        }
+        return $this->toArray();
+    }
+    
+    
+    function runReport($roo, $q)
+    {
+        $g = DB_DataObject::Factory('groups');
+        // use dashboard perms..
+        if (!$roo->authUser->hasPerm('Xtuple.Dashboard','S')) {
+            $roo->jerr("You do not have Dashboard View permissions.");
+        }
+        $head = $this->factory('flhead');
+        if (empty($q['flhead_name']) || !$head->get('flhead_name', $q['flhead_name'])) {
+            $q['flhead_name'] = isset($q['flhead_name']) ? $q['flhead_name'] : 'flhead_name=NOT SET';
+            $roo->jerr("no report named '{$q['flhead_name']}' exists");
+        }
+        if (empty($q['interval'])) {
+            $roo->jerr("no interval set");
+        }
+        if (empty($q['period'])) {
+            $roo->jerr("no period set");
+        }
+        $ar = explode(',', $q['period']);
+        $periods=  array();
+        foreach($ar as $dt) {
+            $pp = DB_DataObject::Factory('period');
+            if (!$pp->get('period_start' ,  date('Y-m-d', strtotime($dt)))) {
+                $roo->jerr("no period for " .  date('Y-m-d', strtotime($dt)));
+            }
+            $periods[] = $pp->pid();
+        }
+        
+        
+        
+        //if (!preg_match('/hk$/', $this->database()) && empty($q['no_timewarp'])) {
+        if (preg_match('/(sg|au)$/', $this->database()) && empty($q['no_timewarp'])) {
+            $rpt = $this->factory('flhead');
+            $rpt->query("SET search_path TO timewarp,public");
+        }
+        // remove old reports..
+        // current user is fake (as we chuser at some point..)... but php always runs report as admin.
+        $rpt = $this->factory('flhead');
+        $rpt->query("  DELETE FROM flrpt WHERE ((flrpt_username='admin') AND (flrpt_flhead_id={$head->pid()}))");
+         
+        
+        $rpt = $this->factory('flhead');
+        
+        $rpt->query("
+            SELECT * FROM financialReport({$head->pid()} , ARRAY[ " . implode(',', $periods) .  "] ,
+            '" . $this->escape($q['interval']) . "' , true,  NULL )
+        ") ;
+        $ret = array();
+        while ($rpt->fetch()) {
+            $ret[] = $rpt->toArray('%s', true);
+        }
+        
+        if (!empty($q['_return_result'])) {
+            return $ret;
+        }
+        
+        $roo->jdata($ret);
+         
+    }
+    
+    function asTree($roo,$q)
+    {
+        $ret = array();
+        $ret[] = array(
+            'id' => 99999,
+            'text' => 'Dashboard',
+            'leaf' => true,
+        );
+        $flhead = $this->factory($this->tableName());
+        $flhead->orderBy('flhead_name ASC');
+        $flhead->whereAdd("flhead_name  != ''");
+        $ff = clone($flhead);
+        
+        $flhead->whereAdd("flhead_name  like 'DRAGON%'");
+        $res = $flhead->fetchAll('flhead_id','flhead_name');
+        if (empty($res)) {
+            $res = $ff->fetchAll('flhead_id','flhead_name');
+        }
+        
+        foreach($res as $k=>$v) {
+            $ret[] = array(
+                'id' => $k,
+                'text' => $v,
+                'leaf' => true
+            );
+        }
+        $roo->jdata($ret);
+        
+        
+    }
+    
+    function groups()
+    {
+        $x = DB_DataObject::Factory('flgrp');
+        $x->flgrp_flhead_id = $this->pid();
+        $x->orderBy('flgrp_order ASC');
+        return $x->fetchAll();
+    }
+    
+    function items()
+    {
+        $x = DB_DataObject::Factory('flitem');
+        $x->flitem_flhead_id = $this->pid();
+        $x->orderBy('flitem_order ASC');
+        return $x->fetchAll();
+    }
+    /*
+    function runManualReport($roo, $q)
+    {
+        $g = DB_DataObject::Factory('groups');
+        if (!$g->get('name', 'Administrators') ) {
+            $roo->jerr('no admin group?');
+        }
+        if (!in_array($roo->authUser->id , $g->memberIds())) {
+            $roo->jerr("Administrators only");
+        }
+        $head = $this->factory('flhead');
+        if (empty($q['flhead_name']) || !$head->get('flhead_name', $q['flhead_name'])) {
+            $q['flhead_name'] = isset($q['flhead_name']) ? $q['flhead_name'] : 'flhead_name=NOT SET';
+            $roo->jerr("no report named '{$q['flhead_name']}' exists");
+        }
+        if (empty($q['interval'])) {
+            $roo->jerr("no interval set");
+        }
+        $interval = $q['interval'];
+        if (empty($q['period'])) {
+            $roo->jerr("no period set");
+        }
+        
+        
+        
+        $rperiods = explode(',', $q['period']);
+        foreach($rperiods as $dt) {
+        
+            $edt = date('Y-m-d', strtotime($dt .  (($interval == 'Y') ? ' + 1 YEAR' : ' + 1 MONTH)')));
+            // what's the period  in
+            $startp = DB_DataObject::factory('period');
+            $startp->get('period_start',$dt);
+            $endp = DB_DataObject::factory('period');
+            $endp->get('period_start', $edt);
+            
+            
+            
+            echo '<PRE>';
+            print_R($head);
+            $gs = $head->groups();
+            foreach($gs as $gi) {
+                print_R($gi);
+                $is = $gi->items();
+                foreach($is as $i) {
+                    $i->runReport($startp->pid(), $endp->pid());
+                }
+                print_R($is);
+            }
+        }    
+        
+        exit;
+        
+       
+       
+        $periods=  array();
+        foreach($ar as $dt) {
+            $pp = DB_DataObject::Factory('period');
+            if (!$pp->get('period_start' ,  date('Y-m-d', strtotime($dt)))) {
+                $roo->jerr("no period for " .  date('Y-m-d', strtotime($dt)));
+            }
+            $periods[] = $pp->pid();
+        }
+        
+        
+        
+        
+        $rpt = $this->factory('flhead');
+        $rpt->query("
+            SELECT * FROM financialReport({$head->pid()} , ARRAY[ " . implode(',', $periods) .  "] ,
+            '" . $this->escape($q['interval']) . "' , true,  NULL )
+        ") ;
+        $ret = array();
+        while ($rpt->fetch()) {
+            $ret[] = $rpt->toArray('%s', true);
+        }
+        $roo->jdata($ret);
+        
+         
+        
+    }
+    */
+    
+    function toJsonTree()
+    {
+        $ret =  $this->toArray();
+        // loop through sub depence
+        //$ret['items'] = ...
+        $groups = array();
+        $flgrp = DB_DataObject::factory('flgrp');
+        $flgrp->flgrp_flhead_id = $this->pid();
+        $flgrp->whereAdd('flgrp_flgrp_id < 0');
+        $flgrp->find();
+        while ($flgrp->fetch()){
+            $groups[$flgrp->flgrp_name] = $flgrp->toArray();
+            $groups[$flgrp->flgrp_name]['groups'] = $flgrp->groupAsArrays();
+            $groups[$flgrp->flgrp_name]['items'] = $flgrp->itemsAsArrays();
+        }
+        
+        $ret['groups'] = $groups;
+        
+        $cols = array();
+        $flcol = DB_DataObject::factory('flcol');
+        $flcol->flcol_flhead_id = $this->pid();
+        $flcol->find();
+        while ($flcol->fetch()){
+            $cols[$flcol->pid()] = $flcol->toArray();
+            $cols[$flcol->pid()]['report'] = $flcol->report()->toArray();
+        }
+        $ret['col'] = $cols;
+        
+        HTML_FlexyFramework::get()->page->jok($ret);
+    }
+    
+}
diff --git a/DataObjects/Flitem.php b/DataObjects/Flitem.php
new file mode 100644 (file)
index 0000000..4e3c6d3
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for flitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flitem';              // table name
+    public $flitem_id;                       // int4(4)  not_null default_nextval%28flitem_flitem_id_seq%29 primary_key
+    public $flitem_flhead_id;                // int4(4)  
+    public $flitem_flgrp_id;                 // int4(4)  
+    public $flitem_order;                    // int4(4)  
+    public $flitem_accnt_id;                 // int4(4)  
+    public $flitem_showstart;                // bool(1)  
+    public $flitem_showend;                  // bool(1)  
+    public $flitem_showdelta;                // bool(1)  
+    public $flitem_showbudget;               // bool(1)  not_null default_false
+    public $flitem_subtract;                 // bool(1)  not_null default_false
+    public $flitem_showstartprcnt;           // bool(1)  not_null default_false
+    public $flitem_showendprcnt;             // bool(1)  not_null default_false
+    public $flitem_showdeltaprcnt;           // bool(1)  not_null default_false
+    public $flitem_showbudgetprcnt;          // bool(1)  not_null default_false
+    public $flitem_prcnt_flgrp_id;           // int4(4)  not_null default_%28-1%29
+    public $flitem_showdiff;                 // bool(1)  not_null default_false
+    public $flitem_showdiffprcnt;            // bool(1)  not_null default_false
+    public $flitem_showcustom;               // bool(1)  not_null default_false
+    public $flitem_showcustomprcnt;          // bool(1)  not_null default_false
+    public $flitem_custom_source;            // bpchar(-1)  
+    public $flitem_company;                  // text(-1)  
+    public $flitem_profit;                   // text(-1)  
+    public $flitem_number;                   // text(-1)  
+    public $flitem_sub;                      // text(-1)  
+    public $flitem_type;                     // bpchar(-1)  
+    public $flitem_subaccnttype_code;        // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Flnotes.php b/DataObjects/Flnotes.php
new file mode 100644 (file)
index 0000000..c0bb7f2
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for flnotes
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flnotes extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flnotes';             // table name
+    public $flnotes_id;                      // int4(4)  not_null default_nextval%28flnotes_flnotes_id_seq%29
+    public $flnotes_flhead_id;               // int4(4)  unique_key multiple_key
+    public $flnotes_period_id;               // int4(4)  unique_key multiple_key
+    public $flnotes_notes;                   // text(-1)  default_
+
+    
+   /**
+    * Getter / Setter for $flnotes_flhead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function flhead() {
+        return func_num_args() ? $this->link('flnotes_flhead_id', func_get_arg(0)) : $this->link('flnotes_flhead_id');
+    }
+
+   /**
+    * Getter / Setter for $flnotes_period_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function period() {
+        return func_num_args() ? $this->link('flnotes_period_id', func_get_arg(0)) : $this->link('flnotes_period_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Flrpt.php b/DataObjects/Flrpt.php
new file mode 100644 (file)
index 0000000..2e6e337
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for flrpt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flrpt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flrpt';               // table name
+    public $flrpt_flhead_id;                 // int4(4)  not_null
+    public $flrpt_period_id;                 // int4(4)  not_null
+    public $flrpt_username;                  // text(-1)  not_null
+    public $flrpt_order;                     // int4(4)  not_null
+    public $flrpt_level;                     // int4(4)  not_null
+    public $flrpt_type;                      // text(-1)  not_null
+    public $flrpt_type_id;                   // int4(4)  not_null
+    public $flrpt_beginning;                 // numeric(-1)  
+    public $flrpt_ending;                    // numeric(-1)  
+    public $flrpt_debits;                    // numeric(-1)  
+    public $flrpt_credits;                   // numeric(-1)  
+    public $flrpt_budget;                    // numeric(-1)  
+    public $flrpt_beginningprcnt;            // numeric(-1)  
+    public $flrpt_endingprcnt;               // numeric(-1)  
+    public $flrpt_debitsprcnt;               // numeric(-1)  
+    public $flrpt_creditsprcnt;              // numeric(-1)  
+    public $flrpt_budgetprcnt;               // numeric(-1)  
+    public $flrpt_parent_id;                 // int4(4)  
+    public $flrpt_diff;                      // numeric(-1)  
+    public $flrpt_diffprcnt;                 // numeric(-1)  
+    public $flrpt_custom;                    // numeric(-1)  
+    public $flrpt_customprcnt;               // numeric(-1)  
+    public $flrpt_altname;                   // text(-1)  
+    public $flrpt_accnt_id;                  // int4(4)  
+    public $flrpt_interval;                  // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Flspec.php b/DataObjects/Flspec.php
new file mode 100644 (file)
index 0000000..2a95e9c
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Table Definition for flspec
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Flspec extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'flspec';              // table name
+    public $flspec_id;                       // int4(4)  not_null default_nextval%28flspec_flspec_id_seq%29 primary_key
+    public $flspec_flhead_id;                // int4(4)  not_null
+    public $flspec_flgrp_id;                 // int4(4)  not_null
+    public $flspec_order;                    // int4(4)  not_null
+    public $flspec_name;                     // text(-1)  
+    public $flspec_type;                     // text(-1)  
+    public $flspec_showstart;                // bool(1)  not_null default_true
+    public $flspec_showend;                  // bool(1)  not_null default_true
+    public $flspec_showdelta;                // bool(1)  not_null default_true
+    public $flspec_showbudget;               // bool(1)  not_null default_false
+    public $flspec_subtract;                 // bool(1)  not_null default_false
+    public $flspec_showstartprcnt;           // bool(1)  not_null default_false
+    public $flspec_showendprcnt;             // bool(1)  not_null default_false
+    public $flspec_showdeltaprcnt;           // bool(1)  not_null default_false
+    public $flspec_showbudgetprcnt;          // bool(1)  not_null default_false
+    public $flspec_showdiff;                 // bool(1)  not_null default_false
+    public $flspec_showdiffprcnt;            // bool(1)  not_null default_false
+    public $flspec_prcnt_flgrp_id;           // int4(4)  not_null default_%28-1%29
+    public $flspec_showcustom;               // bool(1)  not_null default_false
+    public $flspec_showcustomprcnt;          // bool(1)  not_null default_false
+    public $flspec_custom_source;            // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Form.php b/DataObjects/Form.php
new file mode 100644 (file)
index 0000000..6161bd6
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for form
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Form extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'form';                // table name
+    public $form_id;                         // int4(4)  not_null default_nextval%28%28%22form_form_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $form_name;                       // text(-1)  
+    public $form_descrip;                    // text(-1)  
+    public $form_report_id;                  // int4(4)  
+    public $form_key;                        // varchar(-1)  
+    public $form_report_name;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Freightclass.php b/DataObjects/Freightclass.php
new file mode 100644 (file)
index 0000000..57ca57c
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for freightclass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Freightclass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'freightclass';        // table name
+    public $freightclass_id;                 // int4(4)  not_null default_nextval%28freightclass_freightclass_id_seq%29 primary_key
+    public $freightclass_code;               // text(-1)  not_null unique_key
+    public $freightclass_descrip;            // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Glseries.php b/DataObjects/Glseries.php
new file mode 100644 (file)
index 0000000..9a660f6
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for glseries
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Glseries extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'glseries';            // table name
+    public $glseries_id;                     // int4(4)  not_null default_nextval%28%28%22glseries_glseries_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $glseries_sequence;               // int4(4)  
+    public $glseries_doctype;                // bpchar(-1)  
+    public $glseries_docnumber;              // text(-1)  
+    public $glseries_accnt_id;               // int4(4)  
+    public $glseries_amount;                 // numeric(-1)  
+    public $glseries_source;                 // text(-1)  
+    public $glseries_distdate;               // date(4)  
+    public $glseries_notes;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Gltrans.php b/DataObjects/Gltrans.php
new file mode 100644 (file)
index 0000000..142ef49
--- /dev/null
@@ -0,0 +1,739 @@
+<?php
+/**
+ * Table Definition for gltrans
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Gltrans extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'gltrans';             // table name
+    public $gltrans_id;                      // int4(4)  not_null default_nextval%28%28%22gltrans_gltrans_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $gltrans_exported;                // bool(1)  
+    public $gltrans_created;                 // timestamptz(8)  
+    public $gltrans_date;                    // date(4)  not_null
+    public $gltrans_sequence;                // int4(4)  
+    public $gltrans_accnt_id;                // int4(4)  not_null
+    public $gltrans_source;                  // text(-1)  
+    public $gltrans_docnumber;               // text(-1)  
+    public $gltrans_misc_id;                 // int4(4)  
+    public $gltrans_amount;                  // numeric(-1)  not_null
+    public $gltrans_notes;                   // text(-1)  
+    public $gltrans_journalnumber;           // int4(4)  
+    public $gltrans_posted;                  // bool(1)  not_null
+    public $gltrans_doctype;                 // text(-1)  
+    public $gltrans_rec;                     // bool(1)  not_null default_false
+    public $gltrans_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $gltrans_deleted;                 // bool(1)  default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['cohead_id'])) {
+             $this->coheadView($q,$roo);
+            return;
+            
+        }
+        
+        if(!empty($q['_poview'])){
+            $this->poheadView($q,$roo);
+            return;
+        }
+        
+        if (isset($q['_with_credit_debit'])) {
+            //$this->whereAdd("gltrans_date > '2010-01-01'");
+            $acc = DB_DataObject::Factory('accnt');
+            $acc->get($q['gltrans_accnt_id']);
+            $mul  = $acc->multiplier();
+            
+            
+            $this->gltrans_initial_rate  = false;   
+            
+            $this->gltrans_base_balance = 0;
+            $this->gltrans_cur_balance = 0;
+            
+            $gl = DB_DataObject::Factory('gltrans');
+            $gl->gltrans_accnt_id = $q['gltrans_accnt_id'];
+            $gl->gltrans_deleted  = false;
+            if ($gl->count() > 9000) {
+                if (!isset($q['_as_of'])) {
+                    $roo->jerr("To much data, as of date is needed.");
+                }
+                 
+                
+                // if we pick as of.. then go back 1 year from that date..
+                $dt = date('Y-m-d', strtotime($q['_as_of'] . ' - 6 MONTH'));
+                $this->_start_date = $dt;
+                $this->whereAdd("gltrans_date > '$dt'");
+                
+                $gl = DB_DataObject::Factory('gltrans');
+                //DB_DataObject::DebugLevel(1);
+                $gl->selectAdd();
+                $gl->selectAdd("
+                    COALESCE(sum(ROUND(gltrans_amount * $mul,2)), 0.0) as gltrans_base_balance,
+                    COALESCE(currtocurr(
+                        baseCurrId(),
+                        {$acc->accnt_curr_id} , 
+                       COALESCE(sum(ROUND(gltrans_amount * $mul,2)), 0.0) ,
+                       ('$dt'::date - INTERVAL '1 DAY')::date
+                    ),0.0) as gltrans_cur_balance
+                ");
+                $gl->gltrans_accnt_id = $q['gltrans_accnt_id'];
+                $gl->gltrans_deleted  = false;
+                $gl->whereAdd("gltrans_date <= '$dt'");
+                $gl->find(true);
+                //exit;
+                $this->gltrans_base_balance = $gl->gltrans_base_balance ;
+                $this->gltrans_cur_balance = $gl->gltrans_cur_balance ;
+                
+                $gl = DB_DataObject::Factory('gltrans');
+                $gl->gltrans_deleted  = false;
+                $gl->query("
+                           SELECT 
+                                1 / currtobase({$acc->accnt_curr_id},1.0,('$dt'::date - INTERVAL '1 DAY')::date)
+                            as gltrans_curr_rate
+                ");
+                $gl->fetch();
+                
+                $this->gltrans_initial_rate = $gl->gltrans_curr_rate;
+                
+            }
+            
+            // how many transactions - limited to 
+            
+            
+            $this->gltrans_deleted  = false;
+            $this->selectAdd("
+                currtocurr(
+                    baseCurrId(),
+                    {$acc->accnt_curr_id}, 
+                             
+                             
+                    CASE WHEN gltrans_amount * $mul > 0 THEN
+                        gltrans_amount * $mul
+                    ELSE
+                        0
+                    END,
+                    gltrans_date
+                )  AS gltrans_amount_credit,
+                currtocurr(
+                    baseCurrId(),
+                    {$acc->accnt_curr_id} , 
+               
+                    CASE WHEN  gltrans_amount * $mul  < 0 THEN
+                        gltrans_amount * $mul
+                    ELSE
+                        0
+                    END,
+                   gltrans_date
+                )  
+                AS gltrans_amount_debit,
+                
+                CASE WHEN  gltrans_amount * $mul  > 0 THEN
+                    gltrans_amount * $mul
+                ELSE
+                    0
+                END as gltrans_base_credit,
+                
+                CASE WHEN  gltrans_amount * $mul  < 0 THEN
+                    gltrans_amount * $mul
+                ELSE
+                    0
+                END as gltrans_base_debit,
+                
+                 gltrans_amount * $mul as gltrans_base_normal,
+                 
+                currtocurr(
+                    baseCurrId(),
+                    {$acc->accnt_curr_id}, 
+               
+                    gltrans_amount * $mul ,
+                    gltrans_date
+                )   as gltrans_amount_normal,
+                
+                
+                1 / currtobase({$acc->accnt_curr_id},1.0,gltrans_date) as gltrans_curr_rate
+
+            ");
+            
+        }
+        
+        
+        if(isset($q['_as_of'])){
+            $dt = date('Y-m-d', strtotime($q['_as_of'] ));
+            $this->whereAdd("gltrans_date <= '{$dt}'");
+            $this->orderBy('gltrans_date DESC');
+        }
+        
+        if(!empty($q['_download'])){
+            $this->toExcel($q, $roo);
+        }
+        
+        
+    }
+    
+    
+    function  postListFilter($data, $authUser, $q) //return $data - add extra data to an object
+    {
+        $ret = $this->toArray();
+        
+        if (isset($q['_migrate_check'])) {
+            
+            require_once 'Pman/Xtuple/VerifyAccounts.php';
+            
+            $x = new Pman_Xtuple_VerifyAccounts();
+            $data = $x->addEndOfDay(
+                    $q['gltrans_accnt_id'], $data,
+                    $this->gltrans_base_balance,
+                    $this->gltrans_cur_balance,
+                    $this->gltrans_initial_rate
+                );
+            
+        }
+       
+        return $data;
+        
+    }
+    /**
+     *  simpel je.
+     *
+     *    array(
+            date
+            memo
+            notes,
+            array(
+                ...
+                array(
+                    accnt_id,
+                    amount
+                )
+            )
+     )
+     *
+     *
+     *
+     */
+    function newJournalEntry($roo, $r)
+    {
+        
+        $gl = DB_DataObject::Factory('gltrans');
+        
+        
+        // check if we already have this...
+        if ($gl->get('gltrans_docnumber', $r['memo'] . '-1')) {
+            return $gl->gltrans_sequence;
+        }
+        
+        
+        
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("SELECT fetchGLSequence() as result");
+        $gl->fetch();
+        $seq = $gl->result;
+        
+        foreach($r['lines'] as $i=>$l) {
+            $gl = DB_DataObject::Factory('gltrans');
+            $gl->query("
+                SELECT      insertIntoGLSeries(
+                            $seq,
+                            'G/L',
+                            'JE',
+                            '". $this->escape($r['memo'].'-'.($i+1)) ."',
+                            {$l['accnt_id']}, 
+                            {$l['amount']},
+                            '{$r['date']}'::date) AS result");
+            $gl->fetch();
+            if ($gl->result < 1) {
+                $roo->jerr("failed");
+            }
+        }
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("
+        
+            UPDATE glseries
+                    SET glseries_notes = '". $this->escape($r['notes']) ."' 
+                    
+                WHERE (glseries_sequence={$seq})
+                
+        ");
+        
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("
+                SELECT postGLSeriesNoSumm($seq,COALESCE(NULL,fetchJournalNumber('G/L'))) AS result
+        ");
+        $gl->fetch();
+        if ($gl->result < 1) {
+            $roo->jerr("failed");
+        }
+        foreach($r['lines'] as $l) {
+            $gl = DB_DataObject::Factory('gltrans');
+            $gl->query("
+                    SELECT forwardupdateaccount({$l['accnt_id']}) AS result
+            ");
+            
+        }
+        
+        return $seq;
+    }
+    
+    function coheadView($q, $roo)
+    {
+        if (!empty($q['gltrans_accnt_id'])) {
+            return $this->coheadViewDetail($q,$roo);
+        }
+        
+        $cohead_id =(int) $q['cohead_id'];
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        
+        $this->joinAddAccnt();
+        $this->selectAdd();
+
+        
+        if (empty($q['_split_sales'])) {
+             $this->selectAdd("
+                gltrans_accnt_id,
+                join_gltrans_accnt_id_id.accnt_descrip  AS gltrans_accnt_id_accnt_descrip ,
+                -1   AS gltrans_is_ship 
+                    
+            ");
+            
+             
+        } else {
+              
+            $this->selectAdd("
+                gltrans_accnt_id,
+                CASE WHEN gltrans_notes LIKE 'Ship Order%' OR  gltrans_notes LIKE 'Recall Ship%'  THEN
+                        join_gltrans_accnt_id_id.accnt_descrip || ' (Ship)'
+                    ELSE
+                        join_gltrans_accnt_id_id.accnt_descrip 
+                    END
+                    AS gltrans_accnt_id_accnt_descrip ,
+                    
+                CASE WHEN gltrans_notes LIKE 'Ship Order%' OR  gltrans_notes LIKE 'Recall Ship%'  THEN
+                        1
+                    ELSE
+                        0
+                    END
+                    AS gltrans_is_ship 
+                    
+            ");
+            
+        }
+      
+        $this->selectAdd("  
+            COALESCE(SUM(
+                    CASE WHEN gltrans_amount > 0 AND gltrans_posted THEN gltrans_amount ELSE 0 END
+                    ),0) as   gltrans_amount_credit,
+            
+            COALESCE(SUM(
+                    CASE WHEN gltrans_amount < 0 AND gltrans_posted THEN gltrans_amount ELSE 0 END
+                    ),0) as   gltrans_amount_debit,
+            
+            COALESCE(SUM(
+                    CASE WHEN gltrans_posted THEN gltrans_amount ELSE 0 END
+                    ),0) as   gltrans_amount_total,
+            
+            COALESCE(SUM(
+                    CASE WHEN gltrans_posted OR  gltrans_deleted THEN 0 ELSE gltrans_amount  END
+                    ),0) as   gltrans_amount_total_unposted ,
+            0 as gltrans_as_summary                 
+        ");
+        
+        
+        $shiphead = DB_DataObject::factory('shiphead');
+        $shiphead->shiphead_order_id = $cohead->pid();
+        $numbers = $shiphead->fetchAll('shiphead_number');
+        $numbers[]= $cohead->cohead_number;
+        $ors = array();
+        foreach($numbers as $n) {
+            $ors[] = "gltrans_docnumber like '{$cohead->escape($n)}%'";
+            $ors[] = "gltrans_docnumber = '{$cohead->escape($n)}'";
+        }
+        
+        
+        $this->whereAdd( implode(' OR ', $ors));
+                        
+         $this->orderBy(" join_gltrans_accnt_id_id.accnt_descrip  ASC");
+         $this->groupBy("gltrans_accnt_id,
+                            gltrans_accnt_id_accnt_descrip,
+                            join_gltrans_accnt_id_id.accnt_descrip,
+                            gltrans_is_ship ");
+            
+    }
+    function coheadViewDetail($q, $roo)
+    {
+        
+        
+        
+        $cohead_id =(int) $q['cohead_id'];
+        $accnt_id =(int) $q['gltrans_accnt_id'];
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        $shiphead = DB_DataObject::factory('shiphead');
+        $shiphead->shiphead_order_id = $cohead->pid();
+        $numbers = $shiphead->fetchAll('shiphead_number');
+        $numbers[]= $cohead->cohead_number;
+        $ors = array();
+        foreach($numbers as $n) {
+            $ors[] = "gltrans_docnumber like '{$cohead->escape($n)}%'";
+            $ors[] = "gltrans_docnumber = '{$cohead->escape($n)}'";
+        }
+        
+        
+        
+        $this->whereAdd( implode(' OR ', $ors));
+        
+        $this->whereAdd("
+                  
+                gltrans_accnt_id = $accnt_id 
+                
+        ");
+        
+        $not =  ($q['gltrans_is_ship'] ? '' : 'NOT') ;
+        $andor = $not == 'NOT' ? 'AND' : 'OR';
+        $this->whereAdd("
+                        
+                        
+                        gltrans_notes {$not}  LIKE 'Ship Order%'
+                        $andor
+                        gltrans_notes {$not}  LIKE 'Recall Ship%'
+                        ");
+        
+        if ($q['gltrans_as_summary']) {
+            $this->selectAdd();
+            $this->selectAdd("
+                    distinct(gltrans_docnumber) as gltrans_docnumber,
+                    max(gltrans_id) as gltrans_id,
+                    max(gltrans_date) as gltrans_date,
+                    gltrans_source,
+                    '' as gltrans_notes,
+                    sum(gltrans_amount) as gltrans_amount,
+                    gltrans_posted
+                    
+                             ");
+            $this->groupBy('gltrans_docnumber,
+                    gltrans_source,
+                   
+                    gltrans_posted');
+            
+            
+        }
+        
+    }
+    
+    function joinAddAccnt()
+    {
+        $ac = DB_DataObject::Factory('accnt');
+        $this->_join .= "
+            LEFT JOIN accnt join_gltrans_accnt_id_id
+            ON
+            join_gltrans_accnt_id_id.accnt_id = gltrans_accnt_id
+            ";
+        $this->selectAs($ac, 'gltrans_accnt_id_%s', 'join_gltrans_accnt_id_id');
+        
+        
+    }
+    
+    function beforeInsert($q,$roo)
+    {
+        if (!empty($q['_post'])) {
+            $this->post($roo);
+            $this->jok("voided");
+   
+        }
+        
+        $this->jerr("direct access not allowed");
+    }
+    
+    function beforeUpdate($old,$q, $roo)
+    {
+        if(!empty($q['_variance'])){
+            $result = $this->addVariance($roo);
+            $roo->jok($result);
+        }
+        
+        if(!empty($q['_del'])){
+            $v = DB_DataObject::Factory('gltrans');
+            $v->query("select deleteGlSeries({$this->gltrans_sequence}, 'Fix Purchase Price Variance ') as result");
+            $v->fetch();
+            
+            if (empty($v->result)) {
+                $roo->jerr("deleteglseries failed");
+            }
+            $roo->jok('DELETED');
+        }
+        
+        if (!empty($q['_void'])) {
+            if (!preg_match('/(Recall|Ship Order)/', $this->gltrans_notes)) {
+                $roo->jerr("can only be used to void ship records.");   
+            }
+            $this->void($roo);
+            $roo->jok("posted");
+   
+        }
+        if (!empty($q['_unvoid'])) {
+            $this->unvoid($roo);
+            $roo->jok("posted");
+   
+        }
+        if(!empty($q['_update_notes'])){
+            return;
+        }
+        $roo->jerr("direct access not allowed");
+    }
+    
+    function post($roo)
+    {
+        // this is similar to returnshipmenttransaction.
+        
+        // make sure there is only two tx's for the sequence.?
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->gltrans_sequence = $this->gltrans_sequence;
+        $total = $gl->find();
+        if ($total != 2) {
+            $roo->jerr("can not post this as there are more than 2 transactions");
+        }
+        while ($gl->fetch()) {
+            if ($gl->gltrans_posted) {
+                $roo->jerr("series already posted");
+            } 
+        }
+        
+        
+        
+        $ci = $this->factory('coitem');
+        $ci->query("
+            SELECT postintotrialbalance({$this->gltrans_sequence}) AS  result
+        ");
+        $ci->fetch();
+        if (empty($ci->result) || $ci->result < 0) {
+            $roo->jerr(" postintotrialbalance FAILED?? : {$ci->result}\n");
+        }
+        $roo->jok("posted");
+        
+        
+        
+    }
+    // also used by landed cost code..
+    function void($roo, $return_result =false, $msg=false)
+    {
+        
+        //$roo->jerr("Disabled");
+        if ($this->gltrans_deleted) {
+            $roo->jerr("already deleted");
+        }
+        if (!$this->gltrans_posted) {
+            $roo->jerr("not posted");
+        }
+        // moved to calling scope above.
+        //if (!preg_match('/(Recall|Ship Order)/', $this->gltrans_notes)) {
+        //    $roo->jerr("can only be used to void ship records.");   
+        //}
+        
+        $msg = ($msg===false) ?  'Voided due to system error' : $msg;
+        
+        $v = DB_DataObject::Factory('gltrans');
+        $v->query("select deleteglseries({$this->gltrans_sequence}, '{$this->escape($msg)}') as result");
+        $v->fetch();
+        if (empty($v->result)) {
+            $roo->jerr("deleteglseries failed");
+        }
+        if (!$return_result) {
+            $roo->jok("voided");
+        }
+        return true;
+        
+    }
+     function unvoid($roo)
+    {
+        
+        //$roo->jerr("Disabled");
+        if (!$this->gltrans_deleted) {
+            $roo->jerr("not deleted");
+        }
+        if ($this->gltrans_posted) {
+            $roo->jerr("posted");
+        }
+        if (!preg_match('/(Recall|Ship Order)/', $this->gltrans_notes)) {
+            $roo->jerr("can only be used to void ship records.");   
+        }
+        
+        
+        
+        $v = DB_DataObject::Factory('gltrans');
+        $v->query("select undeleteglseries({$this->gltrans_sequence}, 'un - Voided due to system error') as result");
+        $v->fetch();
+        if (empty($v->result)) {
+            $roo->jerr("undeleteglseries failed");
+        }
+        $roo->jok("voided");
+        
+    }
+    
+    function poheadView($q,$roo)
+    {
+        $this->gltrans_accnt_id = $this->sqlValue("(SELECT costcat_asset_accnt_id FROM costcat LIMIT 1)");
+        $this->whereAdd("
+            gltrans_docnumber = '{$q['_ponumber']}-{$q['_linenumber']}'
+            OR
+            (
+                gltrans_docnumber = '{$q['_ponumber']}'
+                AND
+                gltrans_notes = 'Purchase price variance adjusted for P/O {$q['_ponumber']} for item {$q['_item']}'
+            )
+            OR
+            (
+                gltrans_docnumber = '{$q['_ponumber']}'
+                AND
+                gltrans_notes LIKE 'Purchase price variance adjusted for P/O {$q['_ponumber']} on%'
+            )
+        ");
+        
+        $this->_join .= "
+            LEFT JOIN
+                invdetailview AS join_invdetailview
+            ON
+                gltrans_misc_id = invhist_id
+                AND
+                invfifo_void = 0
+        ";
+        
+        $this->whereAdd("
+            gltrans_misc_id = -1 OR invhist_id IS NOT NULL
+        ");
+        
+        
+    }
+    
+    function addVariance($roo)
+    {
+        $v = DB_DataObject::Factory('gltrans');
+        $v->query("select invfifo_addVariance('{$this->gltrans_docnumber}', {$this->gltrans_misc_id}) as result");
+        $v->fetch();
+        if($v->result < 0){
+            $roo->jerr("Error occur on adding variance for {$this->gltrans_docnumber}, result : {$v->result}");
+        }
+        return $v->result;
+    }
+    
+    function toExcel($q, $roo)
+    {
+        
+        $financial = DB_DataObject::factory('yearperiod');
+        $financial->whereAdd("
+            '{$q['_as_of']}'::date BETWEEN yearperiod_start AND yearperiod_end
+        ");
+        if(!$financial->find(true)){
+            $roo->jerr("Could not found the financial year of {$q['_as_of']}");
+        }
+        
+        $accounts = array();
+        
+        if(isset($q['gltrans_accnt_id'])){
+            
+            $accnt = DB_DataObject::factory('accnt');
+            
+            if(!$accnt->get($q['gltrans_accnt_id'])){
+                $roo->jerr("Invalid account id {$q['gltrans_accnt_id']}");
+            }
+            $accounts[$accnt->pid()] = $accnt->accnt_descrip;
+            
+            $this->runReport($accounts, $financial, $roo);
+            exit;
+        }
+        
+        // all account is really very big.. MUST set this, otherwise, it will get error
+        ini_set('memory_limit', '-1');
+        set_time_limit(0);
+        
+        $gltrans = DB_DataObject::factory('gltrans');
+        $gltrans->joinAddAccnt();
+        $gltrans->gltrans_deleted = false;
+        $gltrans->whereAdd("
+            gltrans_date BETWEEN '{$financial->yearperiod_start}'::date AND '{$financial->yearperiod_end}'::date
+        ");
+        $gltrans->selectAdd();
+        $gltrans->selectAdd("DISTINCT(gltrans_accnt_id), join_gltrans_accnt_id_id.accnt_descrip AS accnt_descrip");
+        $gltrans->orderBy('accnt_descrip ASC');
+        $accounts = $gltrans->fetchAll('gltrans_accnt_id', 'accnt_descrip');
+        
+        $this->runReport($accounts, $financial, $roo);
+        exit;
+        
+    }
+    
+    function runReport($accounts, $financial, $roo)
+    {
+        $data = array();
+        $sheets = array();
+        
+        foreach ($accounts as $accnt_id => $accnt_descrip){
+            
+            $results = $this->buildData($accnt_id, $financial, $roo);
+            
+            $data[$accnt_id] = $results['data'];
+            
+            $sheets[$accnt_id] = array(
+                'workbook' => substr($accnt_descrip, 0, 31),
+                'cols' => $results['cols']
+            );
+            
+        }
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $sheets,
+        ));
+        
+        $x->send('Account Summary -' . date('Y-m-d') . '.xls');
+    }
+    
+    function buildData($accnt_id, $financial, $roo)
+    {
+        $meta = DB_DataObject::Factory('metasql');
+        
+        $params = array(
+            '_group' => 'account',
+            '_name' => 'summary',
+            'limit' => 99999,
+            'accnt_id:number' => $accnt_id,
+            'startDate:text' => $financial->yearperiod_start,
+            'endDate:text' => $financial->yearperiod_end
+        );
+        
+        $queryinfo = $meta->buildReportQuery($params, $roo);
+        
+        $query = $queryinfo['query'];
+        
+        $data = array();
+        ini_set('memory_limit', '512M'); // thse can be big..
+        $do = DB_DataObject::Factory('metasql');
+        $do->query($query);
+        // we cannot use fetchAll() for the metasql!
+        while ($do->fetch()) {
+           $data[] = $do->toArray();
+        }
+        
+        $cols = array();
+        
+        foreach ($queryinfo['info']->COLS as $k => $v){
+            $cols[] = array(
+                'dataIndex' => $v,
+                'header'  => $queryinfo['info']->TITLES[$k],
+                'width'  => 75
+            );
+        }
+        
+        return array('data' => $data, 'cols' => $cols);
+    }
+}
diff --git a/DataObjects/Gltranssync.php b/DataObjects/Gltranssync.php
new file mode 100644 (file)
index 0000000..076d098
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Table Definition for gltranssync
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Gltranssync extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'gltranssync';         // table name
+    public $gltrans_id;                      // int4(4)  not_null default_nextval%28%28%22gltrans_gltrans_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $gltrans_exported;                // bool(1)  
+    public $gltrans_created;                 // timestamptz(8)  
+    public $gltrans_date;                    // date(4)  not_null
+    public $gltrans_sequence;                // int4(4)  
+    public $gltrans_accnt_id;                // int4(4)  not_null
+    public $gltrans_source;                  // text(-1)  
+    public $gltrans_docnumber;               // text(-1)  
+    public $gltrans_misc_id;                 // int4(4)  
+    public $gltrans_amount;                  // numeric(-1)  not_null
+    public $gltrans_notes;                   // text(-1)  
+    public $gltrans_journalnumber;           // int4(4)  
+    public $gltrans_posted;                  // bool(1)  not_null
+    public $gltrans_doctype;                 // text(-1)  
+    public $gltrans_rec;                     // bool(1)  not_null default_false
+    public $gltrans_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $gltrans_deleted;                 // bool(1)  default_false
+    public $gltranssync_period_id;           // int4(4)  not_null
+    public $gltranssync_company_id;          // int4(4)  not_null
+    public $gltranssync_curr_amount;         // numeric(-1)  not_null
+    public $gltranssync_curr_id;             // int4(4)  not_null
+    public $gltranssync_curr_rate;           // numeric(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $gltranssync_company_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function company() {
+        return func_num_args() ? $this->link('gltranssync_company_id', func_get_arg(0)) : $this->link('gltranssync_company_id');
+    }
+
+   /**
+    * Getter / Setter for $gltranssync_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('gltranssync_curr_id', func_get_arg(0)) : $this->link('gltranssync_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $gltranssync_period_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function period() {
+        return func_num_args() ? $this->link('gltranssync_period_id', func_get_arg(0)) : $this->link('gltranssync_period_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Grp.php b/DataObjects/Grp.php
new file mode 100644 (file)
index 0000000..48835be
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Table Definition for grp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Grp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'grp';                 // table name
+    public $grp_id;                          // int4(4)  not_null default_nextval%28grp_grp_id_seq%29 primary_key
+    public $grp_name;                        // text(-1)  not_null unique_key
+    public $grp_descrip;                     // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function create($name)
+    {
+        $sg = DB_DataObject::Factory('Groups');
+        $sg->name = $name;
+        $sg->type = 0;
+        if (!$sg->find(true)) {
+            $sg->insert();
+        }
+        
+        $g = DB_DataObject::Factory('grp');
+        $g->grp_name = $name;
+        
+        if (!$g->find(true)) {
+            $g->grp_descrip= $name;
+            $g->insert();
+        }
+        if ($name == 'ADMIN') {
+            return;
+        }
+        $admin = DB_DataObject::Factory('grp');
+        $admin->get('grp_name', 'ADMIN');
+        
+        $pr = DB_DataObject::Factory('priv');
+        $prtype = $pr->fetchAll('priv_id', 'priv_module');
+        
+        
+        $gp = DB_DataObject::Factory('grppriv');
+        $gp->grppriv_grp = $admin->pid();
+        $privs = $gp->fetchAll('grppriv_priv_id');
+        foreach($privs as $p) {
+            // do not add accounting privs to anyone..
+            if (isset($prtype[$p]) && $prtype[$p] == 'Accounting') {
+                continue;
+            }
+            // tier 4 can not use xtuple. ui.
+            if ($name == 'TIER4' && isset($prtype[$p]) && $prtype[$p] == 'Desktop') {
+                continue;
+            }
+            
+            $gp = DB_DataObject::Factory('grppriv');
+            $gp->grppriv_grp = $g->pid();
+            $gp->grppriv_priv_id = $p;
+            if (!$gp->find(true)) {
+                $gp->insert();
+            }
+        }
+        
+        
+    }
+     
+}
diff --git a/DataObjects/Grppriv.php b/DataObjects/Grppriv.php
new file mode 100644 (file)
index 0000000..78ec429
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for grppriv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Grppriv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'grppriv';             // table name
+    public $grppriv_id;                      // int4(4)  not_null default_nextval%28grppriv_grppriv_id_seq%29 primary_key
+    public $grppriv_grp_id;                  // int4(4)  not_null
+    public $grppriv_priv_id;                 // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $grppriv_grp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function grp() {
+        return func_num_args() ? $this->link('grppriv_grp_id', func_get_arg(0)) : $this->link('grppriv_grp_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Hnfc.php b/DataObjects/Hnfc.php
new file mode 100644 (file)
index 0000000..4d286a4
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Table Definition for hnfc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Hnfc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'hnfc';                // table name
+    public $hnfc_id;                         // int4(4)  not_null default_nextval%28hnfc_hnfc_id_seq%29 primary_key
+    public $hnfc_code;                       // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Image.php b/DataObjects/Image.php
new file mode 100644 (file)
index 0000000..fd0aef9
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for image
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Image extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'image';               // table name
+    public $image_id;                        // int4(4)  not_null default_nextval%28%28%22image_image_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $image_name;                      // text(-1)  
+    public $image_descrip;                   // text(-1)  
+    public $image_data;                      // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Imageass.php b/DataObjects/Imageass.php
new file mode 100644 (file)
index 0000000..d2cf503
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for imageass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Imageass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'imageass';            // table name
+    public $imageass_id;                     // int4(4)  not_null default_nextval%28imageass_imageass_id_seq%29 primary_key
+    public $imageass_source_id;              // int4(4)  not_null
+    public $imageass_source;                 // text(-1)  not_null
+    public $imageass_image_id;               // int4(4)  not_null
+    public $imageass_purpose;                // bpchar(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $imageass_image_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function image() {
+        return func_num_args() ? $this->link('imageass_image_id', func_get_arg(0)) : $this->link('imageass_image_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdt.php b/DataObjects/Incdt.php
new file mode 100644 (file)
index 0000000..afa6545
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Table Definition for incdt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdt';               // table name
+    public $incdt_id;                        // int4(4)  not_null default_nextval%28incdt_incdt_id_seq%29 primary_key
+    public $incdt_number;                    // int4(4)  not_null unique_key
+    public $incdt_crmacct_id;                // int4(4)  
+    public $incdt_cntct_id;                  // int4(4)  
+    public $incdt_summary;                   // text(-1)  
+    public $incdt_descrip;                   // text(-1)  
+    public $incdt_item_id;                   // int4(4)  
+    public $incdt_timestamp;                 // timestamp(8)  not_null default_now%28%29
+    public $incdt_status;                    // bpchar(-1)  not_null default_N
+    public $incdt_assigned_username;         // text(-1)  
+    public $incdt_incdtcat_id;               // int4(4)  
+    public $incdt_incdtseverity_id;          // int4(4)  
+    public $incdt_incdtpriority_id;          // int4(4)  
+    public $incdt_incdtresolution_id;        // int4(4)  
+    public $incdt_lotserial;                 // text(-1)  
+    public $incdt_ls_id;                     // int4(4)  
+    public $incdt_aropen_id;                 // int4(4)  
+    public $incdt_owner_username;            // text(-1)  
+    public $incdt_recurring_incdt_id;        // int4(4)  
+    public $incdt_updated;                   // timestamp(8)  not_null default_now%28%29
+    public $incdt_prj_id;                    // int4(4)  
+    public $incdt_public;                    // bool(1)  
+
+    
+   /**
+    * Getter / Setter for $incdt_aropen_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function aropen() {
+        return func_num_args() ? $this->link('incdt_aropen_id', func_get_arg(0)) : $this->link('incdt_aropen_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('incdt_cntct_id', func_get_arg(0)) : $this->link('incdt_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_crmacct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function crmacct() {
+        return func_num_args() ? $this->link('incdt_crmacct_id', func_get_arg(0)) : $this->link('incdt_crmacct_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_incdtcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdtcat() {
+        return func_num_args() ? $this->link('incdt_incdtcat_id', func_get_arg(0)) : $this->link('incdt_incdtcat_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_incdtpriority_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdtpriority() {
+        return func_num_args() ? $this->link('incdt_incdtpriority_id', func_get_arg(0)) : $this->link('incdt_incdtpriority_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_incdtresolution_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdtresolution() {
+        return func_num_args() ? $this->link('incdt_incdtresolution_id', func_get_arg(0)) : $this->link('incdt_incdtresolution_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_incdtseverity_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdtseverity() {
+        return func_num_args() ? $this->link('incdt_incdtseverity_id', func_get_arg(0)) : $this->link('incdt_incdtseverity_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('incdt_item_id', func_get_arg(0)) : $this->link('incdt_item_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('incdt_prj_id', func_get_arg(0)) : $this->link('incdt_prj_id');
+    }
+
+   /**
+    * Getter / Setter for $incdt_recurring_incdt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function recurring_incdt() {
+        return func_num_args() ? $this->link('incdt_recurring_incdt_id', func_get_arg(0)) : $this->link('incdt_recurring_incdt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdtcat.php b/DataObjects/Incdtcat.php
new file mode 100644 (file)
index 0000000..9fa3828
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for incdtcat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdtcat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdtcat';            // table name
+    public $incdtcat_id;                     // int4(4)  not_null default_nextval%28incdtcat_incdtcat_id_seq%29 primary_key
+    public $incdtcat_name;                   // text(-1)  not_null unique_key
+    public $incdtcat_order;                  // int4(4)  
+    public $incdtcat_descrip;                // text(-1)  
+    public $incdtcat_ediprofile_id;          // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdthist.php b/DataObjects/Incdthist.php
new file mode 100644 (file)
index 0000000..e900756
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for incdthist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdthist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdthist';           // table name
+    public $incdthist_id;                    // int4(4)  not_null default_nextval%28incdthist_incdthist_id_seq%29 primary_key
+    public $incdthist_incdt_id;              // int4(4)  not_null
+    public $incdthist_change;                // bpchar(-1)  
+    public $incdthist_target_id;             // int4(4)  
+    public $incdthist_timestamp;             // timestamp(8)  not_null default_now%28%29
+    public $incdthist_username;              // text(-1)  not_null default_%22current_user%22%28%29
+    public $incdthist_descrip;               // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $incdthist_incdt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdt() {
+        return func_num_args() ? $this->link('incdthist_incdt_id', func_get_arg(0)) : $this->link('incdthist_incdt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdtpriority.php b/DataObjects/Incdtpriority.php
new file mode 100644 (file)
index 0000000..53e223f
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for incdtpriority
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdtpriority extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdtpriority';       // table name
+    public $incdtpriority_id;                // int4(4)  not_null default_nextval%28incdtpriority_incdtpriority_id_seq%29 primary_key
+    public $incdtpriority_name;              // text(-1)  not_null unique_key
+    public $incdtpriority_order;             // int4(4)  
+    public $incdtpriority_descrip;           // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdtresolution.php b/DataObjects/Incdtresolution.php
new file mode 100644 (file)
index 0000000..d701792
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for incdtresolution
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdtresolution extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdtresolution';     // table name
+    public $incdtresolution_id;              // int4(4)  not_null default_nextval%28incdtresolution_incdtresolution_id_seq%29 primary_key
+    public $incdtresolution_name;            // text(-1)  not_null unique_key
+    public $incdtresolution_order;           // int4(4)  
+    public $incdtresolution_descrip;         // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Incdtseverity.php b/DataObjects/Incdtseverity.php
new file mode 100644 (file)
index 0000000..440fa31
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for incdtseverity
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Incdtseverity extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'incdtseverity';       // table name
+    public $incdtseverity_id;                // int4(4)  not_null default_nextval%28incdtseverity_incdtseverity_id_seq%29 primary_key
+    public $incdtseverity_name;              // text(-1)  not_null unique_key
+    public $incdtseverity_order;             // int4(4)  
+    public $incdtseverity_descrip;           // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Invadj.php b/DataObjects/Invadj.php
new file mode 100644 (file)
index 0000000..94912c4
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Table Definition for alarm
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invadj extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invadj';               // table name
+    public $invadj_id;                        // int4(4)  not_null default_nextval%28alarm_alarm_id_seq%29 primary_key
+    public $invadj_transdate;                    // text(-1)  not_null
+    public $invadj_location_id;                     // bool(1)  not_null default_false
+    public $invadj_itemsite_id;                     // bool(1)  not_null default_false
+    public $invadj_qty_by;                    // bool(1)  not_null default_false
+    public $invadj_posted;                   // timestamptz(8)  
+    public $invadj_comments;                      // timestamptz(8)  
+    public $invadj_invadjgrp_id;                      // int  
+     
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        ///DB_DataObject::DebugLevel(1);
+        $tn = $this->tableName();
+        $this->autoJoinItem();
+        $this->autoJoinInvfifo();
+        if (!empty($q['query']['comment'])) {
+            $s = $this->escape($q['query']['comment']);
+            $this->whereAdd("invadj_comments LIKE '%$s%'");
+        }
+        
+         
+        if(isset($q['_with_detail'])){
+            $this->selectAdd("
+                CASE WHEN invadj_posted THEN
+                    (SELECT ROUND(COALESCE(invdetail_atdate(invadj_transdate + INTERVAL '1 DAY', invadj_location_id, invadj_itemsite_id), 0),0))
+                ELSE
+                    ((SELECT ROUND(COALESCE(invdetail_atdate(invadj_transdate + INTERVAL '1 DAY', invadj_location_id, invadj_itemsite_id), 0),0)) + invadj_qty_by)
+                END AS invadj_qty_after,
+                
+                CASE WHEN invadj_posted THEN
+                    ((SELECT ROUND(COALESCE(invdetail_atdate(invadj_transdate + INTERVAL '1 DAY', invadj_location_id, invadj_itemsite_id), 0),0)) - invadj_qty_by)
+                ELSE
+                    (SELECT ROUND(COALESCE(invdetail_atdate(invadj_transdate + INTERVAL '1 DAY', invadj_location_id, invadj_itemsite_id), 0),0))
+                END AS invadj_qty_before
+            ");
+            
+        }
+        if (!empty($q['_hide_group'])) {
+            $this->whereAdd("{$tn}.invadj_invadjgrp_id IS NULL");
+        }
+        
+        
+        if (empty($q['_show_void']) && empty($q['invadj_invadjgrp_id'])) { // then hide void..
+            
+            $this->whereAdd("{$tn}.invadj_voids_id = 0 AND {$tn}.invadj_voided_by_id = 0   AND (invadj_invdetail_id  IS NULL OR invfifo.invfifo_void =0)");
+        }
+        if (isset($q['_show_void']) && empty($q['invadj_invadjgrp_id'])) { // then only show void..
+            $this->whereAdd("{$tn}.invadj_voids_id != 0 OR {$tn}.invadj_voided_by_id != 0 OR
+                            (invadj_invdetail_id  IS NOT NULL AND invfifo.invfifo_void !=0)
+                ");
+        }
+        
+        
+        
+    }
+    function autoJoinItem()
+    {
+        $i = DB_DataObject::Factory('item');
+        
+        
+        $this->_join .= '
+            LEFT JOIN item join_item ON join_invadj_itemsite_id_itemsite_id.itemsite_item_id = item_id
+        ';
+        $this->selectAs($i, 'invadj_itemsite_id_%s', 'join_item');
+        
+    }
+    
+    function autoJoinInvfifo()
+    {
+        $i = DB_DataObject::Factory('invfifo');
+        
+        //LEFT JOIN invdetail ON invdetail_id = invadj_invdetail_id
+        //    LEFT JOIN invhist ON invdetail_invhist_id = invhist_id
+        $this->_join .= '
+            
+            LEFT JOIN invfifo ON invfifo_invdetail_id = invadj_invdetail_id
+        ';
+        $this->selectAs($i, '%s');
+        
+    }
+    
+    function beforeInsert($q, $roo) {
+        if ($this->invadj_posted) {
+            $roo->jerr("can not update posted");
+        }
+        if ($this->invadj_invdetail_id) {
+            $roo->jerr("can not existing transaction");
+        }
+        if ($this->invadj_voided_by_id ) {
+            $roo->jerr("can not voided by");
+        }
+        if (isset($this->invadj_invdetail_id)) {
+            unset($this->invadj_invdetail_id);
+        }
+
+
+    }
+    function beforeUpdate($old, $q, $roo) {
+        
+        if (isset($q['_post'])) {
+            $this->post($roo);
+        }
+        
+        if ($this->invadj_posted || !empty($q['invadj_posted'])) {
+            $roo->jerr("can not update posted");
+        }
+        if ($this->invadj_invdetail_id || !empty($q['invadj_invdetail_id'])) {
+            $roo->jerr("can not existing transaction");
+        }
+        if ($this->invadj_voided_by_id || !empty($q['invadj_voided_by_id'])) {
+            $roo->jerr("can not voided by");
+        }
+        if (isset($this->invadj_invdetail_id)) {
+            unset($this->invadj_invdetail_id);
+        }
+        
+        
+    }
+    
+    function post($roo)
+    {
+        // check if it's a closed period..
+        
+        $p = DB_DataObject::factory('period');
+        if ($p->isClosed($this->invadj_transdate)) {
+            $fo  = $p->firstOpen();
+            $roo->jerr(
+                "account period is closed - This will change the post date to {$fo->period_start}, you can then try posting again",
+                array('trandate' => $fo->period_start )
+            );
+        }
+        
+        
+        $t= clone($this);
+        $t->query("SELECT invadj_post({$this->invadj_id}) as result");
+        // that will throw an error if there is a problem.
+        $roo->jok("POSTED");
+         
+    }
+}
\ No newline at end of file
diff --git a/DataObjects/Invadjgrp.php b/DataObjects/Invadjgrp.php
new file mode 100644 (file)
index 0000000..2311979
--- /dev/null
@@ -0,0 +1,246 @@
+<?php
+/**
+ * Table Definition for alarm
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invadjgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invadjgrp';               // table name
+    public $invadjgrp_id;                        // int4(4)  not_null default_nextval
+    public $invadjgrp_name;                      // text
+    public $invadjgrp_transdate;                 // date
+    public $invadjgrp_location_id;               // int
+    public $invadjgrp_posted;                    // boolean
+    public $invadjgrp_comments;                  // text
+     
+    
+    /**
+    * Getter / Setter for $invadjgrp_location_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function location_id() {
+        return func_num_args() ? $this->link('invadjgrp_location_id', func_get_arg(0)) : $this->link('invadjgrp_location_id');
+    }
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if(isset($q['_with_qty_detail'])){
+            $this->selectAdd("
+                (SELECT COALESCE(SUM(invadj_qty_by),0) FROM invadj WHERE invadj_invadjgrp_id = invadjgrp_id AND invadj_qty_by < 0) AS invadjgrp_neg_qty,
+                (SELECT COALESCE(SUM(invadj_qty_by),0) FROM invadj WHERE invadj_invadjgrp_id = invadjgrp_id AND invadj_qty_by > 0) AS invadjgrp_pos_qty
+            ");
+        }
+    }
+    
+    function beforeInsert($q,$roo)
+    {
+        if(!empty($q['invadjgrp_name'])){
+            $invadjgrp = DB_DataObject::factory('invadjgrp');
+            $invadjgrp->whereAdd("
+                invadjgrp_name = '{$this->escape($q['invadjgrp_name'])}'
+            ");
+            if($invadjgrp->count()){
+                $roo->jerr('Inventory Adjustment Group Name already exist!');
+            }
+        }
+    }
+    
+    function beforeUpdate($old, $q, $roo) 
+    {   
+        if(isset($q['_void'])){
+            $this->void($roo, $q['_force']);
+            $roo->jok('VOIDED');
+        }
+        
+        if($old->invadjgrp_posted){
+            $roo->jerr('Can not update posted');
+        }
+        
+        if(!empty($q['invadjgrp_name'])){
+            $invadjgrp = DB_DataObject::factory('invadjgrp');
+            $invadjgrp->whereAdd("
+                invadjgrp_name = '{$this->escape($q['invadjgrp_name'])}'
+                AND
+                invadjgrp_id != {$this->pid()}
+            ");
+            if($invadjgrp->count()){
+                $roo->jerr('Inventory Adjustment Group Name already exist!');
+            }
+        }
+        
+        if (isset($q['adjustments'])) {
+            $this->updateInvadj(json_decode($q['adjustments']), $roo);
+             
+        }
+    }
+    
+    function onUpdate($old, $q, $roo)
+    {  
+        if (isset($q['_post'])) {
+            $this->post($roo);
+            $roo->jok('POSTED');
+        }
+    }
+    
+    function beforeDelete($dependants_array, $roo)
+    {
+        $invadj = DB_DataObject::factory('invadj');
+        $invadj->whereAdd("
+            invadj_invadjgrp_id = {$this->pid()}
+            AND
+            invadj_posted
+        ");
+        
+        if($invadj->count()){
+            $roo->jerr('There are some adjustments have been posted of this group');
+        }
+        
+        $invadj = DB_DataObject::factory('invadj');
+        $invadj->invadj_invadjgrp_id = $this->pid();
+        $invadj->find();
+        while ($invadj->fetch()){
+            $invadj->delete();
+        }
+        
+        
+    }
+    
+    function updateInvadj($adjustments, $roo)
+    {
+        $invadj = $this->invadj();
+        
+        foreach ($adjustments as $adj){
+            $i = DB_DataObject::factory('invadj');
+            if(!empty($adj->invadj_id)){
+                $i = $invadj[$adj->invadj_id];                
+            }
+            
+            $i->setFrom(array(
+                'invadj_transdate' => $this->invadjgrp_transdate,
+                'invadj_location_id' => $this->invadjgrp_location_id,
+                'invadj_itemsite_id' => $adj->invadj_itemsite_id,
+                'invadj_qty_by' => $adj->invadj_qty_by,
+                'invadj_posted' => FALSE,
+                'invadj_comments' => $this->invadjgrp_comments,
+                'invadj_voids_id' => 0,
+                'invadj_voided_by_id' => 0,
+                'invadj_invadjgrp_id' => $this->pid()
+            ));
+            
+            if(empty($adj->invadj_id)){
+                $i->insert();
+                continue;
+            }
+            
+            $i->update($invadj[$adj->invadj_id]);
+            unset($invadj[$adj->invadj_id]);
+        }
+        
+        foreach ($invadj as $adj){
+            $adj->delete();
+        }
+        
+        
+        
+    }
+    
+    function post($roo)
+    {   
+        $p = DB_DataObject::factory('period');
+        if ($p->isClosed($this->invadjgrp_transdate)) {
+            $fo  = $p->firstOpen();
+            $roo->jerr("account period is closed - This will change the post date to {$fo->period_start}, you can then try posting again");
+        }
+        
+        $invadj = $this->invadj();
+        
+        foreach ($invadj as $adj){
+            if($adj->invadj_posted){
+                continue;
+            }
+            $t= clone($this);
+            $t->query("SELECT invadj_post({$adj->pid()}) as result"); 
+        }
+         
+    }
+    /**
+     * voiding flags teh origianl as void... 
+     *
+    */
+    function void($roo, $force = 1)
+    {  
+        if(!$this->invadjgrp_posted){
+            $roo->jerr("This group has not been posted");
+        }
+        
+        $invadj = DB_DataObject::factory('invadj');
+        $invadj->whereAdd("
+            invadj_invadjgrp_id = {$this->pid()}
+            AND
+            invadj_voided_by_id != 0
+        ");
+        
+        if(empty($force) && $invadj->count()){
+            $roo->jerr("There are some adjustments have been voided of this group", array('confirm' => 1));
+        }
+        
+        $invadj = $this->invadj();
+        
+        foreach ($invadj as $adj){
+            if(!empty($adj->invadj_voided_by_id)){ // voided
+                continue;
+            }
+            
+            $i = DB_DataObject::factory('invadj');
+            $i->setFrom(array(
+                'invadj_transdate' => $adj->invadj_transdate,
+                'invadj_location_id' => $adj->invadj_location_id,
+                'invadj_itemsite_id' => $adj->invadj_itemsite_id,
+                'invadj_qty_by' => $adj->invadj_qty_by * -1,
+                'invadj_posted' => FALSE,
+                'invadj_comments' => (!empty($adj->invadj_voids_id)) ? 'Restore Adjustment #' . $adj->invadj_voids_id : 'Void of Adjustment #' . $adj->pid(),
+                'invadj_voids_id' => $adj->pid(),
+                'invadj_voided_by_id' => 0,
+                'invadj_invadjgrp_id' => $this->pid()
+            ));
+            if(!$i->insert()){
+                $roo->jerr('Error occur on insert a invadj');
+            }
+            
+            $t= clone($this);
+            $t->query("SELECT invadj_post({$i->pid()}) as result");
+            
+        }
+        $old = clone($this);
+        $this->invadjgrp_void = true;
+        $this->update($old);
+        
+    }
+    /**
+     * return k=> (object) array where k = pid()
+     */
+    function invadj()
+    {
+        $ret = array();
+        
+        $invadj = DB_DataObject::factory('invadj');
+        $invadj->invadj_invadjgrp_id = $this->pid();
+        $invadj->find();
+        while ($invadj->fetch()){
+            $i = clone ($invadj);
+            $ret[$invadj->pid()] = $i;
+        }
+        return $ret;
+    }
+    
+}
\ No newline at end of file
diff --git a/DataObjects/Invchead.php b/DataObjects/Invchead.php
new file mode 100644 (file)
index 0000000..989ede9
--- /dev/null
@@ -0,0 +1,1048 @@
+<?php
+/**
+ * Table Definition for invchead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invchead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invchead';            // table name
+    public $invchead_id;                     // int4(4)  not_null default_nextval%28invchead_invchead_id_seq%29 primary_key
+    public $invchead_cust_id;                // int4(4)  not_null
+    public $invchead_shipto_id;              // int4(4)  
+    public $invchead_ordernumber;            // text(-1)  
+    public $invchead_orderdate;              // date(4)  
+    public $invchead_posted;                 // bool(1)  not_null
+    public $invchead_printed;                // bool(1)  not_null
+    public $invchead_invcnumber;             // text(-1)  not_null unique_key
+    public $invchead_invcdate;               // date(4)  not_null
+    public $invchead_shipdate;               // date(4)  
+    public $invchead_ponumber;               // text(-1)  
+    public $invchead_shipvia;                // text(-1)  
+    public $invchead_fob;                    // text(-1)  
+    public $invchead_billto_name;            // text(-1)  
+    public $invchead_billto_address1;        // text(-1)  
+    public $invchead_billto_address2;        // text(-1)  
+    public $invchead_billto_address3;        // text(-1)  
+    public $invchead_billto_city;            // text(-1)  
+    public $invchead_billto_state;           // text(-1)  
+    public $invchead_billto_zipcode;         // text(-1)  
+    public $invchead_billto_phone;           // text(-1)  
+    public $invchead_shipto_name;            // text(-1)  
+    public $invchead_shipto_address1;        // text(-1)  
+    public $invchead_shipto_address2;        // text(-1)  
+    public $invchead_shipto_address3;        // text(-1)  
+    public $invchead_shipto_city;            // text(-1)  
+    public $invchead_shipto_state;           // text(-1)  
+    public $invchead_shipto_zipcode;         // text(-1)  
+    public $invchead_shipto_phone;           // text(-1)  
+    public $invchead_salesrep_id;            // int4(4)  
+    public $invchead_commission;             // numeric(-1)  not_null
+    public $invchead_terms_id;               // int4(4)  
+    public $invchead_freight;                // numeric(-1)  not_null
+    public $invchead_misc_amount;            // numeric(-1)  not_null
+    public $invchead_misc_descrip;           // text(-1)  
+    public $invchead_misc_accnt_id;          // int4(4)  
+    public $invchead_payment;                // numeric(-1)  
+    public $invchead_paymentref;             // text(-1)  
+    public $invchead_notes;                  // text(-1)  
+    public $invchead_billto_country;         // text(-1)  
+    public $invchead_shipto_country;         // text(-1)  
+    public $invchead_prj_id;                 // int4(4)  
+    public $invchead_curr_id;                // int4(4)  default_basecurrid%28%29
+    public $invchead_gldistdate;             // date(4)  
+    public $invchead_recurring;              // bool(1)  not_null default_false
+    public $invchead_recurring_interval;     // int4(4)  
+    public $invchead_recurring_type;         // text(-1)  
+    public $invchead_recurring_until;        // date(4)  
+    public $invchead_recurring_invchead_id;    // int4(4)  
+    public $invchead_shipchrg_id;            // int4(4)  
+    public $invchead_taxzone_id;             // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $invchead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('invchead_taxzone_id', func_get_arg(0)) : $this->link('invchead_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $invchead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('invchead_curr_id', func_get_arg(0)) : $this->link('invchead_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+     function applyFilters($q, $au, $roo)
+    {
+        // DB_DataObject::debugLevel(1);
+        
+        if (!empty($q['query']['invchead_ordernumber'])) {
+            $v = $this->escape($q['query']['invchead_ordernumber']);
+            $this->whereAdd("    invchead_ordernumber ILIKE '$v%' ");
+        
+        }
+        
+        if (!empty($q['search']['cohead_id'])) {
+            $co = DB_DataObject::Factory('cohead');
+            $co->get($q['search']['cohead_id']);
+            $this->whereAdd("    invchead_ordernumber = '{$this->escape($co->cohead_number)}' ");
+        
+        }
+        
+        if (!empty($q['query']['invchead_invcnumber'])) {
+            $v = $this->escape($q['query']['invchead_invcnumber']);
+            $this->whereAdd("  invchead_invcnumber ILIKE '$v%'    ");
+        }
+        if (isset($q['_print'])) {
+            $this->invchead_id = $q['invchead_id'];
+            $this->toPDF($roo, $q['_print']);
+            
+        }
+        if (!empty($q['search']['fromDate'])) {
+            $v = $this->escape($q['search']['fromDate']);
+            $this->whereAdd("invchead_invcdate >= '$v'");
+        }
+        if (!empty($q['search']['toDate'])) {
+            $v = $this->escape($q['search']['toDate']);
+            $this->whereAdd("invchead_invcdate <= '$v'");
+        }
+        
+        
+        if (!empty($q['_with_salesorder'])) {
+            
+            $so = DB_DataObject::Factory('cohead');
+            $this->selectAs($so, '%s');
+            $this->_join .= '
+                LEFT JOIN cohead ON cohead_number=invchead_ordernumber
+                ';
+             
+        }
+        
+        $so = DB_DataObject::Factory('custinfo');
+        $this->selectAs($so, '%s');
+        $this->_join .= '
+            LEFT JOIN custinfo ON invchead_cust_id=cust_id
+            ';
+            
+            // was ordered??? that was probably wrong.
+        $this->selectAdd("
+            (SELECT sum(invcitem_price *  invcitem_billed) FROM invcitem WHERE invcitem_invchead_id = invchead_id) as 
+                       invchead_invctotal,
+            (SELECT sum(invcitem_price *  invcitem_billed) FROM invcitem WHERE invcitem_invchead_id = invchead_id)  +
+                invchead_misc_amount + invchead_freight as 
+                       invchead_total                       
+        ");
+
+        $this->joinAddSalesRep();
+        $this->joinAddCustomerRep();    
+        $this->joinAddCustomerAddress();
+        $this->joinAddAropen();
+        
+        if(!empty($q['_show_status'])) {
+            switch($q['_show_status']) {
+                case 'NV': // not void
+                    $this->whereAdd('invchead_void = false');
+                    
+                    break;
+                
+                case 'V': // void
+                    $this->whereAdd('invchead_void = true');
+                    break;
+                    
+                case 'U': // unpaid
+                    $this->whereAdd('aropen_amount > aropen_paid');
+                    
+                    break;
+                
+                default: // inc. all
+                    break;
+                    
+            }
+            
+            
+        }
+        
+        
+    }
+    
+    
+    function joinAddSalesRep()
+    {
+        $so = DB_DataObject::Factory('salesrep');
+        $this->selectAs($so, 'invchead_salesrep_id_%s', 'join_invchead_salesrep_id_sr');
+        $this->_join .= '
+            LEFT JOIN salesrep as join_invchead_salesrep_id_sr
+                ON join_invchead_salesrep_id_sr.salesrep_id = invchead_salesrep_id
+            ';
+        
+    }
+    function joinAddCustomerRep()
+    {
+        $so = DB_DataObject::Factory('salesrep');
+        $this->selectAs($so, 'cust_salesrep_id_%s', 'join_cust_salesrep_id__r');
+        $this->_join .= '
+            LEFT JOIN salesrep as join_cust_salesrep_id__r
+                ON join_cust_salesrep_id__r.salesrep_id = custinfo.cust_salesrep_id
+            ';
+        
+    }
+    function joinAddCustomerAddress()
+    {
+        $so = DB_DataObject::Factory('addr');
+        $this->selectAs($so, 'cust_addr_id_%s', 'join_cust_addr');
+        $this->_join .= '
+            LEFT JOIN cntct as join_cnct_id ON  cust_cntct_id = join_cnct_id.cntct_id
+              LEFT JOIN addr as  join_cust_addr ON join_cust_addr.addr_id = join_cnct_id.cntct_addr_id
+        ';
+    }
+    
+    function joinAddAropen()
+    {
+        $so = DB_DataObject::Factory('aropen');
+        $this->selectAs($so, '%s');
+        $this->_join .= "
+            LEFT JOIN aropen
+                ON
+                  aropen_docnumber =  invchead_invcnumber
+                  AND
+                  aropen_doctype = 'I'
+                  
+            ";
+        
+    }
+    
+    function beforeInsert($q, $roo)
+    {
+        if (!empty($q['_is_xfer'])) {
+            $res = $this->handleXfer($roo, $q);
+            if ($res !== true) {
+                $roo->jerr($res);
+            }
+            $roo->jok("completed");
+        }
+        if (!empty($q['_is_xfer_void'])) {
+            if (empty($q['invchead_invcnumber']) || !preg_match('#^XF-#', $q['invchead_invcnumber'])) {
+                $roo->jerr("invalid invoice to void: " .
+                            (empty($q['invchead_invcnumber']) ? 'not specified' : $q['invchead_invcnumber']));
+            }
+            
+            
+            $t = DB_DataObject::Factory('invchead');
+            if (!$t->get('invchead_invcnumber', $q['invchead_invcnumber'])) {
+                
+                $t = DB_DataObject::Factory('invchead');
+                $ivn = $t->escape($q['invchead_invcnumber']);
+                $t->whereAdd("invchead_invcnumber like '{$ivn}x-%'");
+                
+                if ($t->count()) {
+                    $roo->jok("already voided");
+                }
+                
+                
+                $roo->jerr("could not find invoice : " .$q['invchead_invcnumber'] );
+            }
+            
+            if ($t->invchead_void) {
+                $this->jok("Already void, we allow this scenario");
+            }
+            
+            $t->void($roo);
+            
+            $roo->jerr("we should not get here..");
+        }
+        
+        
+    }
+    function beforeUpdate($old, $q, $roo)
+    {
+        if (!empty($q['_void'])) {
+            $this->void($roo);
+        }
+    }
+    function order()
+    {
+        $co = DB_DataObject::Factory('cobmisc');
+        if (!$co->get('cobmisc_invchead_id', $this->invchead_id)) {
+            return false;
+        }
+        return $co->cohead();
+        
+        
+        
+    }
+    
+    function items($what=false)
+    {
+        $i = $this->factory('invcitem');
+        $i->invcitem_invchead_id = $this->invchead_id;
+        if ($what !== false) {
+            return $i->fetchAll($what);
+        }
+        
+        $ret = array();
+        $i->find();
+        while($i->fetch()) {
+            $ret[] = clone($i);
+        }
+        return $ret;
+        
+    }
+    /*
+      This is used to post invoice which are not Sales ordered (and do not have cobills.)
+     
+    */
+    
+    
+    function post($roo, $src_location)
+    {
+        if (!isset($roo->transObj)) { 
+            $this->factory('invchead')->query("BEGIN");
+        }
+
+        $t = $this->factory('invchead');
+        $t->query(" SELECT fetchJournalNumber('AR-IN') AS result");
+        $t->fetch();
+        $jn = $t->result;
+        
+        // invheadid, journal nmber?
+        $t = $this->factory('invchead');
+        $t->query(" SELECT postInvoice({$this->pid()}, $jn) AS result");
+        $t->fetch();
+        if ($t->result < 0) {
+            $roo->jerr("post invoice returned {$t->result}");
+        }
+        $series = $t->result;
+        
+        $il = DB_DataObject::factory('itemlocdist');
+        $il->itemlocdist_series = $series;
+        $il->orderBy('itemlocdist_id ASC');
+        foreach($il->fetchAll() as $ril)
+        {
+            $il = DB_DataObject::factory('itemlocdist');
+            
+            // this looks like it should be -1.. however it appears to
+            // post the wrong amount
+            //   $src_location,       itemlocdist_qty * -1,
+            
+            $il->query("INSERT INTO itemlocdist (
+                            itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                            itemlocdist_source_id,  itemlocdist_qty,
+                            itemlocdist_ls_id, itemlocdist_expiration
+                        ) SELECT
+                    itemlocdist_id,       'L',
+                     $src_location,       itemlocdist_qty ,
+                    itemlocdist_ls_id, endOfTime()
+                    FROM
+                    itemlocdist WHERE (itemlocdist_id={$ril->itemlocdist_id})
+                ");
+
+            $t = DB_DataObject::factory('itemlocdist');
+                       
+            $t->query("SELECT distributeToLocations({$ril->itemlocdist_id}) AS result");
+            $t->fetch();
+            if ($t->result < 0) {
+                $roo->jerr("distributeToLocations returned {$t->result}");
+            }
+        }
+       
+          
+        $t = DB_DataObject::factory('itemlocdist');
+        $t->query("SELECT postItemlocseries($series) AS result");
+        $t->fetch();
+        if ($t->result < 0) {
+            $roo->jerr("postItemlocseries returned {$t->result}");
+        }
+        
+        $t = DB_DataObject::factory('itemlocdist');
+        if (!isset($roo->transObj)) { 
+            $t->query('COMMIT');
+        }
+    
+        
+    }
+    
+    
+    /**
+     * This is the code used by cobmisc as well for voiding.
+     * 
+     *   It does a check on invdetail to see if the original order
+     *   affected stock (eg. a standard sales order invoice )
+     *   
+     *
+     */
+    
+    function void($roo)
+    {
+        
+        // we have a slight borked type of invoice 
+        
+        
+        
+        $items  = $this->items();
+        
+        
+        $o = $this->order();
+        
+        $t = $this->factory('invchead');
+        
+        if (!$t->get($this->invchead_id)) {
+            $roo->jerr("Invoice id is not valid");
+        }
+        $invhead = $t;
+        if ($t->invchead_void) {
+            $roo->jerr("Invoice is already void");
+        }
+        
+        if (!$t->invchead_posted) {
+            
+            // this is a bit of a kludge...
+            $t = $this->factory('invchead');
+            $t->query("    UPDATE shipitem
+                SET shipitem_invoiced=FALSE,
+                    shipitem_invcitem_id=NULL
+                WHERE (shipitem_invcitem_id IN (SELECT invcitem_id
+                                                FROM invcitem
+                                                WHERE (invcitem_invchead_id={$this->invchead_id})))
+                                            ");
+            $t = $this->factory('invchead');                
+            $t->query("
+                UPDATE cobill
+                SET cobill_invcnum=NULL,
+                    cobill_invcitem_id=NULL
+                WHERE (cobill_invcitem_id IN (SELECT invcitem_id
+                                              FROM invcitem
+                                              WHERE (invcitem_invchead_id={$this->invchead_id})))
+                                              ");
+            $t = $this->factory('invchead');
+            $t->query("
+            UPDATE cobmisc
+                SET cobmisc_posted=FALSE,
+                    cobmisc_invcnumber=NULL,
+                    cobmisc_invchead_id=NULL
+                WHERE (cobmisc_invchead_id={$this->invchead_id})
+                
+            ");
+            
+            $t = $this->factory('invchead');
+            $t->query("
+                 DELETE FROM invcitem
+           
+                WHERE (invcitem_invchead_id={$this->invchead_id})
+                
+            ");
+            
+            
+            $old = clone($invhead);
+            
+            $invhead->invchead_void = true;
+            $invhead->update($old);
+            
+            $roo->addEvent("VOIDED", $this);
+            $roo->jok("Fixed");
+            
+        }
+        if (empty($roo->transObj)) {
+            $this->factory('invchead')->query("BEGIN");
+        }
+   
+        /*
+         *  we need to void the receive payment before void the invoice..
+         *  however, it is not allow us to void it automatically
+         *  show a error
+         */
+        
+        $aropen = $this->aropen();
+        $cashrcptitem = DB_DataObject::factory('cashrcptitem');
+        $cashrcptitem->cashrcptitem_aropen_id = $aropen->pid();
+//        $cashrcptitem->autoJoin();
+//        $cashrcptitem->whereAdd('join_cashrcptitem_cashrcpt_id_cashrcpt_id.cashrcpt_void = FALSE');
+        if($cashrcptitem->count()){
+            $cashrcpt = DB_DataObject::factory('cashrcpt');
+            $cashrcpt->whereAddIn('cashrcpt_id', $cashrcptitem->fetchAll('cashrcptitem_cashrcpt_id'), 'int');
+            $cashrcpt->cashrcpt_posted = TRUE;
+            $cashrcpt->cashrcpt_void = FALSE;
+            if($cashrcpt->count()){
+                $receive = implode(',', $cashrcpt->fetchAll('cashrcpt_number'));
+                $roo->jerr("a payment '{$receive}' has been made on invoice '{$this->invchead_invcnumber}', reference order '{$this->invchead_ordernumber}' - void the payment first.");
+            }
+
+        }
+        
+        $t = $this->factory('invchead');
+        
+        $t->query("SELECT voidInvoice({$this->invchead_id}) as result");
+        $t->fetch();
+        
+        if ($t->result < 0) {
+            
+            if ($t->result == -20) {
+                $roo->jerr("This invoice has cash receipts pending or posted - please void them first");
+            }
+            
+            $roo->jerr("SELECT voidInvoice({$this->invchead_id}) as result :: returned ". $t->result);
+        }
+        
+        $series = $t->result;
+
+        
+        $coids = array();
+        foreach($items as $i) {
+            if (!empty($i->invcitem_coitem_id)) {
+                $coids[] = $i->invcitem_coitem_id;
+            }
+        }
+        
+        if (!empty($coids)) {
+             
+            $this->factory('coitem')->query(
+                "UPDATE coitem SET coitem_status='O'
+                            WHERE coitem_id IN (" . implode(',', $coids) .")"
+            );
+        }
+            
+        if ($o && $o->cohead_id && $o->cohead_status != 'O') {
+            $oo = clone($o);
+            $o->cohead_status = 'O';
+            $o->update($oo);
+        }
+        if (empty($roo->transObj)) {
+            $this->factory('invchead')->query("COMMIT");
+        }
+        // find last series..
+        
+        // this only applies to invoices that are created without sales orders
+        // eg. our xfer orders...
+        
+        // for regular invoices, they do not have any effect on stock transfer.
+        
+        
+        //DB_DataObject::DebugLevel(1);
+        $invhist =  DB_DAtaObject::factory('invhist');
+        $invhist->invhist_ordnumber  = $invhead->invchead_invcnumber;
+        $invhist->invhist_transtype = 'SH';
+        $invhist->invhist_ordtype = 'IN';
+        
+        $invhist->whereAdd('invhist_invqty > 0');
+        $invhist->orderBy('invhist_id desc');
+        $invhist->limit(1);
+        $invhist->selectAdd();
+        $invhist->selectAdd('invhist_series');
+        $invhist->find(true);
+        $oldseries = $invhist->invhist_series;
+        if (empty($oldseries)) {
+            
+            // eg. it was a regular sales order based transaction.
+            
+            return true;
+            // 
+            $roo->jerr("could not find old series from invhist");
+        }
+        //DB_DataObject::debugLevel(1);
+        
+        // find out all the locations where the original invoice was delivered to..
+        $invdetail =  DB_DAtaObject::factory('invdetail');
+        $invdetail->autoJoinInvhist();
+        
+        $invdetail->whereAdd("
+            join_invhist.invhist_series= $oldseries
+        ");
+        
+        // get the
+        $old = array();
+        $invdetail->find();
+        while($invdetail->fetch()) {
+            $is = $invdetail->invhist_itemsite_id;
+            $qty = $invdetail->invhist_invqty;
+            $old[$is] = isset($old[$is] ) ? $old[$is]  : array();
+            $old[$is][$qty] = isset($old[$is][$qty] ) ? $old[$is][$qty]  : array();
+            $old[$is][$qty][] = $invdetail->invdetail_location_id;
+            
+        }
+        
+         
+        
+        
+        $il = DB_DataObject::factory('itemlocdist');
+        $il->itemlocdist_series = $series;
+        $il->orderBy('itemlocdist_id ASC');
+        foreach($il->fetchAll() as $ril)
+        {
+            
+            // where did the last distribution go..
+            // we need the invhist from the last
+            $qty = $ril->itemlocdist_qty;
+            $is = $ril->itemlocdist_itemsite_id;
+            if (empty($old[$is][$qty])) {
+                $roo->jerr("Can not find matching transaction for Itemsite:$is qty:$qty");
+            }
+            $loc = array_pop($old[$is][$qty]);
+            
+            
+            $il = DB_DataObject::factory('itemlocdist');
+            $il->query("INSERT INTO itemlocdist (
+                            itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                            itemlocdist_source_id,  itemlocdist_qty,
+                            itemlocdist_ls_id, itemlocdist_expiration
+                        ) SELECT
+                    itemlocdist_id,       'L',
+                    
+                    $loc, itemlocdist_qty  ,
+                    itemlocdist_ls_id, endOfTime()
+                    FROM
+                    itemlocdist WHERE (itemlocdist_id={$ril->itemlocdist_id})
+                ");
+
+            $t = DB_DataObject::factory('itemlocdist');
+                       
+            $t->query("SELECT distributeToLocations({$ril->itemlocdist_id}) AS result");
+            $t->fetch();
+            if ($t->result < 0) {
+                $roo->jerr("distributeToLocations returned {$t->result}");
+            }
+        }
+       
+          
+        $t = DB_DataObject::factory('itemlocdist');
+        $t->query("SELECT postItemlocseries($series) AS result");
+        $t->fetch();
+        if ($t->result < 0) {
+            $roo->jerr("postItemlocseries returned {$t->result}");
+        }
+        
+      
+        if (!isset($roo->transObj)) {
+            $t = DB_DataObject::factory('itemlocdist');
+            $t->query('COMMIT');
+        }
+    
+        
+        
+        
+        
+        
+        $roo->addEvent("POSTED", $this);
+        
+        
+        
+        $roo->jok($t->result);
+        
+        
+        
+    }
+    function toPDF($roo, $version = '1')
+    {
+        
+        $db = substr($this->database(),-2);
+        if ($version !== '1') {
+          //  var_dump($version);
+            $db = $version;
+        }
+        
+        require_once 'Pman/Xtuple/Print.php';
+        $x = new Pman_Xtuple_Print();
+        $x->toPdf(array(
+             'param' => "invchead_id:integer='{$this->invchead_id}'",
+            'template' => 'Invoice-' . $db,
+            
+            
+        ), 'Invoice-' . $this->invchead_id);
+        
+        exit;
+    }
+    
+    /**
+     * used by shiphead => remote post _is_xfer = hk
+     *
+     * used by SG->shipped posted
+     * also by SG locally for CM posted
+     */
+    
+    function handleXfer($roo, $r)
+    {
+       // return print_r($r,true) ;
+        
+        // first off see if the invoice exists...
+        $num = $this->escape($r['invchead_invcnumber']);
+        
+        
+        $q= DB_DataObject::Factory('invchead');
+        $q->whereAdd("
+                    invchead_invcnumber = '$num'
+                    OR
+                    invchead_invcnumber like '$num-%'
+                    AND
+                    invchead_void = false
+        ");
+        if($q->count()) {
+            return
+            "A posted transfer already exists with the reference $num,
+                you will have to log into the main system and void it";
+        }
+        
+        
+        
+        
+        $q= DB_DataObject::Factory('invchead');
+        $q->whereAdd("
+                    invchead_invcnumber = '$num'
+                    OR
+                    invchead_invcnumber like '$num-%'
+        ");
+        $q->selectAdd();
+        $q->selectAdd('invchead_invcnumber');
+        $q->orderBy('invchead_invcnumber DESC');
+        $q->limit(1);
+        $snum = '';
+        if ($q->find(true)) {
+            $suf = strlen($q->invchead_invcnumber, strlen($num));
+            $snum = strlen($suf) ? '-' . array_pop(explode('-', $suf)) : '-1';
+                
+        }
+        
+        
+        
+        $num .= $snum; /// got the invoice number with correct suffix now.
+        //return "using $num";
+        // next step create the invoice..
+        $ih = DB_DataObject::Factory('invchead');
+        
+        $ih->setFrom($r);
+        $ih->setFrom(array(
+        
+           'invchead_invcnumber' => $num,
+           //'invchead_cust_id' => $cust_id , << shouuld we validate this??
+           'invchead_posted' => false,
+           'invchead_printed' => false,
+           'invchead_commission' => 0,
+           'invchead_freight' => 0,
+           'invchead_misc_amount' => 0,
+           'invchead_shipchrg_id' => -1,
+           
+        ));
+        $cust = false;
+        // work out the customer.. based on the database and currency = usd..
+        if (empty($r['cust_number']) && $r['_is_xfer']) {
+            
+            $cur = DB_DataObject::factory('curr_symbol');
+            $cur->get('curr_name', 'USD');
+            
+            // set the currency here..
+            $ih->invchead_curr_id = $cur->pid();
+            
+            $custinfo = DB_DataObject::Factory('custinfo');
+            $cust = $custinfo->findInternal($target_office, $cur);
+            
+            
+        }
+        
+        
+        
+        if (!$cust && empty($r['cust_number'])) {
+            $roo->jerr("missing customer number");
+        }
+        if (!$cust) {
+            $cust=  DB_DataObject::factory('custinfo');
+            if (!$cust->get('cust_number',$r['cust_number'])) {
+                $roo->jerr("could not find customer number {$r['cust_number']}");
+            }
+        }
+        $ih->invchead_cust_id = $cust->pid();
+        
+        
+        
+        $ih->insert();
+        // we have created our head now..
+        //return print_R($r,true);
+         
+        $i =0;
+        foreach($r['items'] as $inum => $qty)  {
+            
+            $i++;
+            $linenumber = $i;
+            $price = false; 
+            $item_number = $inum;
+            $xf_qty = $qty;
+            if (is_array($qty)) {
+                
+                $linenumber   = $qty['linenumber'];
+                $xf_qty       = $qty['qty'];
+                $price        = $qty['unitprice'];
+                $item_number  = $qty['item_number'];
+                
+            }
+            $it = DB_DataObject::Factory('item');
+            $it->item_number = $item_number;
+            if (!$it->find(true)) {
+                $roo->jerr( "Could not find item $item_number");
+                
+            }
+            if ($price === false) {
+                $roo->jerr("No price for $inum");
+                //$this->sqlValue("stdcost({$it->pid()})");
+            }
+            
+            //$inum = $this->escape($item_number);
+            //DB_DataObject::DebugLevel(1);
+           
+            
+            $ii = DB_DataObject::Factory('invcitem');
+            $ii->setFrom(array( 
+             
+             
+                /*
+                    12218, 903, '1',
+            369, 35,  '',
+            '', -1,  '',
+            1, 1, FALSE,
+            4, 1,  0,
+            110,  4, 1,
+            '',   NULL);
+                */
+                
+                'invcitem_invchead_id' => $ih->pid(),
+                'invcitem_linenumber' =>$linenumber,
+                
+                'invcitem_item_id' => $it->pid(),
+                //invcitem_warehous_id
+                'invcitem_number' => '', //?? needed?
+                
+                'invcitem_descrip' => $it->item_descrip1,
+                'invcitem_salescat_id' => -1, 
+                'invcitem_custpn' => '',
+                
+                'invcitem_ordered' => $xf_qty,
+                'invcitem_billed' => $xf_qty,
+                'invcitem_updateinv' => true,  // << do not bother updating inv...!!!
+                
+                'invcitem_qty_uom_id' => $it->item_price_uom_id,
+                'invcitem_qty_invuomratio' => 1,
+                //'invcitem_custprice' => 0 << calced..
+                
+                //'invcitem_price' => $ir['rate'],
+                'invcitem_price_uom_id' => $it->item_price_uom_id,
+                'invcitem_price_invuomratio' => 1,
+                
+                'invcitem_notes' => '',
+                //'invcitem_taxtype_id' => $ir[''],
+                
+                'invcitem_updateinv' => true, // IMPORTANT!!!
+            ));
+            $ii->invcitem_custprice = $price;
+            $ii->invcitem_price = $price;
+            
+            $ii->invcitem_warehous_id = $ii->sqlValue('(SELECT warehous_id FROM whsinfo ORDER by warehous_id LIMIT 1)');
+            $ii->invcitem_taxtype_id =$ii->sqlValue( "gettaxtypeid('Taxable'::text)");
+            $ii->insert();
+            
+        }
+        if (empty($r['src_location'])) {
+            $roo->jerr("no source location specified");
+        }
+        $loc = DB_DataObject::Factory('location');
+        //DB_DataObject::DebugLevel(1);
+        if (!$loc->get('location_name',  $r['src_location'])) {
+            $roo->jerr( "invalid location");
+        }
+         
+         
+        $ih->post($roo, $loc->pid());
+         
+        return true; // we succeeded..
+        
+    }
+    
+    function createFromTransfer($roo,$target_office, $trans, $items)
+    {
+         
+        $source_office = substr($this->database(),-2);
+        
+        
+            // first off see if the invoice exists...
+        $num = 'XF-'.
+                strtoupper($source_office) .
+                '-'.
+                strtoupper($target_office) .
+                '-'.
+                $trans->invhist_transfer_number;
+        
+        
+        $q= DB_DataObject::Factory('invchead');
+       
+        if ($q->get('invchead_ordernumber',  $num)) {  
+            $roo->jerr(
+                "A posted transfer already exists with the reference $num"
+            );
+        }
+        
+        $q= DB_DataObject::Factory('invchead');
+        $q->query("SELECT fetchInvcNumber() as nextinv");
+        $q->fetch();
+        $invnumber = $q->nextinv;
+        
+        $cust = $trans->location_to()->customer();
+        
+        if (!$cust) {
+            $roo->jerr("could not find customer");
+        }
+        
+        $cur = $cust->priceListCurrency($roo);
+        
+        $ih = DB_DataObject::Factory('invchead');
+        
+        $dt = date('Y-m-d', strtotime($trans->invhist_transfer_transdate));
+        
+        $ih->setFrom(array(
+            'invchead_ordernumber' =>$num,
+            'invchead_invcnumber' => $invnumber,
+           
+           
+              
+            'invchead_orderdate' => $dt,
+            'invchead_invcdate' => $dt,
+            'invchead_cust_id' => $cust->pid() ,
+          
+            'invchead_curr_id' => $cur->pid(),
+           
+            'invchead_notes' => 'Created from Transfer: '. $trans->invhist_transfer_number,
+     
+           
+             'invchead_posted' => false,
+            'invchead_printed' => false,
+            'invchead_commission' => 0,
+            'invchead_freight' => 0,
+            'invchead_misc_amount' => 0,
+            'invchead_shipchrg_id' => -1,
+           
+        ));
+        
+        
+        
+        $ih->insert();
+        
+        $loc_from = $trans->location_from();
+        
+        
+        // grab all the items and itemsites..
+        foreach($items as $item) {
+            $item = (object) $item;
+            $itemsites[] = $item->_itemsite_id;
+        }
+        $itemsite = DB_DATaObject::Factory('itemsite');
+        $itemsite->whereAddIn('itemsite_id', $itemsites,'int');
+        $itemsite->autoJoin();
+        $itemsites = $itemsite->fetchAll();
+        foreach($itemsites as $i) {
+            $ismap[$i->pid()] = $i;
+        }
+        
+        
+        
+        foreach($items as $item) {
+            $item = (object) $item;
+            /*
+                'line' => $row->invhist_transfer_item_line,
+                'item_number' => $row->item_number,
+                _itemsite_id
+                'qty' => $row->invhist_transfer_item_qty,
+                'cost' => $row->item_stdcost,
+                'currency' => $base_cur->curr_name,
+            */
+            if (!isset($ismap[$item->_itemsite_id])) {
+                $roo->jerr("invalid itemsite? ". $item->_itemsite_id);
+            }
+            $is = $ismap[$item->_itemsite_id];
+            
+        // we have created our head now..
+        //return print_R($r,true);
+         
+           $ii = DB_DataObject::Factory('invcitem');
+            $ii->setFrom(array( 
+             
+             
+                /*
+                    12218, 903, '1',
+            369, 35,  '',
+            '', -1,  '',
+            1, 1, FALSE,
+            4, 1,  0,
+            110,  4, 1,
+            '',   NULL);
+                */
+                
+                'invcitem_invchead_id' =>   $ih->pid(),
+                'invcitem_linenumber' =>    $item->line,
+                
+                'invcitem_item_id' =>       $is->itemsite_item_id,
+                //invcitem_warehous_id
+                'invcitem_number' => '', //?? needed?
+                
+                'invcitem_descrip' =>       $is->itemsite_item_id_item_descrip1,
+                'invcitem_salescat_id' => -1, 
+                'invcitem_custpn' => '',
+                
+                'invcitem_ordered' => $item->qty,
+                'invcitem_billed' => $item->qty,
+                'invcitem_updateinv' => true,  // << do not bother updating inv...!!!
+                
+                'invcitem_qty_uom_id' => $is->itemsite_item_id_item_price_uom_id,
+                'invcitem_qty_invuomratio' => 1,
+                //'invcitem_custprice' => 0 << calced..
+                
+                //'invcitem_price' => $ir['rate'],
+                'invcitem_price_uom_id' =>$is->itemsite_item_id_item_price_uom_id,
+                'invcitem_price_invuomratio' => 1,
+                
+                'invcitem_notes' => '',
+                //'invcitem_taxtype_id' => $ir[''],
+                
+                'invcitem_updateinv' => true, // IMPORTANT!!!
+            ));
+            $ii->invcitem_custprice = $item->cost;
+            $ii->invcitem_price = $item->cost;
+            
+            $ii->invcitem_warehous_id = $ii->sqlValue('(SELECT warehous_id FROM whsinfo ORDER by warehous_id LIMIT 1)');
+            $ii->invcitem_taxtype_id = $ii->sqlValue( "gettaxtypeid('Taxable'::text)");
+            $ii->insert();
+            
+        }
+        if (empty($loc_from)) {
+            $roo->jerr("no source location specified");
+        }
+         
+         
+        $ih->post($roo, $loc_from->pid());
+         
+        return true; // we succeeded..
+        
+        
+    }
+    
+    
+    
+    
+    function aropen()
+    {
+        $d = DB_DataObject::factory('aropen');
+        $d->aropen_doctype = 'I';
+        if ($d->get('aropen_docnumber', $this->invchead_invcnumber)) {
+            return $d;
+        }
+        return false;
+        
+    }
+    
+}
diff --git a/DataObjects/Invcheadtax.php b/DataObjects/Invcheadtax.php
new file mode 100644 (file)
index 0000000..0cab99d
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for invcheadtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invcheadtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invcheadtax';         // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Invcitem.php b/DataObjects/Invcitem.php
new file mode 100644 (file)
index 0000000..ed0a549
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Table Definition for invcitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invcitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invcitem';            // table name
+    public $invcitem_id;                     // int4(4)  not_null default_nextval%28invcitem_invcitem_id_seq%29 primary_key
+    public $invcitem_invchead_id;            // int4(4)  not_null unique_key multiple_key
+    public $invcitem_linenumber;             // int4(4)  unique_key multiple_key
+    public $invcitem_item_id;                // int4(4)  multiple_key
+    public $invcitem_warehous_id;            // int4(4)  multiple_key
+    public $invcitem_custpn;                 // text(-1)  
+    public $invcitem_number;                 // text(-1)  
+    public $invcitem_descrip;                // text(-1)  
+    public $invcitem_ordered;                // numeric(-1)  not_null
+    public $invcitem_billed;                 // numeric(-1)  not_null
+    public $invcitem_custprice;              // numeric(-1)  
+    public $invcitem_price;                  // numeric(-1)  not_null
+    public $invcitem_notes;                  // text(-1)  
+    public $invcitem_salescat_id;            // int4(4)  
+    public $invcitem_taxtype_id;             // int4(4)  
+    public $invcitem_qty_uom_id;             // int4(4)  
+    public $invcitem_qty_invuomratio;        // numeric(-1)  not_null
+    public $invcitem_price_uom_id;           // int4(4)  
+    public $invcitem_price_invuomratio;      // numeric(-1)  not_null
+    public $invcitem_coitem_id;              // int4(4)  
+    public $invcitem_updateinv;              // bool(1)  default_false
+
+    
+   /**
+    * Getter / Setter for $invcitem_invchead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invchead() {
+        return func_num_args() ? $this->link('invcitem_invchead_id', func_get_arg(0)) : $this->link('invcitem_invchead_id');
+    }
+
+   /**
+    * Getter / Setter for $invcitem_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('invcitem_price_uom_id', func_get_arg(0)) : $this->link('invcitem_price_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $invcitem_qty_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qty_uom() {
+        return func_num_args() ? $this->link('invcitem_qty_uom_id', func_get_arg(0)) : $this->link('invcitem_qty_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $invcitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('invcitem_taxtype_id', func_get_arg(0)) : $this->link('invcitem_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        $this->joinAddItem();
+    }
+    
+    function joinAddItem()
+    {
+        $i = DB_DataObject::Factory('item');
+        $this->_join .= '
+            LEFT JOIN
+                item join_invcitem_item_id_item_id
+            ON
+                invcitem_item_id = item_id
+                ';
+        $this->selectAs($i, 'invcitem_item_id_%s',  'join_invcitem_item_id_item_id');
+        
+    }
+    
+    
+    
+    
+}
diff --git a/DataObjects/Invcitemtax.php b/DataObjects/Invcitemtax.php
new file mode 100644 (file)
index 0000000..e233249
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for invcitemtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invcitemtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invcitemtax';         // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Invcnt.php b/DataObjects/Invcnt.php
new file mode 100644 (file)
index 0000000..f0b7880
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Table Definition for invcnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invcnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invcnt';              // table name
+    public $invcnt_id;                       // int4(4)  not_null default_nextval%28%28invcnt_invcnt_id_seq%29%3A%3Aregclass%29 primary_key
+    public $invcnt_itemsite_id;              // int4(4)  
+    public $invcnt_tagdate;                  // timestamptz(8)  
+    public $invcnt_cntdate;                  // timestamptz(8)  
+    public $invcnt_qoh_before;               // numeric(-1)  
+    public $invcnt_qoh_after;                // numeric(-1)  
+    public $invcnt_matcost;                  // numeric(-1)  
+    public $invcnt_posted;                   // bool(1)  
+    public $invcnt_postdate;                 // timestamptz(8)  
+    public $invcnt_comments;                 // text(-1)  
+    public $invcnt_priority;                 // bool(1)  
+    public $invcnt_tagnumber;                // text(-1)  
+    public $invcnt_invhist_id;               // int4(4)  
+    public $invcnt_location_id;              // int4(4)  
+    public $invcnt_cnt_username;             // text(-1)  
+    public $invcnt_post_username;            // text(-1)  
+    public $invcnt_tag_username;             // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Invdetail.php b/DataObjects/Invdetail.php
new file mode 100644 (file)
index 0000000..677cc2c
--- /dev/null
@@ -0,0 +1,1252 @@
+<?php
+/**
+ * Table Definition for invdetail
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invdetail extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invdetail';           // table name
+    public $invdetail_id;                    // int4(4)  not_null default_nextval%28%28%22invdetail_invdetail_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $invdetail_transtype;             // bpchar(-1)  
+    public $invdetail_invhist_id;            // int4(4)  
+    public $invdetail_location_id;           // int4(4)  
+    public $invdetail_qty;                   // numeric(-1)  
+    public $invdetail_comments;              // text(-1)  
+    public $invdetail_qty_before;            // numeric(-1)  
+    public $invdetail_qty_after;             // numeric(-1)  
+    public $invdetail_invcitem_id;           // int4(4)  
+    public $invdetail_expiration;            // date(4)  
+    public $invdetail_warrpurc;              // date(4)  
+    public $invdetail_ls_id;                 // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (!empty($q['cohead_id'])) {
+            $this->coheadView($q,$roo);
+            return;
+             
+        }
+        if (!empty($q['_summary_at_date'])) {
+            $this->summaryAtDate($q,$roo);
+            return;
+        }
+        
+        if (!empty($q['_fifo_fill'])) {
+            return $this->fifoFill($roo, $q);
+        }
+       // DB_DataObject::debugLevel(1);
+        
+        $this->autoJoinItem();
+
+       
+        $id = DB_DataObject::Factory('location');
+        $this->_join .= "
+            LEFT JOIN location AS join_location ON
+               invdetail.invdetail_location_id = join_location.location_id";
+        $this->selectAs($id, '%s', 'join_location');
+        
+        
+        
+        
+        // need for sorting..        
+       
+        
+        if (isset($q['query']['endDateSel'])){
+            $end = empty($q['query']['endDateSel']) ? "2100-01-01" : "{$this->escape($q['query']['endDateSel'])}";
+            $this->whereAdd("join_invhist.invhist_transdate <= '{$end}'::date");
+        }
+        
+        if(!empty($q['query']['dateSel'])){
+            $this->whereAdd("join_invhist.invhist_transdate >= '{$this->escape($q['query']['dateSel'])}'::date");
+        }
+        
+        /* both have $q['query']['item_number'] ..
+         * 
+         * 
+         * $q['invdetail_location_id'] && $q['query']['dateSel'] for Manage Xtuple Inventory History
+         * 
+         * $q['query']['location_name'] && $q['search']['item'] for Sales Quick Stock Check
+         * 
+         */
+        // you must have at least one of these set..
+        // so if the are all empty t
+        
+        
+        if (
+             empty($q['query']['item_number'])
+             &&
+             empty($q['invdetail_location_id'])
+             &&
+             empty($q['query']['dateSel'])
+             &&
+             empty($q['query']['endDateSel'])
+             &&
+             empty($q['query']['location_name'])
+             &&
+             empty($q['search']['item']) 
+             
+            ) {
+            // this kind of query is too slow..
+            $this->whereAdd('1=0');
+            return;
+        }
+        
+        if (!empty($q['query']['item_number'])) {
+            $in = $this->escape($q['query']['item_number']);
+            
+            $this->whereAdd("join_invhist.invhist_itemsite_id = (
+                          SELECT itemsite_id FROM itemsite where itemsite_item_id =
+                            ( SELECT item_id FROM item where item_number ='$in' LIMIT 1  )
+                          LIMIT 1
+                            
+                        )");
+            
+        }
+        
+        if (!empty($q['search']['item'])) {
+            $in = $this->escape($q['search']['item']);
+            
+            $this->whereAdd("join_invhist.invhist_itemsite_id IN (
+                          SELECT itemsite_id FROM itemsite where itemsite_item_id IN
+                            (
+                                SELECT item_id FROM item
+                                    where
+                                        item_number ilike '%$in%'
+                                        OR
+                                        item_descrip1 ilike '%$in%'
+                                         
+                            )
+                          
+                            
+                        )");
+            
+        }
+        
+        
+        if (!empty($q['query']['location_name'])) {
+            $in = $this->escape($q['query']['location_name']);
+            
+            $this->whereAdd("join_location.location_name = '$in' ");
+            
+        }
+        
+        if (!empty($q['query']['item_number'])  || !empty($q['query']['location_name'])) {
+            $this->selectAdd('invdetail_bydate(invdetail_id) AS  invdetail_bydate_qty');
+        }
+        
+        if (!empty($q['query']['viewtype'])) {
+            switch($q['query']['viewtype']) {
+                case 'IN':
+                    $this->whereAdd('invdetail_qty > 0');
+                    $this->whereAdd('
+                        invfifo_void IS NULL OR invfifo_void = 0
+                     ');
+                    break;
+                case 'OUT':
+                    $this->whereAdd('invdetail_qty < 0');
+                    $this->whereAdd('
+                        invfifo_void IS NULL OR invfifo_void = 0
+                                 ');
+                    break;
+                
+                case 'BOTHALL':
+                    
+                    break;
+                
+                case 'BOTH':
+                    $this->whereAdd('
+                        invfifo_void IS NULL OR invfifo_void = 0
+                                 ');
+                    
+                default:
+                        break;
+            }
+        }
+        if (!empty($q['_hide_void'])) {
+                $this->whereAdd('
+                    invfifo_void IS NULL OR invfifo_void = 0
+                                 ');
+            
+        }
+        
+        if(!empty($q['_asExcel'])){
+            $this->selectAdd();
+            $ar = array();
+            foreach($q['csvCols'] as $c) {
+                if ($c=='invdetail_balance_qty') {
+                    continue;
+                }
+                $ar[] = $c;
+            }
+            $this->selectAdd(implode(',', $ar));
+        }
+        
+        if(!empty($q['_with_balance'])){
+            $this->selectAdd('0 as  invdetail_balance_qty'); // done in postlistfilter for spped
+            $this->_extra_cols[] = 'invdetail_balance_qty';
+        }
+        
+        $this->selectAdd("
+            regexp_replace(join_invhist.invhist_ordnumber, '-[0-9]+$', '') as invhist_ordernumber
+        ");
+         
+    }
+    
+    function summaryAtDate($q,$roo)
+    {
+        
+        $dt = date('Y-m-d', strtotime($q['_summary_at_date']));
+        //$this->autoJoin();
+        
+        $this->autoJoinItem();
+        $this->autoJoinLocation();
+       
+        $this->whereAdd("
+                        invhist_transdate::date <= '$dt'
+                        AND
+                        invhist_posted
+                        AND
+                        invfifo_void = 0
+                    ");
+        //$this->having("sum(invdetail_qty) <>  0");
+        $this->selectAdd();
+        $this->selectAdd("
+            item_id,
+            item_number,
+            item_descrip1,
+            location_name,
+            sum(invdetail_qty) as stock_qty,
+            sum(invdetail_qty) * stdcost(item_id) as stdcost_value,
+            sum(invdetail_qty * invfifo_landedunitcost) as fifo_value
+            
+                         
+        ");
+        $this->groupBy('item_number, location_name,item_descrip1, item_id');
+        $this->_extra_cols = array('item_number','location_name');
+        
+        
+      
+    }
+    function postListFilter($data, $au, $q)
+    {
+        if (empty($data)) {
+            return $data;
+        }
+        if (!empty($q['_with_balance']) && count($data)) {
+            //DB_DataObject::debugLevel(1);
+            $ids= array();
+            foreach($data as $i=>$d) {
+                $ids[] = $d['invdetail_id'];
+            }
+            
+            $lk = DB_DataObject::Factory('invdetail');
+            $lk->selectAdd();
+            $lk->selectAdd('invdetail_id, invdetail_qty_at_id(invdetail_id) AS invdetail_balance_qty');
+            $lk->whereAddIn('invdetail_id', $ids, 'int');
+            $ar = $lk->fetchAll('invdetail_id', 'invdetail_balance_qty'); 
+            
+            foreach($data as $i=>$d) {
+                
+                if (isset($ar[$d['invdetail_id']])) {
+                    //echo "setting qty\n";
+                    $data[$i]['invdetail_balance_qty'] = $ar[$d['invdetail_id']];
+                    $data[$i]['invdetail_before_qty'] = $ar[$d['invdetail_id']] - $data[$i]['invdetail_qty'];
+                }
+            }
+        }
+          
+        
+        //die("plf");
+        if (empty($q['_with_empty_stock'])) {
+            return $data;
+        }
+        $ids = array();
+        foreach($data as $d) {
+            $ids[] = $d['item_id'];
+        }
+        $p = DB_DataObject::Factory('item');
+        $p->item_type = 'P';
+        $p->orderBy('item_number ASC');
+        $p->whereAddIn('!item_id', $ids, 'int');
+        foreach($p->fetchAll() as $p) {
+            $data[] = array(
+                'item_id' => $p->item_id,
+                'item_number' => $p->item_number,
+                'item_descrip1' => $p->item_descrip1,
+                'stock_qty' => '0',
+                'location_name' => ' ',
+                'stdcost_value' => ' ',
+                'fifo_value' => ' ',
+                
+            );
+            
+        }
+        
+        return $data;
+        
+        
+        
+        
+    }
+    function applySort($au, $sort, $dir, $cols, $ms)
+    {
+        if ($sort == 'invhist_transdate') {
+            $this->orderBY("invhist_transdate $dir, invdetail_id $dir");
+            return true;
+        }
+        return false;
+    }
+      
+    function beforeInsert($q, $roo)
+    {
+        if (!empty($q['_reverse'])) {
+            $inv  = DB_DataObject::Factory($this->tableName());
+            $inv->autoJoin();
+            
+            $inv->autoJoinItem();
+            $inv->get($q['_reverse']);
+            $inv->reverse($roo,$q);
+            $roo->jok("done");
+        }
+        
+         if (!empty($q['_reverse_all_bad'])) {
+            $inv  = DB_DataObject::Factory($this->tableName());
+            $inv->reverseAllBad($roo, $q['_reverse_all_bad']);
+            
+            $roo->jok("done");
+        }
+        
+        
+        if (!empty($q['_duplicate'])) {
+            $inv  = DB_DataObject::Factory($this->tableName());
+            $inv->autoJoin();
+            
+            $inv->autoJoinItem();
+            $inv->get($q['_duplicate']);
+            $inv->duplicate($roo);
+            $roo->jok("done");
+        }
+        
+        
+        $roo->jerr("you can not insert directly!");
+        
+        
+    }
+    
+    function beforeUpdate($old, $q, $roo)
+    {
+        
+        $roo->jerr("you can not update directly!");
+        
+        
+    }
+    
+    function coheadView($q,$roo)
+    {
+        
+        if (!empty($q['itemsite_id'])) {
+            return $this->coheadViewDetail($q,$roo);
+        }
+        
+        $cohead_id =(int) $q['cohead_id'];
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        
+        
+       // $this->autoJoin();
+        $this->autoJoinItem();
+        
+       
+        $this->selectAdd();
+        $this->selectAdd("
+            invhist_itemsite_id,
+            join_item.item_number as item_number,
+            COALESCE ((SELECT
+                        SUM(coitem_qtyreturned)
+                    FROM
+                        coitem
+                    WHERE
+                        coitem_cohead_id = $cohead_id
+                    and
+                        coitem_itemsite_id = invhist_itemsite_id
+            ) ,0) AS rec_returned,
+            COALESCE ((SELECT
+                        SUM(coitem_qtyshipped)
+                    FROM
+                        coitem
+                    WHERE
+                        coitem_cohead_id = $cohead_id
+                    and
+                        coitem_itemsite_id = invhist_itemsite_id
+            ), 0) AS rec_shipped,
+            
+            COALESCE(SUM(invdetail_qty),0) as tx_total,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_shipped,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_returned,
+            
+            COALESCE(SUM(invdetail_qty * invhist_unitcost),0) as total_value
+            
+            
+        ");
+        
+        // add the sum of the gls...
+        
+        
+        
+        $this->whereAdd("
+           
+                invhist_ordtype = 'SO'
+                AND
+                (
+                    invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+                    OR
+                    invhist_ordnumber ='{$cohead->escape($cohead->cohead_number)}'
+                )
+        ");
+         $this->orderBy(" join_item.item_number ASC");
+         $this->groupBy("invhist_itemsite_id, join_item.item_number");
+            
+        
+        
+        
+    }
+    
+     
+    function coheadViewDetail($q,$roo)
+    {
+        
+        $cohead_id =(int) $q['cohead_id'];
+        $itemsite = (int) $q['itemsite_id'];
+        
+        
+        
+        $ci = $this->factory('coitem');
+        $ci->query("
+            SELECT invfifo_cohead_void_flag({$cohead_id}, {$itemsite})
+        ");
+        $ci->fetch();
+        
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        
+        //$this->autoJoin();
+        
+        $this->autoJoinItem();
+        
+       // just show the raw transactions...
+        
+        $this->whereAdd("
+           
+                invhist_ordtype = 'SO'
+                AND
+                (
+                    invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+                    OR
+                    invhist_ordnumber ='{$cohead->escape($cohead->cohead_number)}'
+                )
+                AND
+                invhist_itemsite_id = $itemsite 
+        ");
+        
+        $this->selectAdd("
+                           
+            ROUND(COALESCE((SELECT SUM(COALESCE(coitem_qtyreturned,0) - COALESCE(coitem_qtyshipped,0) ) from coitem
+                where coitem_cohead_id = $cohead_id
+                AND
+                coitem_linenumber =  SPLIT_PART(SUBSTRING(invhist_ordnumber, " . (strlen($cohead->cohead_number) + 2) . "), '.', 1)::INTEGER
+                AND
+                coitem_subnumber =   (0 || SPLIT_PART(SUBSTRING(invhist_ordnumber, " . (strlen($cohead->cohead_number) + 2) . "), '.', 2))::INTEGER
+                
+                
+            ),0),0) AS coitem_shipped
+
+        ");
+        $this->_extra_cols = array('coitem_shipped');
+        $this->orderBy(" invhist_ordnumber ASC ");
+        
+        // what we will need to see:
+        
+            
+        
+        
+        
+    }
+    
+    function autoJoin()
+    {
+        $ret = parent::autoJoin();
+        // does not add these cols to 'ret'..
+        $this->autoJoinInvhist();
+        $this->autoJoinFifo();
+        return $ret;
+    }
+    
+    
+    function autoJoinInvhist()
+    {
+        $id = DB_DataObject::Factory('invhist');
+        $this->_join .= "
+            LEFT JOIN invhist AS join_invhist ON
+               invdetail.invdetail_invhist_id = join_invhist.invhist_id";
+        $this->selectAs($id, '%s', 'join_invhist');
+        
+        $this->_extra_cols = empty($this->_extra_cols) ? array() : $this->_extra_cols ;
+        $this->_extra_cols[] = 'invhist_created';
+        $this->_extra_cols[] = 'invhist_transdate';
+        
+        
+        
+    }
+    function autoJoinLocation()
+    {
+        $id = DB_DataObject::Factory('location');
+        $this->_join .= "
+            LEFT JOIN location AS join_location ON
+               invdetail.invdetail_location_id = join_location.location_id";
+        $this->selectAs($id, '%s', 'join_location');
+        
+        
+    }
+    
+    function autoJoinfifo()
+    {
+        $id = DB_DataObject::Factory('invfifo');
+        $this->_join .= "
+            LEFT JOIN invfifo AS join_invfifo ON
+               invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id";
+        $this->selectAs($id, '%s', 'join_invfifo');
+        
+        
+    }
+    
+    function autoJoinHist()
+    {
+        return $this->autoJoinInvhist();
+        
+        
+        
+    }
+    
+    function autoJoinItem()
+    {
+        $id = DB_DataObject::Factory('itemsite');
+        $this->_join .= "
+            LEFT JOIN itemsite AS join_itemsite  ON
+               join_invhist.invhist_itemsite_id = join_itemsite.itemsite_id";
+        $this->selectAs($id, '%s', 'join_itemsite');
+        
+        
+        $id = DB_DataObject::Factory('item');
+        $this->_join .= "
+            LEFT JOIN item AS join_item  ON
+               join_itemsite.itemsite_item_id = join_item.item_id";
+        $this->selectAs($id, '%s', 'join_item');
+        
+        
+        
+    }
+    
+    function fifoFill($roo, $q)
+    {
+        
+        
+        
+        $lquery = '1=1';
+        $iquery = '1=1';
+        
+        $after = 'true';
+        
+        if (!empty($q['location_id']) || !empty($q['item_number'])) {
+            // doing for a specifc location or item number - do not update afterwards
+            // as we will go through and call again..
+            $after = 'false';
+        }
+        if (!empty($q['location_id']) ) {
+            $l = DB_DataObject::Factory('location');
+            if (!$l->get($q['location_id'] )) {
+                $roo->jerr("invalid location?");
+            }
+            $lquery = 'invdetail_location_id = '. $l->pid();
+            
+            //$after = 'false';
+        }
+        if (! empty($q['item_number'])) {
+            
+            $l = DB_DataObject::Factory('item');
+            if (!$l->get('item_number',$q['item_number'] )) {
+                $roo->jerr("invalid item number?");
+            }
+            $its = $l->itemsite();
+            $iquery = 'invhist_itemsite_id = '. $its->pid();
+            
+            //$after = 'false';
+            
+            
+        }
+        
+        $t = clone($this);
+        $t->whereAdd(" $iquery AND $lquery");
+        $total = $t->count();
+        
+        
+        
+        $offset = empty($q['offset']) ? 0 : (int) $q['offset'];
+        
+        if ($offset > $total) {
+            $roo->jerr("DONE"); //???
+        }
+        
+        
+        
+        //var_dump($q['_fifo_fill']);
+        
+        if ($q['_fifo_fill'] > 1) {
+                $limit =   50;
+                $update_after = 'true';
+                if (empty($q['location_id'])) {
+                    $update_after = 'false';
+                }
+                
+                
+               $this->query("
+                SELECT  invfifo_update_from_invdetail(invdetail_id,{$update_after}) FROM (
+                    SELECT
+                            invdetail_id
+                        FROM
+                            invdetailview
+       
+                        WHERE
+                            $lquery
+                            AND
+                            $iquery
+                        ORDER BY
+                            invhist_transdate ASC,
+                            invdetail_id ASC
+                        LIMIT
+                            $limit OFFSET $offset
+                    ) x;
+            ");
+            
+            
+            
+        } else {
+            
+            $limit = 200;
+            $this->query("
+                SELECT invfifo_fill(invdetail_id, $after) FROM (
+                    SELECT
+                            invdetail_id
+                        FROM
+                            invdetailview
+       
+                        WHERE
+                            $lquery
+                            AND
+                            $iquery
+                        ORDER BY
+                            invhist_transdate ASC,
+                            invdetail_id ASC
+                        LIMIT
+                            $limit OFFSET $offset
+                    ) x;
+            ");
+        }
+        $roo->jok(array('total' => $total, 'limit'=>$limit, 'offset' => $offset));
+        
+        
+        
+    }
+    // needs the join!
+    function itemsite()
+    {
+        $is = DB_DataObject::factory('itemsite');
+        $is->get($this->invhist_itemsite_id);
+        return $is;
+    }
+    
+    
+    function duplicate($roo,$q)
+    {
+        
+        $roo->jerr("Disabled");
+        // this is needed as we messed up the shipping.
+        // it should only handle shipment mess initially..
+        //print_R($this);exit;
+        if ($this->invhist_ordtype != 'SO') {
+            $roo->jerr("only handles sales order reversals.");
+        }
+        if ( $this->invdetail_qty > 0) {
+            $roo->jerr("only duplicates deliveries.");
+            
+        }
+        $this->reverseReturn($roo);
+    }
+        
+    /**
+     *
+     * 
+     *
+     */
+    
+    // make this the generic 'reverse'....      
+    function reverse($roo,$q)
+    {
+        //DB_DataObject::debugLevel(1);
+        
+        if ($this->invhist_ordtype != 'SO') {
+            $roo->jerr("only handles sales order reversals.");
+        }
+        
+        
+        $is = $this->itemsite();
+        $item = $is->item();
+        $costcat = $is->costcat();
+        
+        
+        // do some sanity checks...
+        
+        //DB_DataObject::DebugLevel(1);
+        
+        
+        
+        // there is a case where coitem was deleted, and we need to reverse it..
+        // the aim here is to temporary create it if necessary.
+        
+        list($ord,$num) = explode('-', $this->invhist_ordnumber);
+        $num = explode('.', $num);
+        $num = $num[0];
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        if (!$cohead->get('cohead_number',$ord)) {
+            $roo->jerr("can not find order!?");
+        }
+        
+        // what is the total sum of recieved / returned items..
+        // if it matches our totals for database on this - then do not allow the reversal..
+        
+        $coitem = DB_DataObject::Factory('coitem');
+        $coitem->coitem_cohead_id = $cohead->pid();
+        $coitem->coitem_itemsite_id = $this->invhist_itemsite_id;
+        $coitem->selectAdd();
+        $coitem->selectAdd('COALESCE(sum(coitem_qtyreturned - COALESCE(coitem_qtyshipped,0)),0)  as coitem_balance');
+        
+        $coitem->find(true);
+        $coitem_balance = $coitem->coitem_balance;
+        
+        
+        
+        $ih = DB_DataObject::factory($this->tableName());
+        
+        $ih->autoJoin();
+        $ih->autoJoinItem();
+        
+       // just show the raw transactions...
+        
+        $ih->whereAdd("
+           
+                invhist_ordtype = 'SO'
+                AND
+                (
+                    invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+                    OR
+                    invhist_ordnumber ='{$cohead->escape($cohead->cohead_number)}'
+                )
+                AND
+                invhist_itemsite_id = {$this->invhist_itemsite_id} 
+        ");
+        $ih->selectAdd();
+        $ih->selectAdd('COALESCE(SUM(invdetail_qty), 0) as invhist_balance');
+        $ih->find(true);
+        
+        // current balance (-ve) + abs(this->value) should be less than or equal to real value.
+        
+        // cobalance should be -1 (eg. 1 shipped)
+        // our total might be 0 or
+        
+        
+        // our action will increase the stock level
+        
+        $qty  = $this->invdetail_qty * -1 ; // oposite...
+        $old_value = $this->invhist_value_after - $this->invhist_value_before;
+        $absqty = abs($qty);
+        
+        $distloc_qty = $qty;
+        
+        switch(true) {
+            
+            // couple of weird scenarios..
+            
+            
+            
+            // issue +ve number
+            // issue +ve $value << reverse from/to/accc
+            
+            // return -ve number
+            // return -ve $value << reverse from/to/accc
+            
+            
+            
+            case ($this->invdetail_qty < 0 && $old_value <= 0 && preg_match('/Issue/',$this->invhist_comments)):
+                // was issue..
+                $notes = 'Return from Shipping';
+                
+                $to_acc = $costcat->costcat_shipasset_accnt_id;
+                $from_acc = $costcat->costcat_asset_accnt_id;
+                $rev_id = $this->invhist_id;
+                
+                $qty  = $this->invdetail_qty * -1 ; // oposite...
+                $new_value = $old_value * -1;
+                
+                $tx_type = 'RS';
+                
+                if (!empty($q['_force'])) {
+                    break;
+                }
+                
+                
+                if (($ih->invhist_balance + abs($this->invdetail_qty) > $coitem_balance)) {
+                    $roo->jerr("reversing this will cause stock to increase beyond balance",array('confirm' => 1));
+                }
+                
+                break;
+            
+            
+            case ($this->invdetail_qty < 0 && $old_value <= 0 && !preg_match('/Issue/',$this->invhist_comments)):
+                // normally was a bad return...
+                $notes = 'Return from Shipping (void)';
+                
+                $tx_type = 'RS';
+                
+                $new_value = $old_value * -1;
+                
+                
+                $from_acc = $costcat->costcat_shipasset_accnt_id;
+                $to_acc = $costcat->costcat_asset_accnt_id;
+                $rev_id = 'NULL';
+                
+                if (!empty($q['_force'])) {
+                    break;
+                }
+                
+                
+                if (($ih->invhist_balance + abs($this->invdetail_qty) > $coitem_balance)) {
+                    $roo->jerr("reversing this will cause stock to increase beyond balance",array('confirm' => 1));
+                }
+                
+                break;
+            
+             case ($this->invdetail_qty  > 0 && $old_value >= 0):
+                // bad returns or bad issues..
+                $notes = "Issue {$item->item_number} to Shipping for Customer";
+                $tx_type = 'SH';
+                 
+                $to_acc = $costcat->costcat_asset_accnt_id;
+                $from_acc = $costcat->costcat_shipasset_accnt_id;
+                
+                $rev_id = 'NULL';
+                
+                $new_value = $old_value * -1;
+                
+                
+                if (!empty($q['_force'])) {
+                    break;
+                }
+                if (($ih->invhist_balance - abs($this->invdetail_qty) < $coitem_balance)) {
+                    $roo->jerr("reversing this will cause stock to decrease beyond balance",array('confirm' => 1));
+                }
+                break;
+            
+            
+            // really buggy...
+            
+            case ($this->invdetail_qty  > 0 && $old_value <= 0):
+                $roo->jerr("still need to fix this - qty > 0 and value < 0");
+                // borked values ... just trying to reverse account to start with...
+                $notes = "Issue {$item->item_number} to Shipping for Customer (void)";
+                
+                $to_acc = $costcat->costcat_asset_accnt_id;
+                $from_acc = $costcat->costcat_shipasset_accnt_id;
+                
+                // prethend it's a return..
+                $tx_type = 'SH';
+                
+                $new_value = $old_value ; // kludge as reverse seems wrong...
+                
+                
+                // we have to revese the qty..
+                $qty *= -1;
+                //$distloc_qty = $qty * -1;
+                
+                $rev_id = $this->invhist_id;
+                if (!empty($q['_force'])) {
+                    break;
+                }
+                if (($ih->invhist_balance - abs($this->invdetail_qty) < $coitem_balance)) {
+                    $roo->jerr("reversing this will cause stock to decrease beyond balance",array('confirm' => 1));
+                }
+                break;
+            
+            
+            case ($this->invdetail_qty  < 0 && $old_value >= 0):
+                
+                //should act as a return.. however the value is broken...
+                
+                
+                // borked values ... just trying to reverse account to start with...
+                
+                $notes = "Return {$item->item_number} to Shipping for Customer (void)";
+                
+                
+                $from_acc = $costcat->costcat_asset_accnt_id;
+                $to_acc = $costcat->costcat_shipasset_accnt_id;
+                
+                // prethend it's a return..
+                $tx_type = 'RS';
+                
+                $new_value = $old_value * -1 ; // kludge as reverse seems wrong...
+                
+                
+                // we have to revese the qty..
+                //$qty *= -1;
+                //$distloc_qty = $qty * -1;
+                
+                $rev_id = 'NULL'; //$this->invhist_id;
+                if (!empty($q['_force'])) {
+                    break;
+                }
+                if (($ih->invhist_balance - abs($this->invdetail_qty) < $coitem_balance)) {
+                    $roo->jerr("reversing this will cause stock to decrease beyond balance",array('confirm' => 1));
+                }
+                break;
+            default:
+                $roo->jerr("not sure how to handle {$this->invdetail_qty}pcs for HKD{$old_value}"); 
+        }
+        
+        //$roo->jerr($notes);
+       
+        
+        
+        
+        
+        
+        
+        $coitem = DB_DataObject::Factory('coitem');
+        $coitem->coitem_cohead_id = $cohead->pid();
+        // we do not handle kits...
+        $coitem->coitem_linenumber = $num;
+        $co_delete  = false;
+        
+        if (!$coitem->find(true)) {
+            // make a fake line item..
+            $coitem->setFrom($coitem->defaults());
+            $coitem->coitem_cohead_id = $cohead->pid();
+            $coitem->coitem_linenumber = $num;
+            $coitem->coitem_qtyord = abs($this->invdetail_qty);
+            $coitem->coitem_price = $coitem->coitem_custprice = abs($this->invhist_unitcost);
+            $coitem->insert();
+            $co_delete = $coitem;
+         
+        }
+        
+        $ci = $this->factory('coitem');
+        $ci->query("SELECT NEXTVAL('itemloc_series_seq')::integer as itemlocseries ");
+        $ci->fetch();
+        $itemlocSeries = $ci->itemlocseries;
+      
+         
+        $unitcost = abs($this->invhist_unitcost);
+        // this is similar to returnshipmenttransaction.
+        
+        
+       //$roo->jerr("FROM $from_acc to $to_acc");
+        
+       $abs_old_value = abs($old_value);
+        
+        // not this uses our modified postinvtrans to ensure the value is based on our
+        // actual cost..
+        $ci = $this->factory('coitem');
+        
+        $date = !empty($q['_as_of']) ? $q['_as_of'] : $this->invhist_transdate;
+        
+        $ci->query("
+            SELECT dragon_postInvTransFixed(
+                    {$this->invhist_itemsite_id},
+                    '{$tx_type}',
+                    $absqty ,
+                    'S/R',
+                    'SO',
+                    '{$this->invhist_ordnumber}',
+                    '{$this->invhist_ordnumber}',
+                   '{$notes}',
+                    {$from_acc},
+                    {$to_acc},
+                  $itemlocSeries,
+                  CAST('{$date}' AS timestamp with time zone),
+                  {$new_value},   -- this is exact value posted  the other end...
+                  {$rev_id}
+            ) AS invhistid
+        ");
+        $ci->fetch();
+        
+        if (empty($ci->invhistid) || $ci->invhistid < 0) {
+            $roo->jerr(" postInvTrans FAILED??\n");
+        }
+        
+        
+        
+        if ($rev_id === 'NULL') { 
+        
+            $d = DB_DataObject::factory('coitem');
+            $d->query("SELECT itemlocdist_id,
+                      itemlocdist_reqlotserial,
+                      itemlocdist_distlotserial,
+                      itemlocdist_qty,
+                      itemsite_loccntrl,
+                      itemsite_controlmethod,
+                      itemsite_perishable,
+                       itemsite_warrpurc,
+                    COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                    COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                    FROM itemlocdist, itemsite
+                    WHERE ( (itemlocdist_itemsite_id=itemsite_id) AND (itemlocdist_series={$itemlocSeries }) ) ORDER BY itemlocdist_id
+                    ");
+            $d->fetch();
+            
+            if (empty( $d->itemlocdist_id) ||  $d->itemlocdist_id < 1) {
+                $roo->jerr("SEARCHING FOR itemlocdist_id  returned { $d->itemlocdist_id}");
+            }
+            
+            $itemlocdist_id = $d->itemlocdist_id;
+   
+           
+           //$roo->jerr("distributing to locations?");
+           
+           
+           $d = DB_DataObject::factory('coitem');
+           $d->query("
+                INSERT INTO itemlocdist (
+                   itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                   itemlocdist_source_id,  itemlocdist_qty,
+                   itemlocdist_ls_id, itemlocdist_expiration
+               ) SELECT
+                   itemlocdist_id,'L',
+                   {$this->invdetail_location_id},       {$qty} ,
+                   itemlocdist_ls_id, endOfTime()
+                   FROM itemlocdist WHERE
+                   (itemlocdist_id={$itemlocdist_id })
+            ");
+           
+           // this generates an additional itemlocdist record..
+           // they throw exceptions if things fail.
+           
+           $d = DB_DataObject::factory('coitem');
+           $d->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+           
+           // that probably throws an exception acording to the recv docs.
+           
+        }
+            
+        
+         // $roo->jerr($ci->invhistid );
+      
+        $ci = $this->factory('coitem');
+        $ci->query("SELECT postItemlocseries({$itemlocSeries}) as result");
+        $ci->fetch();
+        if (empty($ci->result) || !$ci->result ) {
+            $roo->jerr(" UPDATE FAILED??\n ");
+        }
+        // update the flags...
+        
+
+        $ci = $this->factory('coitem');
+        $ci->query("
+            SELECT invfifo_cohead_fix_id(invdetail_id) FROM (select  invdetail_id  FROM invdetailview where invhist_docnumber ='{$this->invhist_ordnumber}') x
+        ");
+        $ci->fetch();
+       
+        if(empty($q['_return_only'])){
+            $ci = $this->factory('coitem');
+            $ci->query("
+                SELECT invfifo_cohead_void_flag({$cohead->pid()}, {$this->invhist_itemsite_id})
+            ");
+            $ci->fetch();
+        }
+        
+       
+        
+        if ($co_delete) {
+            $co_delete->delete();
+        }
+        
+        
+        // do some verification on the value that was posted..
+        
+        if (!empty($roo->cli) || !empty($q['_return_only'])) {
+            return true;
+        }
+        
+        
+        $roo->jok("posted");
+        
+    }
+    function reverseAllBad($roo, $cohead_id) {
+          
+        
+         
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        
+        
+        $this->autoJoin();
+        $this->autoJoinItem();
+        
+       
+        $this->selectAdd();
+        $this->selectAdd("
+            invhist_itemsite_id,
+            join_item.item_number as item_number,
+            COALESCE ((SELECT
+                        SUM(coitem_qtyreturned)
+                    FROM
+                        coitem
+                    WHERE
+                        coitem_cohead_id = $cohead_id
+                    and
+                        coitem_itemsite_id = invhist_itemsite_id
+            ) ,0) AS rec_returned,
+            COALESCE ((SELECT
+                        SUM(coitem_qtyshipped)
+                    FROM
+                        coitem
+                    WHERE
+                        coitem_cohead_id = $cohead_id
+                    and
+                        coitem_itemsite_id = invhist_itemsite_id
+            ), 0) AS rec_shipped,
+            
+            COALESCE(SUM(invdetail_qty),0) as tx_total,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_shipped,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_returned,
+            
+            COALESCE(SUM(invdetail_qty * invhist_unitcost),0) as total_value
+            
+            
+        ");
+        
+        // add the sum of the gls...
+        
+        
+        
+        $this->whereAdd("
+           
+                invhist_ordtype = 'SO'
+                AND
+                (
+                    invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+                    OR
+                    invhist_ordnumber ='{$cohead->escape($cohead->cohead_number)}'
+                )
+        ");
+        $this->orderBy(" join_item.item_number ASC");
+        $this->groupBy("invhist_itemsite_id, join_item.item_number");
+        $lines = $this->fetchAll();
+        foreach($lines as $l) {
+            if (($l->rec_returned - $l->rec_shipped) != $l->tx_total) {
+                $rr = DB_DataObject::Factory($this->tableName());
+                $rr->reverseAllBadItemsite($roo, $cohead, $l->invhist_itemsite_id);
+            }
+        }
+        
+        $roo->jok("done");
+        
+        
+    }
+        
+    function reverseAllBadItemsite($roo, $cohead, $itemsite_id)
+    {
+        $cohead_id =$cohead->pid();
+         
+        $this->autoJoin();
+        
+        $this->autoJoinItem();
+        
+       // just show the raw transactions...
+        
+        $this->whereAdd("
+           
+                invhist_ordtype = 'SO'
+                AND
+                (
+                    invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+                    OR
+                    invhist_ordnumber ='{$cohead->escape($cohead->cohead_number)}'
+                )
+                AND
+                invhist_itemsite_id = $itemsite_id 
+        ");
+        
+        $this->selectAdd("
+                           
+            ROUND(COALESCE((SELECT SUM(COALESCE(coitem_qtyreturned,0) - COALESCE(coitem_qtyshipped,0) ) from coitem
+                where coitem_cohead_id = $cohead_id
+                AND
+                 coitem_linenumber =  SPLIT_PART(SUBSTRING(invhist_ordnumber, " . (strlen($cohead->cohead_number) + 2) . "), '.', 1)::INTEGER
+                AND
+                coitem_subnumber =  ( '0' || SPLIT_PART( SUBSTRING(invhist_ordnumber, " . (strlen($cohead->cohead_number) + 2) . "), '.', 2))::INTEGER
+               
+            ),0),0) AS coitem_shipped
+
+        ");
+        $lines = $this->fetchAll();
+        $bad = array();
+        
+        foreach($lines as $line) {
+            if ($line->invdetail_qty > 0 AND isset($bad[$line->invhist_ordnumber])) {
+                unset($bad[$line->invhist_ordnumber]);
+                continue;
+            }
+            
+            if ($line->coitem_shipped == 0 AND $line->invdetail_qty < 0) {
+                $bad[$line->invhist_ordnumber]  = $line->invdetail_id;
+                continue;
+            }
+            
+            
+        }
+        
+        //$roo->jerr(print_R($bad,true));
+        
+        //$this->orderBy(" invhist_transdate ASC ");
+        
+        foreach($bad as $oid=>$invdetail_id) {
+    
+            $inv  = DB_DataObject::Factory($this->tableName());
+            $inv->autoJoin();
+            
+            $inv->autoJoinItem();
+            $inv->get($invdetail_id);
+            $inv->reverse($roo,array('_force' => true, '_return_only' => true));
+        }
+       // $roo->jok('reversed');
+    }
+    
+}
+
diff --git a/DataObjects/Invdetailview.php b/DataObjects/Invdetailview.php
new file mode 100644 (file)
index 0000000..ebe1d93
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+
+class Pman_Xtuple_DataObjects_Invdetailview extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invdetailview';             // table name
+    public $invfifo_invdetail_id    ;
+    public $invfifo_unitcost       ;
+    public $invfifo_totalcost      ;
+    public $invfifo_qty_before     ;
+    public $invfifo_qty_after      ;
+    public $invfifo_cost_before    ;
+    public $invfifo_cost_after     ;
+    public $invfifo_is_estimate    ;
+    public $invfifo_recalc_queued  ;
+    public $invfifo_vend_id        ;
+    public $invfifo_cust_id        ;
+    
+    public $invhist_id;                      // int4(4)  not_null default_nextval%28%28invhist_invhist_id_seq%29%3A%3Aregclass%29 primary_key
+    public $invhist_itemsite_id;             // int4(4)  
+    public $invhist_transdate;               // timestamptz(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $invhist_transtype;               // bpchar(-1)  
+    public $invhist_invqty;                  // numeric(-1)  
+    public $invhist_invuom;                  // text(-1)  
+    public $invhist_ordnumber;               // text(-1)  
+    public $invhist_docnumber;               // text(-1)  
+    public $invhist_qoh_before;              // numeric(-1)  
+    public $invhist_qoh_after;               // numeric(-1)  
+    public $invhist_unitcost;                // numeric(-1)  
+    public $invhist_acct_id;                 // int4(4)  
+    public $invhist_xfer_warehous_id;        // int4(4)  
+    public $invhist_comments;                // text(-1)  
+    public $invhist_posted;                  // bool(1)  default_true
+    public $invhist_imported;                // bool(1)  
+    public $invhist_hasdetail;               // bool(1)  default_false
+    public $invhist_ordtype;                 // text(-1)  
+    public $invhist_analyze;                 // bool(1)  default_true
+    public $invhist_user;                    // text(-1)  default_%22current_user%22%28%29
+    public $invhist_created;                 // timestamptz(8)  not_null default_now%28%29
+    public $invhist_costmethod;              // bpchar(-1)  not_null
+    public $invhist_value_before;            // numeric(-1)  not_null
+    public $invhist_value_after;             // numeric(-1)  not_null
+    public $invhist_series;                  // int4(4)  
+    
+    
+    public $invdetail_id;                    // int4(4)  not_null default_nextval%28%28%22invdetail_invdetail_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $invdetail_transtype;             // bpchar(-1)  
+    public $invdetail_invhist_id;            // int4(4)  
+    public $invdetail_location_id;           // int4(4)  
+    public $invdetail_qty;                   // numeric(-1)  
+    public $invdetail_comments;              // text(-1)  
+    public $invdetail_qty_before;            // numeric(-1)  
+    public $invdetail_qty_after;             // numeric(-1)  
+    public $invdetail_invcitem_id;           // int4(4)  
+    public $invdetail_expiration;            // date(4)  
+    public $invdetail_warrpurc;              // date(4)  
+    public $invdetail_ls_id;                 // int4(4)  
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['cohead_id'])) {
+            $this->coheadView($q,$roo);
+            return;
+            
+            
+        }
+        
+        
+        
+        
+    }
+    
+    function coheadView($q,$roo)
+    {
+        
+        $cohead_id =(int) $q['cohead_id'];
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        $cohead->get($cohead_id);
+        
+        $this->selectAdd();
+        $this->selectAdd("
+            invhist_itemsite_id,
+            item_number,
+            COALESE (SELECT SUM(coitem_qtyreturned) FROM coitem WHERE coitem_cohead_id = $cohead_id ), 0 ) AS rec_returned,
+            COALESE (SELECT SUM(coitem_qtyshipped) FROM coitem WHERE coitem_cohead_id = $cohead_id , 0 ) AS rec_shipped,
+            
+            COALESCE(SUM(invdetail_qty),0) as tx_total,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_shipped,
+            COALESCE(SUM(
+                CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+            ),0) as tx_returned
+        ");
+        $this->_joinAdd .= "
+        FROM
+            invdetailview
+        LEFT JOIN
+            itemsite
+        ON
+            invhist_itemsite_id = itemsite_id
+        LEFT JOIN
+            item
+        ON
+            item_id = itemsite_item_id
+        ";
+        $this->whereAdd("
+            WHERE 
+                invhist_ordtype = 'SO'
+                AND
+                invhist_ordnumber LIKE '{$cohead->escape($cohead->cohead_number)}' || '-%'
+        ");
+         $this->orderBy(" item_number ASC");
+         $this->groupBy("invhist_itemsite_id");
+            
+        
+        
+        
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/DataObjects/Invfifo.php b/DataObjects/Invfifo.php
new file mode 100644 (file)
index 0000000..e3702b8
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for invhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invfifo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invfifo';             // table name
+    public $invfifo_invdetail_id    ;
+    public $invfifo_unitcost       ;
+    public $invfifo_totalcost      ;
+    public $invfifo_qty_before     ;
+    public $invfifo_qty_after      ;
+    public $invfifo_cost_before    ;
+    public $invfifo_cost_after     ;
+    public $invfifo_is_estimate    ;
+    public $invfifo_recalc_queued  ;
+    public $invfifo_vend_id        ;
+    public $invfifo_cust_id        ;
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+}
\ No newline at end of file
diff --git a/DataObjects/Invhist.php b/DataObjects/Invhist.php
new file mode 100644 (file)
index 0000000..671f49d
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Table Definition for invhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invhist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invhist';             // table name
+    public $invhist_id;                      // int4(4)  not_null default_nextval%28%28invhist_invhist_id_seq%29%3A%3Aregclass%29 primary_key
+    public $invhist_itemsite_id;             // int4(4)  
+    public $invhist_transdate;               // timestamptz(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $invhist_transtype;               // bpchar(-1)  
+    public $invhist_invqty;                  // numeric(-1)  
+    public $invhist_invuom;                  // text(-1)  
+    public $invhist_ordnumber;               // text(-1)  
+    public $invhist_docnumber;               // text(-1)  
+    public $invhist_qoh_before;              // numeric(-1)  
+    public $invhist_qoh_after;               // numeric(-1)  
+    public $invhist_unitcost;                // numeric(-1)  
+    public $invhist_acct_id;                 // int4(4)  
+    public $invhist_xfer_warehous_id;        // int4(4)  
+    public $invhist_comments;                // text(-1)  
+    public $invhist_posted;                  // bool(1)  default_true
+    public $invhist_imported;                // bool(1)  
+    public $invhist_hasdetail;               // bool(1)  default_false
+    public $invhist_ordtype;                 // text(-1)  
+    public $invhist_analyze;                 // bool(1)  default_true
+    public $invhist_user;                    // text(-1)  default_%22current_user%22%28%29
+    public $invhist_created;                 // timestamptz(8)  not_null default_now%28%29
+    public $invhist_costmethod;              // bpchar(-1)  not_null
+    public $invhist_value_before;            // numeric(-1)  not_null
+    public $invhist_value_after;             // numeric(-1)  not_null
+    public $invhist_series;                  // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        $id = DB_DataObject::Factory('invdetail');
+        $this->_join .= "
+            RIGHT JOIN invdetail AS join_invdetail ON
+            invhist.invhist_id = join_invdetail.invdetail_invhist_id";
+        $this->selectAs($id, '%s', 'join_invdetail');
+    
+        $id = DB_DataObject::Factory('location');
+        $this->_join .= "
+            LEFT JOIN location AS join_location ON
+            join_invdetail.invdetail_location_id = join_location.location_id";
+        $this->selectAs($id, '%s', 'join_location');
+    
+        if (!empty($_REQUEST['invdetail_location_id'])) {
+            $l = (int) $_REQUEST['invdetail_location_id'];
+            $this->whereAdd(
+                "invdetail_location_id = $l"
+            );
+        }
+        
+        
+        
+        
+        /*
+         does not work (not needed yet..)
+         if (!empty($q['_with_item'])) {
+            $itemsite = DB_DataObject::Factory('item');
+            
+            $this->_join .= "
+                INNER JOIN itemsite AS join_invhist_itemsite_id ON
+                invhist_itemsite_id = join_invhist_itemsite_id.itemsite_id";
+            $this->selectAs($itemsite, '%s', 'join_invhist_itemsite_id');
+            
+            $item = DB_DataObject::Factory('item');
+            
+            $this->_join .= "
+                INNER JOIN item AS join_invhist_item ON
+                join_invhist_itemsite_id.itemsite_item_id = join_invhist_item.item_id";
+            $this->selectAs($item, '%s', 'join_invhist_item');
+        }
+        */
+    }
+    function details()
+    {
+        if (!$this->invhist_hasdetail) {
+            return false;
+        }
+        $d = DB_DAtaObject::factory('invdetail');
+        $d->invdetail_invhist_id = $this->pid();
+        return $d->fetchAll();
+         
+    }
+    
+}
diff --git a/DataObjects/Invhist_transfer.php b/DataObjects/Invhist_transfer.php
new file mode 100644 (file)
index 0000000..1d650b7
--- /dev/null
@@ -0,0 +1,865 @@
+<?php
+/**
+ * Table Definition for invhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invhist_transfer extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invhist_transfer';             // table name
+    public $invhist_transfer_id;                      // int4(4)  not_null default_nextval%28%28invhist_invhist_id_seq%29%3A%3Aregclass%29 primary_key
+    public $invhist_transfer_from;             // int4(4)  
+    public $invhist_transfer_to;               // timestamptz(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $invhist_transfer_number;               // bpchar(-1)  
+    public $invhist_transfer_descrip;                  // numeric(-1)  
+    public $invhist_transfer_posted;                  // numeric(-1)  
+    public $invhist_transfer_transdate;
+    public $invhist_transfer_arrivaldate;
+    public $invhist_transfer_recvgrp_id;
+    public $invhist_transfer_void;
+    public $invhist_transfer_salesrep_id;
+    public $invhist_transfer_delivery_note;              //TEXT
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (!empty($q['_createFromRecv'])) {
+            $rg = DB_DataObject::Factory('recvgrp');
+            $rg->get($q['_createFromRecv']);
+            
+            $ih = $this->factory($this->tableName());
+            $ih->autoJoin();
+            $ih->get($this->createFromRecvGroup($roo,$rg));
+            $roo->addEvent("CREATEFROMRECV", $this);
+            
+            $roo->jok($ih->toArray());
+            
+        }
+        
+        $this->selectAdd("
+            (SELECT SUM(invhist_transfer_item.invhist_transfer_item_qty) FROM invhist_transfer_item
+                WHERE  invhist_transfer_item_invhist_transfer_id =  invhist_transfer_id ) as qty
+            
+        ");
+        if (!empty($q['query']['location_id'])) {
+            $l = (int) $q['query']['location_id'];
+            $this->whereAdd("
+                   invhist_transfer_from = $l OR  invhist_transfer_to = $l 
+                            
+                            
+                    ");
+        }
+         if (!empty($q['query']['invhist_transfer_number'])) {
+            $l = $this->escape( $q['query']['invhist_transfer_number']) ;
+            $this->whereAdd("
+                   invhist_transfer_number like '$l%' 
+                    ");
+        }
+        
+        if(!empty($q['query']['dateSel'])){
+            $this->invhist_transfer_transdate = "{$q['query']['dateSel']}";
+        }
+        
+        
+        if (!empty($q['_download'])) {
+            //$this->autoJoin();
+            if (!$this->get($q['_download'])) {
+                $roo->jerr("Invalid URL = fetch failed.");
+            }
+            return $this->download($roo);
+        }
+        
+        // add the customer type chars..
+         
+        $this->selectAdd("
+                        (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY')
+                                FROM location where location_id  = invhist_transfer_to LIMIT 1
+                        )
+                         as cust_to_internalcompany,
+                         
+                        (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY')
+                                FROM location where location_id  = invhist_transfer_from LIMIT 1
+                        )
+                         as cust_from_internalcompany
+        ");
+        if (!empty($q['cust_to_internalcompany'])) {
+            $this->whereAdd("
+                            (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY')
+                                FROM location where location_id  = invhist_transfer_to LIMIT 1
+                        ) = '{$this->escape($q['cust_to_internalcompany'])}'
+                ");
+            
+            
+        }
+        
+    }
+    
+    
+    
+    function verifyLocations($roo, $req = array())
+    {
+        
+        if (empty($this->invhist_transfer_from)) {
+            $roo->jerr("Transfer from location  is not set");
+        }
+        if (empty($this->invhist_transfer_to)) {
+            $roo->jerr("Transfer to location is not set");
+        }
+        $src = DB_DataObject::factory('location');
+        $src->get($this->invhist_transfer_from);
+        $dest = DB_DataObject::factory('location');
+        $dest->get($this->invhist_transfer_to);
+        $scust = $src->customer();
+        $dcust = $dest->customer();
+        
+        if (!$dcust) {
+            $roo->jerr("the destination location specified does not have a customer associated with it.");
+        }
+        if (!$scust) {
+            $roo->jerr("the source location specified does not have a customer associated with it.");
+        }
+        
+        if (strlen($scust->char('INTERNALCOMPANY')) ) {
+            
+            
+            $roo->jerr("Transfering from remote not allowed - the other site must create a transfer to you.". print_R($req,true));
+        }
+        
+    }
+    
+    function beforeInsert($request,$roo) 
+    {
+        $this->verifyLocations($roo, $request);
+        
+        /*
+         *  check to see if the delivery notes is allow blank
+         *  if the shiphead location id is same as the default_location, then all blank, otherwise, MUST fill it in...
+         */
+        if(empty($this->invhist_transfer_delivery_note)){
+            $l = DB_DataObject::factory('location');
+            $l = $l->defaultConfigLocation();
+            
+            if($this->invhist_transfer_from != $l->pid()){
+                $roo->jerr("You must fill in the transfer delivery notes!");
+            }
+        }
+        
+        if (($this->invhist_transfer_number == 'AUTOMATIC') || empty($this->invhist_transfer_number)) {
+            $this->invhist_transfer_number = $this->generateNumber();
+            
+        }
+       
+        
+        
+    }
+    
+    function generateNumber($name=false)
+    {
+        if (!$name) {
+            $it = DB_DataObject::Factory('invhist_transfer');
+            $it->selectAdd();
+            $it->selectAdd( 'MAX(substring(invhist_transfer_number from 3)::int) as result');
+            $it->whereAdd( "invhist_transfer_number LIKE 'IT%'");
+            $it->whereAdd( "invhist_transfer_number NOT LIKE 'ITR%'");
+            $it->find(true);
+            $num = isset($it->result) ? $it->result + 1 : 1;
+            return 'IT'. $num;
+        }
+        // otherwise we do it based on suffixes
+        $it = DB_DataObject::Factory('invhist_transfer');
+        if (!$it->get('invhist_transfer_number', $name)) {
+            return $name;
+        }
+        $n = 1;
+        while ($n < 100) {
+            $it = DB_DataObject::Factory('invhist_transfer');
+            if (!$it->get('invhist_transfer_number', $name.'-'.$n)) {
+               return $name.'-'.$n;
+            }   
+            
+            
+            $n++;
+        }
+        
+        
+    }
+    
+    
+    
+    
+    function post($roo,$r)
+    {
+        if ($this->invhist_transfer_posted) {
+              $roo->jerr("It's already posted");
+        }
+          
+        $lf = $this->location_from();
+        if (!$lf) {
+            $roo->jerr("from location does not exist?");
+        }
+        
+        $lt = $this->location_to();
+        
+        if (!$lt) {
+            $roo->jerr("to location does not exist?");
+        }
+        
+        
+        // check that this internal company does not match us 
+         $ourdb = substr($this->database(), -2);
+         
+          
+        $ltc = $lt->customer()->char('INTERNALCOMPANY');
+        
+        
+        if (strlen($ltc) && $ourdb != $ltc) {
+            
+            $this->checkLocationStock($roo);
+            
+            return $this->postInterCompany($roo);
+        }
+        
+        $roo->sessionState(0);
+        
+        
+        $this->query("
+            SELECT invhist_transfer_post({$this->pid()})
+            ");
+        $roo->addEvent("POSTED", $this);
+        $roo->jok("POSTED");
+       
+    }
+    
+    
+    function void($roo,$r)
+    {   
+        $this->verifyLocations($roo);
+          
+        $lf = $this->location_from();
+        if (!$lf) {
+            $roo->jerr("from location does not exist?");
+        }
+        
+        if (strlen($lf->customer()->char('INTERNALCOMPANY'))) {
+            $roo->jerr("Transfering from remote not allowed - the other site must create a transfer to you.");
+        }
+        
+        
+        $lt = $this->location_to();
+        if (!$lt) {
+            $roo->jerr("to location does not exist?");
+        }
+        if (strlen($lt->customer()->char('INTERNALCOMPANY'))) {
+            return $roo->jerr("You can not void a inter-company transfer - ask the other company to transfer the stock back.");
+        }
+        
+        
+        $this->query("
+            SELECT invhist_transfer_void({$this->pid()})
+            ");
+        $roo->addEvent("VOIDED", $this);
+        $roo->jok("VOIDED");
+       
+    }
+    
+    
+    function beforeUpdate($old, $request, $roo)
+    {
+        if (!empty($request['_void'])) {
+            $this->factory('cohead')->lockTables();
+            $this->void($roo,$request);
+        }
+        
+        
+        // would be nice if these where in the trigger for posted..
+        if (!empty($request['_post'])) {
+            
+           $this->factory('cohead')->lockTables();
+            $this->verifyLocations($roo, $request);
+            $this->post($roo, $request);
+        }
+        
+        $this->verifyLocations($roo, $request);
+        
+        /*
+         *  check to see if the delivery notes is allow blank
+         *  if the shiphead location id is same as the default_location, then all blank, otherwise, MUST fill it in...
+         */
+        if(empty($this->invhist_transfer_delivery_note)){
+            $l = DB_DataObject::factory('location');
+            $l = $l->defaultConfigLocation();
+            
+            if($this->invhist_transfer_from != $l->pid()){
+                $roo->jerr("You must fill in the transfer delivery notes!");
+            }
+        }
+        
+        if ($this->invhist_transfer_posted) {
+            $roo->jerr("Transfer is posted, please void first");
+        }
+        if (isset($request['transfer_items'])) {
+            $this->updateItems(json_decode($request['transfer_items']), $roo);
+             
+        }
+        
+        
+    }
+    
+    function onInsert($request,$roo) 
+    {
+         if (isset($request['transfer_items'])) {
+            $this->updateItems(json_decode($request['transfer_items']), $roo);
+             
+        }
+        
+        
+    }
+    
+    
+    function items($curr=false, $with_purchase_dt=false)
+    {
+        
+        
+        $base = DB_DataObject::Factory('curr_symbol');
+        $base = $base->base();
+      
+        
+        if (!$curr) {
+            $curr= $base;
+        }
+        $r= DB_DataObject::Factory('invhist_transfer_item');
+        $r->invhist_transfer_item_invhist_transfer_id = $this->pid();
+        $r->autoJoin();
+        $r->joinAddItem();
+        
+        $r->selectAdd("
+             currtocurr({$base->pid()} , {$curr->pid()}, stdcost(item_id) , '{$this->invhist_transfer_transdate}'::date) as item_stdcost
+        ");
+        
+        if ($with_purchase_dt) {
+            
+            $r->selectAdd(" COALESCE((
+                        SELECT
+                            currtocurr(pohead_curr_id, {$curr->pid()}, poitem_unitprice, '{$this->invhist_transfer_transdate}'::date)
+                        FROM
+                            poitem
+                        LEFT JOIN
+                            pohead
+                        ON
+                            poitem_pohead_id = pohead_id
+                        WHERE
+                           pohead_orderdate  <= '$with_purchase_dt'::date
+                        AND
+                            poitem_itemsite_id = itemsite_id
+                        ORDER BY
+                            poitem_duedate DESC
+                        LIMIT 1
+                        
+                ), -1) as poitem_unitprice
+            ");
+        }
+        
+        $r->orderBy('invhist_transfer_item_line ASC');
+        $r->find();
+        
+        $ret = array();
+        while ($r->fetch()) {
+            /*
+             * use invhist_transfer_item_id as the index
+             * after check, there is no other place using this
+             * 
+             * $ret[$r->invhist_transfer_item_line] = clone($r);
+             */
+         
+            $ret[$r->invhist_transfer_item_id] = clone($r);
+        }
+        
+        return $ret;
+        
+    }
+    /**
+     *
+    *  row of
+    *   qty | itemsite_id | line
+     *
+     **/
+    
+    function updateItems($rows, $roo)
+    {
+        $old = $this->items();
+        
+        $lt = $this->location_to();
+        
+        if (!$lt) {
+            $roo->jerr("to location does not exist?");
+        }
+        
+        $ourdb = substr($this->database(), -2);
+          
+        $ltc = $lt->customer()->char('INTERNALCOMPANY');
+        
+        foreach($rows as $r)
+        {
+            if (isset($old[$r->id])) {
+                $o = clone($old[$r->id]);
+                $o->setFrom(array(
+                    'invhist_transfer_item_itemsite_id' => $r->itemsite_id,
+                    'invhist_transfer_item_qty' => $r->qty,
+                    'invhist_transfer_item_unit_price' => (strlen($ltc) && $ourdb != $ltc) ? $r->price * 1 : $this->sqlValue('NULL')
+                ));
+                $o->update($old[$r->id]);
+                unset($old[$r->id]);
+                continue;
+                
+            }
+            // no old line exists.. - create a new one..
+            
+            $o = DB_DataObject::Factory('invhist_transfer_item');
+            $o->setFrom(array(
+                
+                'invhist_transfer_item_itemsite_id' => $r->itemsite_id,
+                'invhist_transfer_item_qty' => $r->qty,
+                'invhist_transfer_item_invhist_transfer_id' => $this->pid(),
+                'invhist_transfer_item_line' => $r->line, // very trusting?
+                'invhist_transfer_item_unit_price' => (strlen($ltc) && $ourdb != $ltc) ? $r->price * 1 : $this->sqlValue('NULL')
+            ));
+            $o->insert();
+            
+        }
+        if (!empty($old)) {
+            foreach($old as $line=>$r) {
+                $r->delete();
+            }
+        }
+          
+    }
+    function download($roo)
+    {
+        $lt = $this->location_to();
+        
+        if (!$lt) {
+            $roo->jerr("to location does not exist?");
+        }
+        
+        $ourdb = substr($this->database(), -2);
+          
+        $ltc = $lt->customer()->char('INTERNALCOMPANY');
+        
+        $q = array();
+        if (strlen($ltc) && $ourdb != $ltc) {
+            $q['_inter_transfer'] = 1;
+        }
+        
+        $r= DB_DataObject::Factory('invhist_transfer_item');
+        $r->invhist_transfer_item_invhist_transfer_id = $this->pid();
+        $r->autoJoin();
+        $r->applyFilters($q, $roo->authUser, $roo);
+        $r->orderBy('invhist_transfer_item_line ASC');
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        $s = new Pman_Core_SimpleExcel(
+            $r->fetchAll(false,false,'toArray'), array(
+                'head' => array(
+                        array( "Date:", date('Y-m-d', strtotime($this->invhist_transfer_transdate))),
+                        array( "Arrival Date:", date('Y-m-d', strtotime($this->invhist_transfer_arrivaldate))),
+                        array( "Reference:", $this->invhist_transfer_number),
+                        array( "From:", $this->invhist_transfer_from_location_name),
+                        array( "To:", $this->invhist_transfer_to_location_name),
+                ),
+                'cols' => array(
+                    array(
+                        'header'=> "Line",
+                        'dataIndex'=> 'invhist_transfer_item_line',
+                        'width'=>  75,
+                            //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Item Code",
+                        'dataIndex'=> 'item_number',
+                        'width'=>  100,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Description",
+                        'dataIndex'=> 'item_descrip1',
+                        'width'=>  300,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Quantity",
+                        'dataIndex'=> 'invhist_transfer_item_qty',
+                        'width'=>  50,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Currency",
+                        'dataIndex'=> 'invhist_transfer_item_curr_name',
+                        'width'=>  50,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Unit Price",
+                        'dataIndex'=> 'invhist_transfer_item_unit_price',
+                        'width'=>  50,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                ),
+                
+                'workbook' => 'InvTransfer'
+            
+        ));
+        $s->send($this->invhist_transfer_number.date("-d-M-Y").'.xls');
+        
+         
+        
+    }
+    
+    function location_from()
+    {
+        $l = DB_DataObject::Factory('location');
+        if (!$l->get($this->invhist_transfer_from)) {
+            return false;
+        }
+        return $l;
+        
+    }
+    function location_to()
+    {
+        $l = DB_DataObject::Factory('location');
+        if (!$this->invhist_transfer_to || !$l->get($this->invhist_transfer_to)) {
+            return false;
+        }
+        return $l;
+    }
+  
+    
+    
+    function postInterCompany($roo)
+    {
+        
+        //$roo->jerr("disabled until correct prices are uploaded");
+        
+        // which office is it going to...
+        $lt = $this->location_to();
+        if (!$lt) {
+            $roo->jerr("to location does not exist?");
+        }
+        
+        $c = $lt->customer();
+        
+        if(!$c){
+            $roo->jerr("could not find customer");
+        }
+        
+        $cur = $c->priceListCurrency($roo);
+        
+        $target_office = $c->char('INTERNALCOMPANY');
+        
+        if (!strlen($target_office)) {
+             $roo->jerr("target location does not exist");
+        }
+        
+        
+        $url = 'http://localhost'.HTML_FlexyFramework::get()->page->rootURL .'/'.
+                strtolower($target_office) .'.php/Roo/Location?lookup[location_name]=' . urlencode($lt->location_name);
+        
+        $res = json_decode(file_get_contents($url),true);
+        
+        if(!$res['success'] || !count($res['data'])){
+            $roo->jerr('Missing location ' . $lt->location_name . 'in ' . $target_office);
+        }
+        if (!empty($res['data']['location_cust_id_char_internalcompany']) &&
+                strtolower($target_office ) != strtolower($res['data']['location_cust_id_char_internalcompany'])) {
+            
+            $roo->jerr("Remote location is not flagged as a local location");
+        }
+       
+        // pircing...
+        if (empty($this->invhist_transfer_price)) {
+            $roo->jerr("transfer pricing not set");
+        }
+        
+        $priceLists = array();
+        
+        
+        $dt = date('Y-m-d', strtotime( $this->invhist_transfer_transdate));
+        // items with purhcase prices. 
+        $allItems = $this->items($cur, $dt);
+        
+        switch($this->invhist_transfer_price) {
+            case 'PRICELIST': 
+                 
+                $bad_items = array();
+                // slow!!!
+                
+                foreach ($allItems as $row){
+                    if(!empty($row->invhist_transfer_item_unit_price) || $row->invhist_transfer_item_unit_price == 0.00){
+                        $priceLists[$row->invhist_transfer_item_itemsite_id] = $row->invhist_transfer_item_unit_price;
+                        continue;
+                    }
+                    $itemsite = DB_DataObject::factory('itemsite');
+                    if(!$itemsite->get('itemsite_id', $row->invhist_transfer_item_itemsite_id)){
+                        $roo->jerr('error occur on getting item with reference ' . $row->invhist_transfer_item_itemsite_id);
+                    }
+                    
+                    $ipsass = DB_DataObject::factory('ipsass');
+                    $ipsass->query("SELECT itemprice(
+                                    {$itemsite->itemsite_item_id}, 
+                                    {$c->pid()}, 
+                                    null, 
+                                    {$row->invhist_transfer_item_qty}, 
+                                    {$cur->pid()}, 
+                                     '{$dt}'::date
+                                ) AS result");
+                    $ipsass->fetch();
+                    
+                    if ( empty($ipsass->result) || $ipsass->result == 0.0) {
+                        $bad_items[] = $itemsite->itemsite_item_id;
+                        continue;
+                    }
+                    
+                    $priceLists[$row->invhist_transfer_item_itemsite_id] = $ipsass->result;
+                }
+                
+                if (!empty($bad_items)) {
+                    $item = DB_DataObject::Factory('item');
+                    $item->whereAddIn('item_id', $bad_items, 'int');
+                    $ar = $item->fetchAll('item_number');
+                    $roo->jerr("These items do not have prices " . implode(', ', $ar));
+                    
+                }
+                 
+                
+                break;
+            
+            case 'LASTPLUS':
+                foreach($allItems as $rn => $row) {
+                    $priceLists[$row->invhist_transfer_item_itemsite_id] =
+                        $row->poitem_unitprice > 0.0 ?  ($row->poitem_unitprice  * 1.10 * 1.15 ) :    ($row->item_stdcost * 1.15);
+                }
+                break;
+            
+            case 'STDCOST':
+                foreach($allItems as $rn => $row) {
+                    // not allowed to post empty stdcosts...
+                    $priceLists[$row->invhist_transfer_item_itemsite_id] = round($row->item_stdcost,2) == 0.00 ? 0.01 : $row->item_stdcost ;
+                }
+                break;
+            
+            default:
+                $roo->jerr("invalid price type: ". $this->invhist_transfer_price);
+        }
+                    
+             // print_R($priceLists);exit;      
+                    
+                    
+        
+        $items = array();
+        $adt = date('Y-m-d', strtotime($this->invhist_transfer_arrivaldate));
+        $bad_items = array();
+        foreach($allItems as $rn => $row)
+        {
+            
+            if (empty($priceLists[$row->invhist_transfer_item_itemsite_id])) {
+                $bad_items[] = $row->item_number;
+                continue;
+            }
+            $items[] = array(
+                'line' => $row->invhist_transfer_item_line,
+                'item_number' => $row->item_number,
+                '_itemsite_id' => $row->invhist_transfer_item_itemsite_id,
+                'qty' => $row->invhist_transfer_item_qty,
+                'cost' => round($priceLists[$row->invhist_transfer_item_itemsite_id],2),
+                'currency' => $cur->curr_name,
+                'duedate' => $adt
+                
+            );
+            
+            
+        }
+        if (!empty($bad_items)) {
+            $roo->jerr("no prices for ". implode(', ', $bad_items));
+        }
+        
+        $roo->sessionState(0);
+        // if this fails and remote succeeds then we are borked, so we do the local stuff first,
+        // fail if necessary.. before doing remote..
+        $this->factory('cohead')->lockTables();
+        $this->createLocalInvoice($roo,$target_office, $items);
+        
+        //$roo->jok("an invoice should have been created");
+        //$roo->jerr("testing");
+        $this->createRemotePO($roo,$target_office, $items);
+        
+        $roo->sessionState(1); // unless jok does sesson stuff may not need to start session again..  
+        // flag this as posted..
+        
+        $items = $this->items();
+        foreach ($items as $item){
+            $i = clone ($item);
+            $item->invhist_transfer_item_unit_price_default = $i->invhist_transfer_item_unit_price;
+            $item->update($i);
+        }
+        
+        $old = clone($this);
+        $this->invhist_transfer_posted  = true;
+        $this->update($old);
+    
+        
+        
+        $roo->addEvent("POSTED", $this);
+        $roo->jok("CREATED");
+        
+    }
+    
+    
+    
+    
+    function createRemotePO($roo,$target_office, $items )
+    {
+        $target_office = strtolower($target_office);
+        
+        $lt = $this->location_to();
+        
+        /*
+         * check that the target location is actually a local location
+         */
+        
+        $ourdb = substr($this->database(), -2);
+        if ($target_office == $ourdb) {
+            $roo->jerr("target office matches our office?");
+        }
+        
+        $cust = $lt->customer();
+        
+        if (!$cust) {
+            $roo->jerr("could not find customer");
+        }
+        
+        $cur = $cust->priceListCurrency($roo);
+        
+        $po_prefix = 'XF-'. strtoupper(substr($this->database(),-2)).'-'. strtoupper($target_office) .'-';
+        
+        
+        $url = 'http://localhost'.HTML_FlexyFramework::get()->page->rootURL .'/'. $target_office .'.php';
+      // $roo->jerr("posting to $url");
+        
+        $dt = date('Y-m-d', strtotime($this->invhist_transfer_transdate));
+
+        require_once 'HTTP/Request.php';
+       
+        $req = new HTTP_Request( $url . '/Roo/Pohead' );
+        $req->setMethod(HTTP_REQUEST_METHOD_POST);
+        $req->addPostData( array(
+                '_is_xfer' => 1,
+                'pohead_number' => $po_prefix . $this->invhist_transfer_number,  // invoice should match number...
+                'invhist_transfer_number' => $this->invhist_transfer_number,  // invoice should match number...
+                'pohead_orderdate' => $dt,
+                
+                'pohead_released' => $dt,
+                //'invchead_invcdate' => $this->shiphead_shipdate,
+                '_vendor_internal_company' =>  substr($this->database(),-2) ,
+                'curr_name' => $cur->curr_name,
+                 
+                'items' => json_encode($items),
+                'target_location' => $lt->location_name
+          
+        ));
+         //$roo->jerr( print_r($req->_postData,true));
+        //$roo->jerr( $req->_url->getURL() );
+        
+        $res = $req->sendRequest();
+        
+        if (is_a($res,'PEAR_Error')) {
+            $roo->jerr("REMOTE REQUEST RETURNED: ". $res->toString());
+        }
+        $res = json_decode($req->getResponseBody());
+        
+        if (!is_object($res)) {
+            $roo->jerr("REMOTE REQUEST RETURNED: ". $req->getResponseBody());
+        }
+      
+        if (!$res->success) {
+            $roo->jerr("REMOTE REQUEST RETURNED: ". $res->errorMsg);
+        }
+        
+        return (array) $res->data;
+    }
+     
+    function createLocalInvoice($roo, $target_office, $items)
+    {
+        
+        $invc = DB_DataObject::Factory('invchead');
+        $invc->createFromTransfer($roo, $target_office, $this, $items);
+        
+        
+    }
+    
+    
+    
+    function createFromRecvGroup($roo, $rg)
+    {
+        
+         
+        
+        
+        $new = $this->factory($this->tableName());
+        $new->setFrom(array(
+            'invhist_transfer_number' => $this->generateNumber('ITR-' . $rg->pid()),
+            'invhist_transfer_transdate' => date('Y-m-d'),
+            'invhist_transfer_descrip' => 'Created from PO : '  . $rg->pohead()->pohead_number . "\nItem Reciept " . $rg->recvgrp_number,
+            'invhist_transfer_from' => $rg->recvgrp_location_id,
+            'invhist_transfer_recvgrp_id' =>$rg->pid()
+        ));
+        $new->insert();
+        foreach($rg->items() as $line=>$i) {
+            $i->qty = $i->recv_qty;
+            $i->itemsite_id = $i->recv_itemsite_id;
+            $i->line = $i->recv_orderitem_id_poitem_linenumber;
+            $up[] = $i;
+        }
+        $new->updateItems($up, $roo);
+        
+        return $new->pid();
+        
+    }
+    
+    function checkLocationStock($roo)
+    {
+        if(empty($roo->bootLoader->Xtuple['prevent_negative'])){
+            return;
+        }
+        
+        $items = $this->items();
+        
+        $stock = array();
+        
+        foreach ($items as $item){
+            if(empty($item->invhist_transfer_item_qty)){
+                continue;
+            }
+            
+            $balance = $item->itemsite()->checkLocationStock($this->invhist_transfer_from);
+
+            if(empty($balance) || $balance < $item->invhist_transfer_item_qty){
+                $stock[] = $item->itemsite()->item()->item_number;
+            }
+        }
+
+        if(count($stock)){
+            $roo->jerr("These items have negative stock " . implode(', ', $stock));
+        }
+    }
+    
+    
+    
+    
+    
+ }
diff --git a/DataObjects/Invhist_transfer_item.php b/DataObjects/Invhist_transfer_item.php
new file mode 100644 (file)
index 0000000..3b35eec
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+/**
+ * Table Definition for invhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invhist_transfer_item extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invhist_transfer_item';              // table name
+    public $invhist_transfer_item_id;                       // int4(4)  not_null default_nextval%28%28invhist_invhist_id_seq%29%3A%3Aregclass%29 primary_key
+    public $invhist_transfer_item_invhist_transfer_id;      // int4(4)  
+    public $invhist_transfer_item_itemsite_id;              // timestamptz(8)  default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $invhist_transfer_item_qty;                      // bpchar(-1)  
+    public $invhist_transfer_item_line;                     // bpchar(-1)  
+    public $invhist_transfer_invhist_id;                    // int
+    public $invhist_transfer_item_unit_price;               // numeric(12,2) default null
+    public $invhist_transfer_item_unit_price_default;            // numeric(12,2) default null
+
+        
+    
+    /**
+    * Getter / Setter for $invhist_transfer_item_invhist_transfer_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invhist_transfer() {
+        return func_num_args() ? $this->link('invhist_transfer_item_invhist_transfer_id', func_get_arg(0)) : $this->link('invhist_transfer_item_invhist_transfer_id');
+    }
+    
+    
+    /**
+    * Getter / Setter for $invhist_transfer_item_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('invhist_transfer_item_itemsite_id', func_get_arg(0)) : $this->link('invhist_transfer_item_itemsite_id');
+    }
+    
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        $this->joinAddItem();
+        
+        
+        if (!empty($q['query']['at_location'])) {
+             $loc = (int)$q['query']['at_location'];
+             $this->selectAdd("
+                ROUND(COALESCE(
+                        (SELECT itemloc_qty FROM
+                                itemloc
+                            WHERE
+                                itemloc_itemsite_id  = invhist_transfer_item_itemsite_id
+                                AND
+                                itemloc_location_id = $loc
+                        ),0)) as avail_at_location
+            ");
+        }
+        
+        if(!empty($q['_inter_transfer'])){
+            $this->selectAdd("
+                CASE WHEN invhist_transfer_item_unit_price IS NOT NULL THEN
+                    ROUND(invhist_transfer_item_unit_price, 2)
+                ELSE
+                    CASE WHEN (
+                                    SELECT
+                                            ipshead_curr_id
+                                    FROM
+                                            ipsass
+                                    LEFT JOIN
+                                            ipshead
+                                    ON
+                                            ipsass_ipshead_id = ipshead_id
+                                    WHERE
+                                            ipsass_cust_id = (
+                                                                SELECT
+                                                                        location_cust_id
+                                                                FROM
+                                                                        location
+                                                                WHERE
+                                                                        location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                              )
+                                ) IS NOT NULL THEN
+                        ROUND(
+                            (SELECT itemprice(
+                                                join_invhist_transfer_item.item_id, 
+                                                (
+                                                    SELECT
+                                                            location_cust_id
+                                                    FROM
+                                                            location
+                                                    WHERE
+                                                            location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                ), 
+                                                null, 
+                                                1, 
+                                                (
+                                                    SELECT
+                                                            ipshead_curr_id
+                                                    FROM
+                                                            ipsass
+                                                    LEFT JOIN
+                                                            ipshead
+                                                    ON
+                                                            ipsass_ipshead_id = ipshead_id
+                                                    WHERE
+                                                            ipsass_cust_id = (
+                                                                                SELECT
+                                                                                        location_cust_id
+                                                                                FROM
+                                                                                        location
+                                                                                WHERE
+                                                                                        location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                                              )
+                                                ), 
+                                                join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_transdate::date
+                                            )
+                        ), 2)
+                        ELSE
+                            0
+                        END
+                    END AS invhist_transfer_item_unit_price,
+                
+                CASE WHEN invhist_transfer_item_unit_price_default IS NOT NULL AND join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_posted THEN
+                    ROUND(invhist_transfer_item_unit_price_default, 2)
+                ELSE
+                    CASE WHEN (
+                                    SELECT
+                                            ipshead_curr_id
+                                    FROM
+                                            ipsass
+                                    LEFT JOIN
+                                            ipshead
+                                    ON
+                                            ipsass_ipshead_id = ipshead_id
+                                    WHERE
+                                            ipsass_cust_id = (
+                                                                SELECT
+                                                                        location_cust_id
+                                                                FROM
+                                                                        location
+                                                                WHERE
+                                                                        location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                              )
+                                ) IS NOT NULL THEN  
+                        ROUND(
+                            (SELECT itemprice(
+                                                join_invhist_transfer_item.item_id, 
+                                                (
+                                                    SELECT
+                                                            location_cust_id
+                                                    FROM
+                                                            location
+                                                    WHERE
+                                                            location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                ), 
+                                                null, 
+                                                1, 
+                                                (
+                                                    SELECT
+                                                            ipshead_curr_id
+                                                    FROM
+                                                            ipsass
+                                                    LEFT JOIN
+                                                            ipshead
+                                                    ON
+                                                            ipsass_ipshead_id = ipshead_id
+                                                    WHERE
+                                                            ipsass_cust_id = (
+                                                                                SELECT
+                                                                                        location_cust_id
+                                                                                FROM
+                                                                                        location
+                                                                                WHERE
+                                                                                        location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                                              )
+                                                ), 
+                                                join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_transdate::date
+                                            )
+                        ), 2)
+                    ELSE
+                        0
+                    END
+                END AS invhist_transfer_item_unit_price_default,
+                
+                (
+                    SELECT
+                            curr_name
+                    FROM
+                            curr_symbol
+                    WHERE
+                            curr_id = (
+                                        SELECT
+                                                ipshead_curr_id
+                                        FROM
+                                                ipsass
+                                        LEFT JOIN
+                                                ipshead
+                                        ON
+                                                ipsass_ipshead_id = ipshead_id
+                                        WHERE
+                                                ipsass_cust_id = (
+                                                                    SELECT
+                                                                            location_cust_id
+                                                                    FROM
+                                                                            location
+                                                                    WHERE
+                                                                            location_id = join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_to
+                                                                  )
+                                        )
+                ) AS invhist_transfer_item_curr_name
+
+            ");
+
+        }
+    
+        
+    }
+    function joinAddItem()
+    {
+        $item = DB_DataObject::Factory('item');
+        
+        $this->_join .= "\n INNER JOIN item AS join_invhist_transfer_item ON
+            join_invhist_transfer_item_itemsite_id_itemsite_id.itemsite_item_id = join_invhist_transfer_item.item_id";
+        $this->selectAs($item, '%s', 'join_invhist_transfer_item');
+        
+        
+        
+    }
+}
diff --git a/DataObjects/Invoiceitem.php b/DataObjects/Invoiceitem.php
new file mode 100644 (file)
index 0000000..e15bf47
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for invoiceitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Invoiceitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'invoiceitem';         // table name
+    public $invcitem_id;                     // int4(4)  
+    public $invcitem_invchead_id;            // int4(4)  
+    public $invcitem_linenumber;             // int4(4)  
+    public $invcitem_item_id;                // int4(4)  
+    public $invcitem_warehous_id;            // int4(4)  
+    public $invcitem_custpn;                 // text(-1)  
+    public $invcitem_number;                 // text(-1)  
+    public $invcitem_descrip;                // text(-1)  
+    public $invcitem_ordered;                // numeric(-1)  
+    public $invcitem_billed;                 // numeric(-1)  
+    public $invcitem_custprice;              // numeric(-1)  
+    public $invcitem_price;                  // numeric(-1)  
+    public $invcitem_notes;                  // text(-1)  
+    public $invcitem_salescat_id;            // int4(4)  
+    public $invcitem_taxtype_id;             // int4(4)  
+    public $invcitem_qty_uom_id;             // int4(4)  
+    public $invcitem_qty_invuomratio;        // numeric(-1)  
+    public $invcitem_price_uom_id;           // int4(4)  
+    public $invcitem_price_invuomratio;      // numeric(-1)  
+    public $invcitem_coitem_id;              // int4(4)  
+    public $itemsite_id;                     // int4(4)  
+    public $cohead_number;                   // text(-1)  
+    public $qty;                             // numeric(-1)  
+    public $unitprice;                       // numeric(-1)  
+    public $extprice;                        // numeric(-1)  
+    public $baseextprice;                    // numeric(-1)  
+    public $tax;                             // numeric(-1)  
+    public $unitcost;                        // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ipsass.php b/DataObjects/Ipsass.php
new file mode 100644 (file)
index 0000000..babc905
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for ipsass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsass';              // table name
+    public $ipsass_id;                       // int4(4)  not_null default_nextval%28ipsass_ipsass_id_seq%29 primary_key
+    public $ipsass_ipshead_id;               // int4(4)  not_null unique_key multiple_key
+    public $ipsass_cust_id;                  // int4(4)  unique_key multiple_key
+    public $ipsass_custtype_id;              // int4(4)  unique_key multiple_key
+    public $ipsass_custtype_pattern;         // text(-1)  unique_key multiple_key
+    public $ipsass_shipto_id;                // int4(4)  default_%28-1%29 unique_key multiple_key
+    public $ipsass_shipto_pattern;           // text(-1)  unique_key multiple_key
+
+    
+   /**
+    * Getter / Setter for $ipsass_ipshead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ipshead() {
+        return func_num_args() ? $this->link('ipsass_ipshead_id', func_get_arg(0)) : $this->link('ipsass_ipshead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ipsfreight.php b/DataObjects/Ipsfreight.php
new file mode 100644 (file)
index 0000000..7ee3fb3
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Table Definition for ipsfreight
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsfreight extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsfreight';          // table name
+    public $ipsfreight_id;                   // int4(4)  not_null default_nextval%28ipsfreight_ipsfreight_id_seq%29 primary_key
+    public $ipsfreight_ipshead_id;           // int4(4)  not_null
+    public $ipsfreight_qtybreak;             // numeric(-1)  not_null default_0
+    public $ipsfreight_price;                // numeric(-1)  not_null default_0
+    public $ipsfreight_type;                 // bpchar(-1)  not_null
+    public $ipsfreight_warehous_id;          // int4(4)  
+    public $ipsfreight_shipzone_id;          // int4(4)  
+    public $ipsfreight_freightclass_id;      // int4(4)  
+    public $ipsfreight_shipvia;              // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $ipsfreight_freightclass_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freightclass() {
+        return func_num_args() ? $this->link('ipsfreight_freightclass_id', func_get_arg(0)) : $this->link('ipsfreight_freightclass_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsfreight_ipshead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ipshead() {
+        return func_num_args() ? $this->link('ipsfreight_ipshead_id', func_get_arg(0)) : $this->link('ipsfreight_ipshead_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsfreight_shipzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipzone() {
+        return func_num_args() ? $this->link('ipsfreight_shipzone_id', func_get_arg(0)) : $this->link('ipsfreight_shipzone_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsfreight_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('ipsfreight_warehous_id', func_get_arg(0)) : $this->link('ipsfreight_warehous_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ipshead.php b/DataObjects/Ipshead.php
new file mode 100644 (file)
index 0000000..4a7000f
--- /dev/null
@@ -0,0 +1,175 @@
+<?php
+/**
+ * Table Definition for ipshead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipshead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipshead';             // table name
+    public $ipshead_id;                      // int4(4)  not_null default_nextval%28%28%22ipshead_ipshead_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $ipshead_name;                    // text(-1)  unique_key
+    public $ipshead_descrip;                 // text(-1)  
+    public $ipshead_effective;               // date(4)  
+    public $ipshead_expires;                 // date(4)  
+    public $ipshead_curr_id;                 // int4(4)  not_null default_basecurrid%28%29
+    public $ipshead_updated;                 // date(4)  
+
+    
+   /**
+    * Getter / Setter for $ipshead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('ipshead_curr_id', func_get_arg(0)) : $this->link('ipshead_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function beforeUpdate()
+    {
+        $this->ipshead_updated = $this->sqlValue('NOW()');
+    }
+    function beforeInsert()
+    {
+        $this->ipshead_updated = $this->sqlValue('NOW()');
+    }
+    
+    function itemPrice($item) {
+        $ipsitem = DB_DataObject::Factory('ipsiteminfo');
+        $ipsitem->ipsitem_item_id  = $item->pid();
+        $ipsitem->ipsitem_ipshead_id = $this->pid();
+        if (!$ipsitem->find(true)) {
+            return 0;
+        }
+        return $ipsitem->ipsitem_price;
+        
+        
+    }
+    
+    function updatePrices($kv, $imap)
+    {
+        /*
+            public $__table = 'ipsitem';             // table name
+            public $ipsitem_id;                      // int4(4)  
+            public $ipsitem_ipshead_id;              // int4(4)  
+            public $ipsitem_item_id;                 // int4(4)  
+            public $ipsitem_qtybreak;                // numeric(-1)  
+            public $ipsitem_price;                   // numeric(-1)  
+            public $ipsitem_qty_uom_id;              // int4(4)  
+            public $ipsitem_price_uom_id;            // int4(4)  
+            public $ipsitem_discntprcnt;             // numeric(-1)  
+            public $ipsitem_fixedamtdiscount;        // numeric(-1)
+            
+            ipsitem_id               | 10517
+           ipsitem_ipshead_id       | 65
+           ipsitem_item_id          | 2768
+           ipsitem_qtybreak         | 0.000000
+           ipsitem_price            | 14.5000
+           ipsitem_qty_uom_id       | 4
+           ipsitem_price_uom_id     | 4
+           ipsitem_discntprcnt      | 0.000000
+           ipsitem_fixedamtdiscount | 0.0000
+
+                    
+        */
+        
+        // grab a list of current prices with ids'
+        $d = DB_DataObject::Factory('ipsiteminfo');
+        $d->selectAdd();
+        $d->selectAdd('
+            ipsitem_id,
+            item_number,
+            ipsitem_price
+            
+        ');
+        $d->_join = ' LEFT JOIN item ON ipsiteminfo.ipsitem_item_id = item.item_id ';
+        
+        $d->ipsitem_ipshead_id = $this->pid();
+        $d->find();
+        $old = array();
+        while ($d->fetch()) {
+            $old[$d->item_number] = clone($d);
+        }
+        
+        $deleted = 0;
+        $updated = 0;
+        $inserted = 0;
+        
+        foreach($kv as $item=>$price) {
+            $o = isset($old[$item]) ? $old[$item] : false;
+            // no record, and not updated.
+            if (!strlen($price) && $o === false) {
+                continue;
+            }
+            // updated or not changed.
+            if (strlen($price) && $o !== false) {
+                // not changed.
+                if ($o->ipsitem_price == $price) {
+                    continue;
+                }
+                $oo = clone($o);
+                $o->ipsitem_price = $price;
+                $o->update($oo);
+                $updated++;
+                continue;
+            }
+            // new price
+            if (strlen($price) && $o === false) {
+                 $d = DB_DataObject::Factory('ipsiteminfo');
+                $d->setFrom(array(
+
+                    'ipsitem_ipshead_id' => $this->pid(),
+                    'ipsitem_item_id' => $imap[$item],
+                    'ipsitem_qtybreak' =>  0.0,
+                    'ipsitem_price' => $price,
+                   
+                    'ipsitem_discntprcnt' => 0.0,
+                    'ipsitem_fixedamtdiscount' => 0.0
+                    
+                    
+                ));
+                $d->ipsitem_qty_uom_id = $d->sqlValue("getuomid('EA')");
+                $d->ipsitem_price_uom_id = $d->sqlValue("getuomid('EA')");
+                $d->insert();
+                $inserted++;
+                continue;
+                
+                
+                
+            }
+            // o is true, and price is empty..
+            // theory goes we should delete this item..
+            //$o->delete();
+            //$deleted++;
+            // do not delete prices... 
+        }
+        
+        $x = $this->factory($this->tableName());
+        $x->get($this->pid());
+        $xx = clone($x);
+        $x->ipshead_updated = $this->sqlValue('NOW()');
+        $x->update($xx);
+        
+        
+        return array(
+            'deleted' => $deleted,
+            'updated' => $updated,
+            'inserted' => $inserted
+        );
+        
+        
+        
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Ipsitem.php b/DataObjects/Ipsitem.php
new file mode 100644 (file)
index 0000000..ccd09af
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Table Definition for ipsitem - this is a view...
+ */
+
+ /// WARNING THIS IS A VIEW...
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsitem';             // table name
+    public $ipsitem_id;                      // int4(4)  
+    public $ipsitem_ipshead_id;              // int4(4)  
+    public $ipsitem_item_id;                 // int4(4)  
+    public $ipsitem_qtybreak;                // numeric(-1)  
+    public $ipsitem_price;                   // numeric(-1)  
+    public $ipsitem_qty_uom_id;              // int4(4)  
+    public $ipsitem_price_uom_id;            // int4(4)  
+    public $ipsitem_discntprcnt;             // numeric(-1)  
+    public $ipsitem_fixedamtdiscount;        // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+   
+    
+}
diff --git a/DataObjects/Ipsitemchar.php b/DataObjects/Ipsitemchar.php
new file mode 100644 (file)
index 0000000..01194bb
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for ipsitemchar
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsitemchar extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsitemchar';         // table name
+    public $ipsitemchar_id;                  // int4(4)  not_null default_nextval%28ipsitemchar_ipsitemchar_id_seq%29 primary_key
+    public $ipsitemchar_ipsitem_id;          // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $ipsitemchar_char_id;             // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $ipsitemchar_value;               // text(-1)  not_null unique_key multiple_key unique_key multiple_key
+    public $ipsitemchar_price;               // numeric(-1)  
+
+    
+   /**
+    * Getter / Setter for $ipsitemchar_ipsitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ipsitem() {
+        return func_num_args() ? $this->link('ipsitemchar_ipsitem_id', func_get_arg(0)) : $this->link('ipsitemchar_ipsitem_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ipsiteminfo.php b/DataObjects/Ipsiteminfo.php
new file mode 100644 (file)
index 0000000..9394cd4
--- /dev/null
@@ -0,0 +1,258 @@
+<?php
+/**
+ * Table Definition for ipsiteminfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsiteminfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsiteminfo';         // table name
+    public $ipsitem_id;                      // int4(4)  not_null default_nextval%28%28%22ipsitem_ipsitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $ipsitem_ipshead_id;              // int4(4)  unique_key multiple_key
+    public $ipsitem_item_id;                 // int4(4)  unique_key multiple_key
+    public $ipsitem_qtybreak;                // numeric(-1)  not_null unique_key multiple_key
+    public $ipsitem_price;                   // numeric(-1)  not_null
+    public $ipsitem_qty_uom_id;              // int4(4)  not_null unique_key multiple_key
+    public $ipsitem_price_uom_id;            // int4(4)  not_null unique_key multiple_key
+    public $ipsitem_discntprcnt;             // numeric(-1)  not_null default_0.00
+    public $ipsitem_fixedamtdiscount;        // numeric(-1)  not_null default_0.00
+
+    
+   /**
+    * Getter / Setter for $ipsitem_ipshead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ipshead() {
+        return func_num_args() ? $this->link('ipsitem_ipshead_id', func_get_arg(0)) : $this->link('ipsitem_ipshead_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsitem_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('ipsitem_price_uom_id', func_get_arg(0)) : $this->link('ipsitem_price_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsitem_qty_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qty_uom() {
+        return func_num_args() ? $this->link('ipsitem_qty_uom_id', func_get_arg(0)) : $this->link('ipsitem_qty_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $ipsitem_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('ipsitem_item_id', func_get_arg(0)) : $this->link('ipsitem_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au,$roo)
+    {
+        if (!empty($q['_pricegrid'])) {
+            //$this->PriceGrid();
+            $this->priceGridExcel();
+        }
+        
+        
+    }
+    // --- ??? not used..
+    function priceGrid()
+    {   
+        //DB_DataObject::DebugLevel(1);
+        $m = DB_DataObject::Factory('ipshead');
+        $m->orderBy('ipshead_name ASC');
+        $names = $m->fetchAll('ipshead_id' , 'ipshead_name');
+        
+        $m = DB_DataObject::Factory('ipshead');
+        $m->selectAdd();
+        $m->selectAdd('ipshead_id, (SELECT curr_name from curr_symbol where curr_id = ipshead_curr_id) as ipshead_curr');
+        $cnames = $m->fetchAll('ipshead_id' , 'ipshead_curr');
+        // names have to be unique, so we will update them rather than create new ones..
+        
+        $it = DB_DataObject::Factory('ipsiteminfo');
+        $it->selectAdd();
+        
+        $it->selectAdd('distinct(ipsitem_item_id) as item_id');
+        $item_ids = $it->fetchAll('item_id');
+        
+        $in = DB_DataObject::Factory('item');
+        $in->orderBy('item_number ASC');
+        $in->whereAddIn('item_id', $item_ids, 'int');
+        $items = $in->fetchAll('item_id','item_number');
+        
+        $type_pos = array_flip(array_keys($names));
+        $item_pos = array_flip(array_keys($items));
+        
+        $g = array();
+        // head..
+        $g[0] = array_values($names);
+        array_unshift($g[0], '');
+        $g[1] = array('');
+        
+        
+        foreach($names as $id=>$name) {
+            $g[1][] = $cnames[$id];
+        }
+        
+        $empty = array_fill(0, count($g[0]), '');
+        
+        foreach(array_values($items) as $i=>$name) {
+            $g[$i+2] = $empty;
+            $g[$i+2][0] = $name;
+        }
+        
+        $t =  DB_DataObject::Factory('ipsiteminfo');
+        $t->find();
+        while ($t->fetch()) {
+            $row = $item_pos[$t->ipsitem_item_id]  +2;
+            $col = $type_pos[$t->ipsitem_ipshead_id] + 1;
+            $g[$row][$col] = $t->ipsitem_price;
+        }
+       
+        // dump it...
+        $fn = 'pricelist';
+        
+        
+        header('Content-type: text/csv');
+        
+        header('Content-Disposition: attachment; filename="'.$fn.date('Y-m-d') . '.csv"');
+        //header('Content-type: text/plain');
+        $fh = fopen('php://output', 'w');
+        fwrite($fh,"\xEF\xBB\xBF"); // Stupid Excel and unicode!
+        
+         
+        
+        foreach($g as $x) {
+            //echo "<PRE>"; print_r(array($_REQUEST['csvCols'], $x->toArray())); exit;
+           
+            fputcsv($fh, $x);
+        }
+        fclose($fh);
+        exit;
+        
+        
+    }
+    
+    function priceGridExcel()
+    {
+        ini_set('memory_limit', '1024M'); 
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $m = DB_DataObject::Factory('ipshead');
+        $m->orderBy('ipshead_name ASC');
+        $names = $m->fetchAll('ipshead_id' , 'ipshead_name');
+        
+        $head = array_values($names);
+        $ipshead_ids = array_keys($names);
+        array_unshift($head, '');
+        array_unshift($head, '');
+        array_unshift($ipshead_ids, '');
+        array_unshift($ipshead_ids, '');
+        
+        $m = DB_DataObject::Factory('ipshead');
+        $m->selectAdd();
+        $m->selectAdd('ipshead_id, (SELECT curr_name from curr_symbol where curr_id = ipshead_curr_id) as ipshead_curr');
+        $cnames = $m->fetchAll('ipshead_id' , 'ipshead_curr');
+        
+        //$titles = array('','');
+        $dindex  = array('item_brand' , 'item_number');
+       $titles = $dindex  ;
+        foreach($names as $id=>$name) {
+            $titles[] = $cnames[$id];
+        }
+        
+        $fn = 'pricelist - ' . date('Y-m-d') ;
+        $se = false;
+        
+        $se_config=  array(
+            'workbook' => substr($fn, 0, 31),
+            'head' => array($head),
+            'nonspacer' => true,
+            'cols' => array(),
+            'leave_open' => true
+        );
+        
+         
+        $rows = $this->toExcelRows();
+        
+        //echo '<PRE>';print_r($rows);
+        
+        foreach ($rows as $row){
+            if ($titles !== false) {
+                foreach ($head as $i => $col){
+                    
+                    $se_config['cols'][] = array(
+                        'header'=> isset($titles[$i]) ? $titles[$i] : $dindex[$i],
+                        'dataIndex'=> $ipshead_ids[$i] ? 'price_' . $ipshead_ids[$i] : $dindex[$i], //'item_number',
+                        'width'=>  75,
+                    );
+                    
+                    $se = new Pman_Core_SimpleExcel(array(), $se_config);
+                }
+                
+                $titles = false;
+            }
+            $se->addLine($se_config['workbook'], $row);
+        }
+        
+        $se->send($fn .'.xls');
+        exit;
+        
+    }
+    
+    function toExcelRows()
+    {
+        $it = DB_DataObject::Factory('ipsiteminfo');
+        $it->selectAdd();
+        
+        $it->selectAdd('distinct(ipsitem_item_id) as item_id');
+        $item_ids = $it->fetchAll('item_id');
+        //DB_DataObject::debugLevel(1);
+        $in = DB_DataObject::Factory('item');
+        $in->orderBy('item_number ASC');
+        $in->whereAddIn('item_id', $item_ids, 'int');
+        $in->selectAs();
+        $in->selectAdd(" charass_getvalue('I', item_id, 'BRAND') as item_brand ");
+        $items = $in->fetchAll();
+        //print_R($items);
+        $rows = array();
+        $price = array();
+        
+        $it = DB_DataObject::Factory('ipsiteminfo');
+        $ipsitems = $it->fetchAll();
+        foreach ($ipsitems as $i){
+            $price[$i->ipsitem_item_id][$i->ipsitem_ipshead_id] = $i->ipsitem_price;
+        }
+        
+        foreach ($items as $i => $item){
+            $rows[$i] = $item->toArray();
+            $rows[$i]['item_brand'] = $item->item_brand;
+            foreach ($price[$item->item_id] as $k => $v){
+                $rows[$i]['price_' . $k] = $v;
+            }
+            
+        }
+        
+        return $rows;
+        
+    }
+}
diff --git a/DataObjects/Ipsprice.php b/DataObjects/Ipsprice.php
new file mode 100644 (file)
index 0000000..f54ea41
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Table Definition for ipsprice
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsprice extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsprice';            // table name
+    public $ipsprice_id;                     // int4(4)  
+    public $ipsprice_source;                 // text(-1)  
+    public $ipsprice_ipshead_id;             // int4(4)  
+    public $ipsprice_item_id;                // int4(4)  
+    public $ipsprice_qtybreak;               // numeric(-1)  
+    public $ipsprice_price;                  // numeric(-1)  
+    public $ipsprice_uomqtybreak;            // numeric(-1)  
+    public $ipsprice_uomqtybreak_uom_id;     // int4(4)  
+    public $ipsprice_uomprice;               // numeric(-1)  
+    public $ipsprice_uomprice_uom_id;        // int4(4)  
+    public $ipsprice_discountpercent;        // numeric(-1)  
+    public $ipsprice_discountfixed;          // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ipsprodcat.php b/DataObjects/Ipsprodcat.php
new file mode 100644 (file)
index 0000000..f92574f
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for ipsprodcat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ipsprodcat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ipsprodcat';          // table name
+    public $ipsprodcat_id;                   // int4(4)  not_null default_nextval%28ipsprodcat_ipsprodcat_id_seq%29 primary_key
+    public $ipsprodcat_ipshead_id;           // int4(4)  not_null
+    public $ipsprodcat_prodcat_id;           // int4(4)  not_null
+    public $ipsprodcat_qtybreak;             // numeric(-1)  not_null
+    public $ipsprodcat_discntprcnt;          // numeric(-1)  not_null
+    public $ipsprodcat_fixedamtdiscount;     // numeric(-1)  not_null default_0.00
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Item.php b/DataObjects/Item.php
new file mode 100644 (file)
index 0000000..ead1893
--- /dev/null
@@ -0,0 +1,1562 @@
+<?php
+/**
+ * Table Definition for item
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Item extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'item';                // table name
+    public $item_id;                         // int4(4)  not_null default_nextval%28%28item_item_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $item_number;                     // text(-1)  not_null unique_key unique_key unique_key unique_key
+    public $item_descrip1;                   // text(-1)  not_null
+    public $item_descrip2;                   // text(-1)  not_null
+    public $item_classcode_id;               // int4(4)  not_null
+    public $item_picklist;                   // bool(1)  not_null
+    public $item_comments;                   // text(-1)  
+    public $item_sold;                       // bool(1)  not_null
+    public $item_fractional;                 // bool(1)  not_null
+    public $item_active;                     // bool(1)  not_null
+    public $item_type;                       // bpchar(-1)  not_null
+    public $item_prodweight;                 // numeric(-1)  not_null
+    public $item_packweight;                 // numeric(-1)  not_null
+    public $item_prodcat_id;                 // int4(4)  not_null
+    public $item_exclusive;                  // bool(1)  not_null
+    public $item_listprice;                  // numeric(-1)  not_null
+    public $item_config;                     // bool(1)  
+    public $item_extdescrip;                 // text(-1)  
+    public $item_upccode;                    // text(-1)  
+    public $item_maxcost;                    // numeric(-1)  not_null
+    public $item_inv_uom_id;                 // int4(4)  not_null
+    public $item_price_uom_id;               // int4(4)  not_null
+    public $item_warrdays;                   // int4(4)  default_0
+    public $item_freightclass_id;            // int4(4)  
+    public $item_tax_recoverable;            // bool(1)  not_null default_true
+
+    
+   /**
+    * Getter / Setter for $item_classcode_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function classcode() {
+        return func_num_args() ? $this->link('item_classcode_id', func_get_arg(0)) : $this->link('item_classcode_id');
+    }
+
+   /**
+    * Getter / Setter for $item_freightclass_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freightclass() {
+        return func_num_args() ? $this->link('item_freightclass_id', func_get_arg(0)) : $this->link('item_freightclass_id');
+    }
+
+   /**
+    * Getter / Setter for $item_inv_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function inv_uom() {
+        return func_num_args() ? $this->link('item_inv_uom_id', func_get_arg(0)) : $this->link('item_inv_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $item_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('item_price_uom_id', func_get_arg(0)) : $this->link('item_price_uom_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {   
+        if(isset($q['_with_year_total'])){
+            $this->item_active = true;
+            $this->item_sold = true;
+            
+            $p = DB_DataObject::factory('period');
+            $p->selectAdd();
+            $p->selectAdd("
+                period_id,
+                extract(year from period_start) as year
+            ");
+            $p->whereAdd("extract(year from period_start) = extract(year from NOW()) OR extract(year from period_start) = extract(year from NOW() + INTERVAL '1 YEAR')");
+            $period_ids = $p->fetchAll('period_id','year');
+            $pids = array();
+            foreach ($period_ids as $id=>$y){
+                $pids[$y][] = $id; 
+            }
+            $this_year_period_ids = implode(",", $pids[date('Y')]);
+            $next_year_period_ids = implode(",", $pids[date('Y') + 1]);
+            
+            $q['_in_cust_id'] = (int) $q['_in_cust_id'];
+            
+            $invchead_cust_id = "AND invchead_cust_id = {$q['_in_cust_id']}";
+            $salesforecast_cust_id = "AND salesforecast_cust_id = {$q['_in_cust_id']}";
+            
+            if($q['_in_cust_id'] < 0){
+                $invchead_cust_id = '';
+                $salesforecast_cust_id = '';
+            }
+            if($q['_in_cust_id'] == -2){
+                $ci = DB_DataObject::factory('custinfo');
+                $ids = $ci->topCustomerIdsBySalesQty();
+                $list_ids = implode(',', $ids);
+                $invchead_cust_id = "AND invchead_cust_id NOT IN ({$list_ids})";
+                $salesforecast_cust_id = "AND salesforecast_cust_id NOT IN ({$list_ids})";
+            }
+            
+            $this->selectAdd("
+                (SELECT 
+                    ROUND(COALESCE(SUM(salesforecast_sum),0))
+                FROM  
+                    salesforecast
+                LEFT JOIN 
+                    itemsite 
+                ON 
+                    salesforecast_itemsite_id = itemsite_id 
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    itemsite_item_id = item_id 
+                    AND
+                    salesforecast_is_all_buyers = TRUE
+                    AND
+                    salesforecast_period_id IN ({$this_year_period_ids})
+                ) AS company_estimates,
+                
+                (SELECT 
+                    ROUND(COALESCE(SUM(invcitem_billed),0))
+                FROM  
+                    invcitem
+                LEFT JOIN 
+                    invchead 
+                ON 
+                    invcitem_invchead_id = invchead_id
+                LEFT JOIN
+                    itemsite
+                ON
+                    invcitem_item_id = itemsite_item_id
+                WHERE
+                    itemsite_stocked = TRUE
+                    AND
+                    invcitem_item_id = item_id 
+                    AND 
+                    extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '2 YEAR')
+                    $invchead_cust_id
+                ) AS total_before_last_year,
+                
+                (SELECT
+                    ROUND(COALESCE(SUM(invcitem_billed),0))
+                FROM  
+                    invcitem
+                LEFT JOIN 
+                    invchead 
+                ON 
+                    invcitem_invchead_id = invchead_id
+                LEFT JOIN
+                    itemsite
+                ON
+                    invcitem_item_id = itemsite_item_id
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    invcitem_item_id = item_id
+                    AND
+                    extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
+                    $invchead_cust_id
+                ) AS total_last_year,
+               
+                (SELECT
+                    ROUND(COALESCE(SUM(invcitem_billed),0))
+                FROM  
+                    invcitem
+                LEFT JOIN 
+                    invchead 
+                ON 
+                    invcitem_invchead_id = invchead_id
+                LEFT JOIN
+                    itemsite
+                ON
+                    invcitem_item_id = itemsite_item_id
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    invcitem_item_id = item_id 
+                    AND
+                    extract(year from invchead_invcdate) = extract(year from NOW())
+                    $invchead_cust_id
+                ) AS total_this_year,
+               
+                (SELECT
+                    ROUND(COALESCE(SUM(salesforecast_qty),0))
+                FROM  
+                    salesforecast
+                LEFT JOIN
+                    itemsite
+                ON 
+                    salesforecast_itemsite_id = itemsite_id 
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    itemsite_item_id = item_id 
+                    AND 
+                    salesforecast_period_id IN ({$this_year_period_ids}) 
+                    $salesforecast_cust_id
+               ) AS forecast_this_year,
+               
+                (SELECT
+                    ROUND(COALESCE(SUM(salesforecast_qty),0))
+                FROM  
+                    salesforecast
+                LEFT JOIN
+                    itemsite
+                ON 
+                    salesforecast_itemsite_id = itemsite_id 
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    itemsite_item_id = item_id 
+                    AND 
+                    salesforecast_period_id IN ({$next_year_period_ids}) 
+                    $salesforecast_cust_id
+               ) AS forecast_next_year,
+               
+               (SELECT
+                    MAX(period_start)
+                FROM  
+                    period
+                LEFT JOIN
+                    salesforecast
+                ON 
+                    period_id = salesforecast_period_id 
+                LEFT JOIN
+                    itemsite
+                ON
+                    salesforecast_itemsite_id = itemsite_id 
+                WHERE 
+                    itemsite_stocked = TRUE
+                    AND
+                    itemsite_item_id = item_id 
+                    AND 
+                    salesforecast_qty != 0
+                    $salesforecast_cust_id
+               ) AS last_forecast_entered
+           ");
+        }
+        
+        if (!empty($q['_charass_brand_value'])) {
+            $this->whereAdd("charass_getvalue('I', item_id, 'BRAND') = '{$this->escape($q['_charass_brand_value'])}'"); 
+        }
+        
+        if (!empty($q['_charass_group_value'])) {
+            $this->whereAdd("charass_getvalue('I', item_id, 'PRODUCTGROUP') = '{$this->escape($q['_charass_group_value'])}' "); 
+        }
+        
+        if(isset($q['_with_itemsrc_active'])){
+            $this->selectAdd("
+                (SELECT 
+                    count(itemsrc_active)
+                FROM  
+                    itemsrc
+                WHERE 
+                    itemsrc_item_id = item_id
+                    AND
+                    itemsrc_active = TRUE
+                ) AS itemsrc_active
+            ");
+        }
+        
+       if(isset($q['_with_last_purchase_price'])){
+            $this->selectAdd("
+                (SELECT 
+                    poitem_unitprice
+                FROM  
+                    poitem
+                LEFT JOIN
+                    itemsite
+                ON 
+                    poitem_itemsite_id = itemsite_id
+                WHERE 
+                    itemsite_item_id = item_id
+                ORDER BY
+                    poitem_duedate DESC
+                LIMIT 1
+                ) AS last_purchase_price,
+                
+                (SELECT 
+                    curr_name
+                FROM  
+                    poitem
+                LEFT JOIN
+                    itemsite
+                ON 
+                    poitem_itemsite_id = itemsite_id
+                LEFT JOIN
+                    pohead
+                ON 
+                    poitem_pohead_id = pohead_id
+                LEFT JOIN
+                    curr_symbol
+                ON 
+                    pohead_curr_id = curr_id
+                WHERE 
+                    itemsite_item_id = item_id
+                ORDER BY
+                    poitem_duedate DESC
+                LIMIT 1
+                ) AS last_purchase_price_curr_name
+            ");
+        }
+        
+        if (isset($q['_fetchPrices']) ) {
+            if (empty($q['items'])) {
+                $roo->jerr("no items to list");
+            }
+            return $this->applyFilterPrices($roo, $q['items']);
+        }
+        
+        if (!empty($q['_costgrid'])) {
+            $this->costGrid();
+        }
+        if (!empty($q['_syncFromHK'])) {
+            $this->syncFromHK($roo, $q);
+        }
+        if (!empty($q['_with_prodcat'])) {
+            $this->joinAddProdCat();
+            $this->selectAddStdCost();
+        }
+        if (!empty($q['_with_itemsite'])) {
+            $this->joinAddItemsite();
+        }
+        if (!empty($q['_with_itemcost'])) {
+            $this->joinAddItemcost();
+        }
+        
+        if(!empty($q['cohead_cust_id'])){
+            
+            $ch = false;
+            
+            if (!empty($q['cohead_id'])) {
+                $ch = DB_DataObject::Factory('cohead');
+                $ch->get($q['cohead_id']);
+                
+            }
+            
+            $cid = (int)$q['cohead_cust_id'];
+            $cust = DB_DataObject::Factory('custinfo');
+            $cust->get($cid);
+            
+            $curr_id = $cust->cust_curr_id;
+            if ($ch) {
+                $curr_id = $ch->cohead_curr_id;
+            }
+            
+            
+            
+            $this->selectAdd("
+                round(itemprice(itemsite.itemsite_item_id, $cid, -1, 1,   {$curr_id},  NOW()::date),3)
+                    as item_price
+            ");
+            
+        }
+        
+        if (!empty($q['_with_char'])) {
+            $this->selectAddChars($q); 
+        }
+        if (!empty($q['_with_brand'])) {
+            $this->whereAdd(" itemcharvalue(item_id, 'BRAND') = '{$this->escape($q['_with_brand'])}'");
+        }
+        
+        
+         if (!empty($q['query']['number_or_name'])) {
+            //DB_DataObject::debugLevel(1);
+            $v = $this->escape($q['query']['number_or_name']);
+            $this->whereAdd("
+                    item_number ilike '$v%'
+                    OR
+                    item_descrip1 ilike '%$v%'
+                    ");
+            
+            
+        }
+        
+        if(isset($q['_with_image'])){
+            $img = DB_DataObject::factory('Images');
+            $this->selectAdd("
+                (SELECT 
+                    id
+                 FROM
+                    {$img->tableName()}
+                 WHERE
+                    ontable = '{$this->tableName()}'
+                 AND
+                    onid = item_id
+                ) AS item_image_id,
+                
+                (SELECT 
+                    filename
+                 FROM
+                    {$img->tableName()}
+                 WHERE
+                    ontable = '{$this->tableName()}'
+                 AND
+                    onid = item_id
+                ) AS item_image_filename,
+                (SELECT 
+                    ROUND(SUM (width / height), 2) 
+                 FROM
+                    {$img->tableName()}
+                 WHERE
+                    ontable = '{$this->tableName()}'
+                 AND
+                    onid = item_id
+                ) AS item_image_size,
+                
+                false AS item_image_from_hk
+            ");
+        }
+        if(isset($q['_with_stock_balance'])){
+            $this->selectAdd('0 as item_stock_balance');
+            $this->_extra_cols = array('item_stock_balance');
+        }
+        
+        if(isset($q['_rename_sku'])){
+            $this->selectAdd("
+                (
+                    SELECT 
+                            COUNT(item_id)
+                    FROM 
+                            item
+                    WHERE
+                            item_number = '{$this->escape($q['_rename_sku'])}'
+                ) AS is_exist
+            ");
+        }
+        
+        if(!empty($q['query']['not_in_db'])) {
+            $db = urlencode($q['query']['not_in_db']);
+            $base = substr($roo->baseURL , 0, strlen($roo->baseURL) - strlen('hk.php')) ;
+            $url = 'http://localhost'. $base   .$db.'.php/Roo/Item?_distinct=item_number&_columns=item_number&limit=99999';
+             
+         
+            //var_dump($url);exit;
+            $res = json_decode(file_get_contents($url));
+            $n = array();
+            foreach($res->data as $o) {
+                $n[] = $o->item_number;
+            }
+            $this->whereAddIn('!item_number', $n, 'string');
+        }
+        
+        if(!empty($q['_with_salesaccnt'])){
+            $this->selectAdd("
+                (
+                    SELECT
+                            accnt_descrip
+                    FROM
+                            accnt
+                    WHERE
+                            accnt_id = (
+                                            SELECT
+                                                    salesaccnt_sales_accnt_id
+                                            FROM
+                                            (
+                                                SELECT 
+                                                        salesaccnt_sales_accnt_id,
+                                                        CASE WHEN ( (salesaccnt_custtype_id<>-1) AND (salesaccnt_prodcat_id<>-1) ) THEN 'A'
+                                                            WHEN ( (salesaccnt_custtype_id<>-1) AND (salesaccnt_prodcat_id=-1) ) THEN 'B'
+                                                            WHEN ( (salesaccnt_custtype_id=-1) AND (salesaccnt_prodcat_id<>-1) ) THEN 'C'
+                                                       ELSE 'D'
+                                                       END AS orderby
+                                                FROM
+                                                        salesaccnt
+                                                WHERE
+                                                        (salesaccnt_warehous_id=-1)
+                                                        AND  
+                                                            ( 
+                                                                    (salesaccnt_prodcat='.*') 
+                                                                    OR
+                                                                    ( 
+                                                                            (salesaccnt_prodcat_id=-1)
+                                                                            AND
+                                                                            (salesaccnt_prodcat <> '')
+                                                                    ) 
+                                                                    OR
+                                                                    ( 
+                                                                            (salesaccnt_prodcat_id=item_prodcat_id) 
+                                                                    ) 
+                                                            )
+                                                        AND  
+                                                            ( 
+                                                                    (salesaccnt_custtype='.*') 
+                                                                    OR
+                                                                    ( 
+                                                                            (salesaccnt_custtype_id=-1) 
+                                                                            AND
+                                                                            (salesaccnt_custtype<>'') 
+
+                                                                    ) 
+                                                            )
+                                                ORDER BY orderby,salesaccnt_custtype DESC, salesaccnt_prodcat DESC
+                                                LIMIT 1
+                                           ) AS x
+                                        )
+                ) AS item_salesaccnt
+
+            ");
+        }
+        
+        
+    }
+    
+    
+    function selectAddStdCost()
+    {
+        $m = DB_DataObject::Factory('costelem');
+        $m->get('costelem_type', 'Material');
+         
+         $this->selectAdd("   
+            (SELECT itemcost_actcost FROM itemcost
+                    WHERE
+                        itemcost_item_id = item_id
+                    AND
+                        itemcost_costelem_id  = {$m->pid()}
+                    LIMIT 1
+            ) as item_actcost,
+        
+            (SELECT
+                    itemcost_stdcost FROM itemcost
+                    WHERE
+                        itemcost_item_id = item_id
+                    AND
+                        itemcost_costelem_id  = {$m->pid()}
+                    LIMIT 1
+            ) as item_base_cost,
+            
+            stdcost(item_id) as item_stdcost,
+            (SELECT
+                    itemcost_updated FROM itemcost
+                    WHERE
+                        itemcost_item_id = item_id
+                    AND
+                        itemcost_costelem_id  = {$m->pid()}
+                        LIMIT 1
+            ) as  itemcost_updated,
+            
+            
+            (SELECT
+                    curr_name
+                FROM
+                    curr_symbol
+                WHERE
+                    curr_base = true
+            ) as item_base_curr,
+            
+            
+            
+            (SELECT
+                    curr_name
+                FROM
+                    itemcost
+                LEFT JOIN
+                    curr_symbol
+                ON
+                    itemcost_curr_id = curr_id
+                WHERE
+                
+                itemcost_item_id = item_id
+                LIMIT 1
+            ) as item_curr_name
+            
+        ");
+    }
+    
+    function joinAddProdCat()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN
+                prodcat
+            ON
+                prodcat_id = item_prodcat_id
+            
+        ";
+        $d = DB_DataObject::factory('prodcat');
+        $this->selectAs($d, 'item_prodcat_id_%s');
+        
+    }
+    
+    function joinAddItemsite()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN
+                itemsite
+            ON
+                itemsite_item_id = item_id
+            
+            LEFT JOIN
+                costcat
+            ON
+                itemsite_costcat_id = costcat_id
+            LEFT JOIN
+                plancode
+            ON
+                itemsite_plancode_id = plancode_id
+            LEFT JOIN
+                location
+            ON
+                itemsite_location_id = location_id
+            
+        ";
+        
+        $d = DB_DataObject::factory('itemsite');
+        $this->selectAs($d, 'item_itemsite_id_%s');
+        
+        $d = DB_DataObject::factory('costcat');
+        $this->selectAs($d, '%s');
+        
+        $d = DB_DataObject::factory('plancode');
+        $this->selectAs($d, '%s');
+        
+        $d = DB_DataObject::factory('location');
+        $this->selectAs($d, '%s');
+        
+    }
+    
+    function joinAddItemcost()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN
+                itemcost
+            ON
+                itemcost_item_id = item_id
+            LEFT JOIN
+                curr_symbol
+            ON
+                itemcost_curr_id = curr_id
+            
+        ";
+        
+        $d = DB_DataObject::factory('itemcost');
+        $this->selectAs($d, 'item_itemcost_id_%s');
+        
+        $d = DB_DataObject::factory('curr_symbol');
+        $this->selectAs($d, '%s');
+        
+        
+    }
+    
+    
+    function beforeInsert($q,$roo) 
+    {
+        
+        // make sure it's upper case..
+        $q['item_number'] = strtoupper($q['item_number']);
+        $this->item_number = $q['item_number'];
+        
+        if(preg_match('/^DS-/', $this->item_number, $match) && $this->item_type == 'P'){
+            $roo->jerr('DS-* should all be non-products');
+        }
+        
+        if (isset($q['_fetchPrices']) ) {
+            if (empty($q['items'])) {
+                $roo->jerr("no items to list");
+            }
+            return $this->applyFilterPrices($roo, $q['items']);
+        }
+        
+        $item = DB_DataObject::factory($this->tableName());
+        if($item->get('item_number', $q['item_number'])){
+            $roo->jerr("item number already exist");
+        }
+        
+        foreach($this->defaults() as $k=>$v) {
+            if(!isset($this->$k)){
+                $this->$k = $v;
+            }
+        }
+        
+    }
+    
+    
+    function beforeUpdate($old,$q,$roo)
+    {   
+        
+        if (isset($q['_rename_sku'])) {
+            
+            $sku = strtoupper(trim($q['_rename_sku']));
+            $ourdb = substr($this->database(), -2);
+        
+            if (!strlen($sku)) {
+                $roo->jerr("invalid sku");
+            }
+            
+            $d = DB_DataObject::Factory('item');
+            
+            if ($d->get('item_number', $sku)) {
+                $roo->jerr("sku already exists");
+            }
+            // we shoudl be smarter here... - basically the sub office may need to
+            // only manipulate their codes.
+            // if ($roo->baseURL)
+            // 
+            // check if this sku exist in other database and whether the new name exist!
+            if(!empty($q['_check']) && $ourdb == 'hk' ){
+                $exist = $this->checkSKU($old->item_number, $sku, $roo);
+                if(count($exist)){
+                    $exist = array_keys($exist);
+                    array_unshift($exist, substr($this->database(), -2));
+                    $roo->jerr("This SKU is existing in others database", array('confirm' => $exist));
+                }
+            }
+            
+            $d = DB_DataObject::Factory('item');
+            $d->query("ALTER TABLE item DISABLE TRIGGER USER");
+            $d = DB_DataObject::Factory('item');
+            $d->query("UPDATE item SET item_number = '" . $d->escape($sku) . "' WHERE item_id = {$old->item_id}");
+            $d = DB_DataObject::Factory('item');
+            $d->query("ALTER TABLE item ENABLE TRIGGER USER"); 
+            
+            
+            if(!empty($q['_can_change_sku']) && $ourdb == 'hk'){
+                $exist = $this->changeSKU($old->item_number,$sku, $roo);
+                $exist = array_keys($exist); // remove us...???? = this code looks odd..
+                array_unshift($exist, substr($this->database(), -2));
+                $roo->jok($exist);
+            }
+            
+            $roo->jok('UPDATED');
+        }
+        
+    }
+    
+    function onInsert($q,$roo)
+    {
+        if(!empty($q['_update_related'])){
+            $this->updateItemsite($q, $roo);
+            if ($this->item_type == 'P') { /// purchased
+                $cursym = DB_DataObject::Factory('curr_symbol');
+                $cursym->get($q['item_itemcost_id_itemcost_curr_id']);
+            
+            
+                // update item cost if it's a regulare costing..
+                $this->updateItemCost($roo, $cursym->curr_name, $q['item_itemcost_id_itemcost_actcost']);
+            }
+        }
+    }
+    
+    function onUpdate($old, $q,$roo)
+    {
+        if(!empty($q['_update_related'])){
+            $this->updateItemsite($q,$roo);
+            if ($this->item_type == 'P') { /// purchased
+                $cursym = DB_DataObject::Factory('curr_symbol');
+                $cursym->get($q['item_itemcost_id_itemcost_curr_id']);
+    
+                $this->updateItemCost($roo, $cursym->curr_name, $q['item_itemcost_id_itemcost_actcost']);
+            }
+        }
+        
+    }
+    
+    function updateItemsite($q,$roo)
+    {
+        $itemsite = DB_DataObject::factory('itemsite');
+        $itemsite2 = false;
+        if($itemsite->get('itemsite_item_id', $this->pid())){
+            $itemsite2 = clone ($itemsite);
+        }
+        
+        $itemsite->setFrom($q,"item_itemsite_id_%s");
+        
+        foreach($itemsite->defaults($this->item_type) as $k=>$v) {
+            if(!isset($itemsite->$k)){
+                $itemsite->$k = $v;
+            }
+        }
+        
+        // check reorder level
+        
+        if($itemsite->itemsite_stocked && $itemsite->itemsite_reorderlevel <= 0){
+            $roo->jerr("Stocked items must have postive reorder level specified.");
+        }
+        
+        $itemsite->itemsite_item_id = $this->pid();
+        
+        $itemsite2   ? $itemsite->update($itemsite2) : $itemsite->insert();
+        
+    }
+    
+    
+    function selectAddChars($q)
+    {
+        $ch = DB_DAtaObject::Factory('char');
+        $ch->char_items = true;
+        $ch->find();
+        $ret = array();
+        while ($ch->fetch()) {
+            $nm = 'item_char_' . strtolower(preg_replace('/[^a-z]+/i','_', $ch->char_name));
+            $ret[] = $nm;
+        
+            $this->selectAdd("
+                itemcharvalue(item_id, '{$ch->char_name}') as $nm
+            ");
+            if (!empty($q['sort']) && $q['sort'] == $nm) {
+                $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
+                $this->orderBy("itemcharvalue(item_id, '{$ch->char_name}') $dir, item_number ASC");
+            }
+        }
+        return $ret;
+    
+    }
+    
+    
+    function applyFilterPrices($roo, $items)
+    {
+        //DB_DataObject::debugLevel(1);
+         
+        
+        $i = DB_DataObject::Factory('itemsite');
+        $i->whereAddIn('join_itemsite_item_id_item_id.item_number', array_keys($items), 'string');
+        $i->autoJoin();
+        $all = $i->fetchAll();
+        if (count($items) != count($all)) {
+            $roo->jerr("Could not find references for all items listed");
+        }
+        $ret = array();
+        
+        foreach($all as $i) {
+            $ret[$i->itemsite_item_id_item_number] = $i->cogsprice($items[$i->itemsite_item_id_item_number] );
+            if (!$ret[$i->itemsite_item_id_item_number] ) {
+                $roo->jerr("No price details available for {$i->itemsite_item_id_item_number}");
+            }
+        }
+        
+        $roo->jdata($ret);
+         
+        
+        
+    }
+    function itemsite()
+    {
+        $d = DB_DataObject::factory('itemsite');
+        if (!  $d->get('itemsite_item_id', $this->pid())) {
+            return false;
+        }
+        return $d;
+        
+     
+    }
+   
+    
+    /**
+     * returns an array of bomitem
+     */
+    function kitparts()
+    {
+        $b = DB_DataObjecT::Factory('bomitem');
+        $b->bomitem_parent_item_id = $this->pid();
+        $b->orderBy('bomitem_seqnumber ASC');
+        return $b->fetchAll();
+     
+    }
+    
+    
+    
+    
+    
+    
+    
+    function defaults()
+    {
+        static $pc = false;
+        if (!$pc) { 
+            $pc = DB_DataObject::Factory('prodcat');
+            if (!$pc->get('prodcat_code', 'PRODUCT')) {
+                $ff = HTML_FlexyFramework::get();
+                $ff->page->jerr("product category PRODUCT missing");
+            }
+        }    
+        
+        return  array(
+            'item_classcode_id'=> $this->sqlValue("(SELECT classcode_id FROM classcode
+                                       WHERE classcode_code = 'SOLD'
+                                       LIMIT 1)"), //??? use the first class code.
+           
+           'item_sold'=>true, // 
+           'item_fractional'=>false,
+           'item_active'=>true,
+           'item_prodweight'=>0,
+           'item_packweight'=>0,
+           'item_exclusive'=>false,
+           'item_inv_uom_id'=>$this->sqlValue("(SELECT uom_id FROM uom WHERE uom_name='EA' LIMIT 1)"), 
+           'item_price_uom_id'=> $this->sqlValue("(SELECT uom_id FROM uom WHERE uom_name='EA' LIMIT 1)"),
+        
+           //'item_prodcat_id'=>0,
+           'item_config'=>false, // does it need configuratuion?
+           
+           'item_listprice' => 0,
+           'item_maxcost' => 0.0,
+           'item_upccode' => '',
+           'item_picklist' => true,
+            'item_type' => 'P',  // PRODUCT !! immportant
+            'item_tax_recoverable' => true,
+            
+            'item_prodcat_id' => $pc->prodcat_id,
+        );
+        
+    }
+    
+    
+    
+    function createNew($roo, $sku, $description, $opts=array())
+    {
+        //$roo->jerr(print_R($opts,true));
+        
+        $i = DB_DataObject::Factory('item');
+        if ($i->get('item_number', $sku)) {
+            $roo->jerr("item already exists?");
+        }
+        foreach($this->defaults() as $k=>$v) {
+            $i->$k = $v;
+        }
+        
+       
+        
+        $i->setFrom(array(
+           
+            'item_number'=> $sku,
+            'item_descrip1'=> $description,
+            'item_descrip2'=> $description,
+           // 'item_listprice'=>'lastPurchasePrice', << this can be worked out from HK RRP
+            'item_extdescrip'=> $description,
+          
+             
+        ));
+        $i->setFrom($opts);
+        
+        $i->insert();
+        $i = DB_DataObject::Factory('item');
+        if (!$i->get('item_number', $sku)) {
+            $roo->jerr('Creating item failed');
+        }
+        $is = DB_DataObject::Factory('itemsite');
+        $is->createOrFetchFromItem($roo, $i);
+        
+        return $i;
+        
+        
+    }
+    
+    function updateItemCost($roo, $curr, $cost, $date = false)
+    {
+         $ic = DB_DataObject::Factory('itemcost');
+         $ic->updateItemCost($roo, $this, $curr, $cost, $date);
+    }
+  
+    function costGrid()
+    {
+        
+        //DB_DataObject::DebugLevel(1);
+        $ic = DB_DataObject::Factory('itemcost');
+        
+        $ic->autoJoin();
+        $ic->selectAdd();
+        
+        $ic->selectAdd('itemcost_item_id,
+            join_itemcost_curr_id_curr_id.curr_name as itemcost_curr_id_curr_name,
+            itemcost_actcost
+                       
+                       ');
+        
+        $ic->itemcost_costelem_id   =  $ic->sqlValue("(SELECT costelem_id FROM costelem where costelem_type='Material' LIMIT 1)");
+        //DB_DataObject::DebugLevel(1);
+        $ic->find();
+        while ($ic->fetch()) {
+            $costs[$ic->itemcost_item_id] = array($ic->itemcost_curr_id_curr_name, $ic->itemcost_actcost);
+        }
+       
+        $is = DB_DataObject::factory('poitem');
+        $is->autoJoin();
+        $is->autoJoinPohead();
+        $is->autoJoinCurr();
+        
+        $is->selectAdd();
+        $is->selectAdd("
+            join_poitem_itemsite_id_itemsite_id.itemsite_item_id,
+            poitem_unitprice,
+            join_poitem_curr_symbol.curr_name
+        ");
+        $is->find();
+        
+        while ($is->fetch()){
+            $purchase_price[$is->itemsite_item_id] = array($is->curr_name, $is->poitem_unitprice);
+        };
+        
+        $m = DB_DataObject::Factory('item');
+        $m->item_type = 'P';
+        $m->item_sold = true;
+        $m->item_active = true;
+        $m->orderBy('item_number ASC');
+        $m->selectAdd('item_id,item_number,item_descrip1');
+        $chars = $m->selectAddChars(array());
+        
+        $m->selectAdd('item_id');
+        $m->find();
+        $lines = array();
+        while ($m->fetch()) {
+            $lines[$m->item_id] = $m->toArray('%s', true);
+        }
+         
+        // dump it...
+        $fn = 'costlist';
+        
+            
+        require_once 'Pman/Core/SimpleExcel.php';
+         
+        // $fn = (empty($filename) ? 'list-export-' : urlencode($filename)) . date('Y-m-d') ;
+         
+         
+         $se_config=  array(
+             'workbook' => substr($fn, 0, 31),
+             'cols' => array(),
+             'leave_open' => true
+         );
+        
+        
+        
+        $titles = array_merge($chars, array('ITEM CODE',       'description',  'description2', 'CUR',  'New Unit Price', 'Purchase CUR', 'Last Purchase Price'));
+        
+        $cols = array_merge($chars, array('item_number',       'item_descrip1',        'item_descrip2', 'unit_curr',   'unit_price', 'purr_curr', 'purr_price'));
+        
+        
+        foreach($cols as $i=>$col) {
+            $se_config['cols'][] = array(
+                'header'=> isset($titles[$i]) ? $titles[$i] : $col,
+                'dataIndex'=> $col,
+                'width'=>  150,
+               //     'renderer' => array($this, 'getThumb'),
+                 //   'color' => 'yellow', // set color for the cell which is a header element
+                  // 'fillBlank' => 'gray', // set 
+            );
+            $se = new Pman_Core_SimpleExcel(array(),$se_config);
+
+            
+        }
+        foreach($lines as $id => $n) {
+            
+            $costs[$id] = isset($costs[$id])  ? $costs[$id] : array(0,0);
+            $purchase_price[$id] = isset($purchase_price[$id]) ? $purchase_price[$id] : array('',0);
+            
+            $ldata = $n;
+            //foreach($chars as $k) {
+            //    $ldata[$k] = $n[$k];
+           // }
+            
+            
+            $ldata['unit_curr'] = $costs[$id][0];
+            $ldata['unit_price'] = $costs[$id][1];
+            
+            $ldata['purr_curr'] = $purchase_price[$id][0];
+            $ldata['purr_price'] = $purchase_price[$id][1];
+              
+            
+            $se->addLine($se_config['workbook'], $ldata);
+        }
+        $se->send($fn .'.xls');
+        exit;
+    
+        
+        
+           
+        
+        
+        
+    }
+    
+    function updateCharAss($k, $v)
+    {
+        $ca = DB_DAtaObject::factory('charass');
+        $ca->query("SELECT
+                charass_setvalue(
+                   'I',{$this->pid()},
+                   '{$this->escape($k)}', '{$this->escape($v)}'
+                );");
+        
+        
+    }
+    
+    function syncFromHK($roo, $q)
+    {
+        //$char = DB_DataObject::factory('char');
+        //$char->initDatabase();
+        
+        // get the product list from HK...
+        $db= substr($this->database(),-2);
+        $hk = substr($roo->baseURL , 0, strlen($roo->baseURL) - strlen('hk.php')) ;
+        
+        // offset..
+        if (empty($q['offset'])) {
+            $q['offset'] = 0;
+        }
+        $offset = $q['offset'] *1;
+        $limit = 25;
+        
+        if (!empty($q['_new_only'])) {
+            $limit = 9999; // alot...
+        }
+        
+        $url = 'http://localhost'. $hk .'hk.php/Roo/Item?limit='. $limit
+            .'&start=' . $offset .'&_with_char=1&_with_prodcat=1&_with_itemsite=1';
+            
+            
+            
+            
+        if (!empty($q['item_number'])) {
+            $url.='&query%5Bnumber_or_name%5D='.urlencode($q['item_number']);
+        }
+        if (!empty($q['_new_only'])) {
+            $url.='&query%5Bnot_in_db%5D='.urlencode($db);
+        }
+        
+         $this->debug("Requesting URL" . $url);
+         
+         
+         
+         
+         
+         
+         
+        //var_dump($url);exit;
+        $res = json_decode(file_get_contents($url));
+        ///print_R($res);exit;
+        if(count($res->data) < 1) {
+            $roo->jok(array('total' => 0));
+        }
+        foreach($res->data as $item) {
+            $this->syncFromHKItem($roo,$item);
+        }
+        //echo '<PRE>';print_R($res);
+        
+        $roo->jok(array('total' => $res->total, 'offset'=> $offset, 'limit' => $limit));
+        exit;
+        
+        
+        
+        
+    }
+    
+    function syncFromHKItem($roo,$data)
+    {
+        //echo '<PRE>';print_R($data);
+        // have we got this item?
+        $i = DB_DataObject::factory($this->tableName());
+        if ($i->get('item_number', $data->item_number)) {
+            // then it's a simple matter fo updating stuff.
+            
+            
+        
+            $is = DB_DataObject::Factory('itemsite');
+            
+            $is->syncFromHK($roo,  $i, $data);
+            if (!empty($data->itemcost_updated)) {
+                $i->updateItemCost($roo,  $data->item_curr_name, $data->item_actcost, $data->itemcost_updated);
+            }
+            // fix the brand / 
+            $i->updateCharAss('PRODUCTGROUP', $data->item_char_productgroup);
+            $i->updateCharAss('BRAND', $data->item_char_brand);
+            $ii  = clone($i);
+            $i->item_descrip1 = $data->item_descrip1;
+            $i->item_descrip2 = $data->item_descrip2;
+            $i->update($ii);
+            return;
+            
+        }
+        
+        
+        
+        
+        // create the item...
+        //DB_DataObject::debugLevel(1);
+        
+        $opts = array();
+        foreach(array(
+            'item_sold'  ,
+             'item_active' ,
+             'item_type' ,
+            
+            'item_prodweight' ,
+            'item_packweight'  ,
+            
+            'item_exclusive'  ,
+           
+            //'item_config'  ,
+            'item_extdescrip'  ,
+           // 'item_upccode'  ,
+           // 'item_maxcost' ,
+           
+            'item_warrdays'  ,
+            'item_tax_recoverable' ,
+            
+            'item_descrip1',
+            'item_descrip2',
+        )  as $k) {
+            $opts[$k] = $data->$k;
+        }
+        if (empty($data->item_descrip1)) {
+            $data->item_descrip1 = $data->item_number;
+            //$roo->jerr("Product {$data->item_number} does not have a description");
+        }
+        /*
+        'item_listprice'  ,
+        'item_classcode_id'
+        'item_prodcat_id'  ,
+        'item_inv_uom_id' ,
+        'item_price_uom_id'  ,
+        'item_freightclass_id' , // skip..
+       */
+        
+        $cc = DB_DataObject::factory('classcode');
+        if (!$cc->get('classcode_code', $data->item_classcode_id_classcode_code)) {
+            $roo->jerr("no class code {$data->item_classcode_id_classcode_code}");
+        }
+        $opts['item_classcode_id'] = $cc->pid();
+        
+        
+        $cc = DB_DataObject::factory('prodcat');
+        if (!$cc->get('prodcat_code', $data->item_prodcat_id_prodcat_code)) {
+            $cc = DB_DataObject::factory('prodcat');
+            $cc->setFrom($data, 'item_prodcat_id_%s');
+            $cc->insert();
+            
+            
+            
+          //  $roo->jerr("no prodcat code {$data->item_prodcat_id_prodcat_code}");
+        }
+        $opts['item_prodcat_id'] = $cc->pid();
+        
+       
+        $cc = DB_DataObject::factory('uom');
+        if (!$cc->get('uom_name', $data->item_inv_uom_id_uom_name)) {
+            $roo->jerr("no uom name {$data->item_inv_uom_id_uom_name}");
+        }
+        $opts['item_inv_uom_id'] = $cc->pid();
+        
+         $cc = DB_DataObject::factory('uom');
+        if (!$cc->get('uom_name', $data->item_price_uom_id_uom_name)) {
+            $roo->jerr("no uom name {$data->item_price_uom_id_uom_name}");
+        }
+        $opts['item_price_uom_id'] = $cc->pid();
+        
+        
+        // listprice
+        $curr = DB_DataObject::Factory('curr_symbol');
+        $curr->get('curr_name', 'HKD');
+        if (!empty($data->itemcost_updated)) {
+        
+            $opts['item_listprice'] = $this->sqlValue("currtobase({$curr->pid()}, {$data->item_listprice},'{$data->itemcost_updated}')");
+        }
+        
+        
+        $new_item = $this->createNew($roo, $data->item_number, $data->item_descrip1, $opts );
+        
+        
+        $is = DB_DataObject::Factory('itemsite');
+        
+        $is->syncFromHK($roo,  $new_item, $data);
+        
+        //if (!empty($))
+        
+        
+        
+        
+        if (!empty($data->itemcost_updated)) {
+            $new_item->updateItemCost($roo,  $data->item_curr_name, $data->item_actcost, $data->itemcost_updated);
+        }
+            // fix the brand / 
+        $new_item->updateCharAss('PRODUCTGROUP', $data->item_char_productgroup);
+        $new_item->updateCharAss('BRAND', $data->item_char_brand);
+        
+        
+    }
+    
+    function postListFilter($ar, $au, $req)
+    {   
+        if(isset($req['_with_stock_balance'])){
+            $item_ids = array();
+            foreach ($ar as $i => $a){
+                $item_ids[] = $a['item_id'];
+            }
+            
+            $l = DB_DataObject::factory('location')->defaultConfigLocation();
+            
+            $itemsite = DB_DataObject::factory('itemsite');
+            $itemsite->whereAddIn('itemsite_item_id', $item_ids, 'int');
+            $itemsite->selectAdd();
+            $itemsite->selectAdd("
+                    itemsite_item_id, invdetail_atdate(NOW()::date, {$l->pid()}, itemsite_id) as invdetail_balance_qty
+            ");;
+            $balance = $itemsite->fetchAll('itemsite_item_id', 'invdetail_balance_qty');
+            
+            foreach ($ar as $i => $a){
+                $ar[$i]['default_location_name'] = $l->location_name;
+                if(isset($balance[$a['item_id']])){
+                    $ar[$i]['item_stock_balance'] = $balance[$a['item_id']];
+                }
+            }
+            /*
+             
+            
+            $invdetail = DB_DataObject::factory('invdetail');
+            $invdetail->autoJoinfifo();
+            $invdetail->autoJoinHist();
+            $invdetail->selectAdd();
+            $invdetail->selectAdd("
+                COALESCE(SUM( invdetail_qty), 0) AS invdetail_balance_qty,
+                join_invhist.invhist_itemsite_id AS invhist_itemsite_id
+            ");
+            $invdetail->invdetail_location_id = $l->pid();
+            $invdetail->whereAdd("
+                join_invfifo.invfifo_void IS NULL OR join_invfifo.invfifo_void = 0
+            ");
+            $invdetail->whereAddIn('join_invhist.invhist_itemsite_id', array_values($itemsite_ids), 'int');
+            $invdetail->groupBy("join_invhist.invhist_itemsite_id");
+            $balance = $invdetail->fetchAll('invhist_itemsite_id','invdetail_balance_qty');
+            */
+            
+        }
+        
+        if(isset($req['_with_image'])){
+            $db = substr($this->database(), -2);
+            if($db == 'hk'){
+                return $ar;
+            }
+            foreach($ar as $i => $a){
+                if(!empty($a['item_image_id']) && !empty($a['item_image_filename'])){
+                    continue;
+                }
+                $pg= HTML_FlexyFramework::get()->page;
+                $url = "http://localhost{$pg->rootURL}/hk.php/Roo/Item?lookup[item_number]=".$a['item_number']."&_with_image=1";
+                $ret = json_decode(file_get_contents($url),true);
+                if(empty($ret['data']['item_image_id']) && empty($ret['data']['item_image_filename'])){
+                    continue;   
+                }
+                
+                $ar[$i]['item_image_id'] = $ret['data']['item_image_id'];
+                $ar[$i]['item_image_filename'] = $ret['data']['item_image_filename'];
+                $ar[$i]['item_image_size'] = $ret['data']['item_image_size'];
+                $ar[$i]['item_image_from_hk'] = true;
+            }
+        }
+        
+        return $ar;
+    }
+    
+    function lookupSKU($sku)
+    {
+        static $cache = array();
+        
+        $sku = trim($sku);
+        
+        $i = DB_DataObject::factory('item');
+        
+        $is_au = (substr($i->database(),-2) == 'au') ? true : false;
+        
+        if(!$is_au){
+            if($i->get('item_number', $sku)){
+                return $i;     
+            }
+            
+            $i = DB_DataObject::factory('item');
+            $i->whereAdd("UPPER(item_number) = UPPER('{$this->escape($sku)}')");
+            if($i->find(true)){
+                return $i;     
+            } 
+
+            return false;
+        }
+        
+        // this is all australia specific.. not sure if it should
+        // really be here...
+        
+        if (isset($cache[$sku])) {
+            return $cache[$sku];
+        }
+        
+        if (preg_match('/^B_/', $sku)) {
+            $cache[$sku] = false;
+            return false;
+        }
+        
+        if ($sku[0] == '.') {
+            $sku = substr($sku, 1);
+        }
+        
+        
+        $i = DB_DataObject::factory('item');
+        if($i->get('item_number', $sku)){
+            $cache[$sku] = $i;
+            return $i;     
+        }
+        $i = DB_DataObject::factory('item');
+        $i->whereAdd("UPPER(item_number) = UPPER('{$this->escape($sku)}')");
+        if($i->find(true)){
+            return $i;     
+        } 
+         
+        $i = DB_DataObject::factory('item');
+       
+        $prefixes = array('SH', 'PH', 'UB', 'DS-', '0', '00', '000');
+        
+        foreach ($prefixes as $p){
+            if($i->get('item_number', $p . $sku)){
+                $cache[$sku] = $i;
+                return $i;     
+            }
+            if($i->get('item_number', $p . strtoupper($sku))){
+                $cache[$sku] = $i;
+                return $i;     
+            }
+        }
+        
+        $match = array(
+            'Z-GIFTVOUCHER' => array('/GIFTVOUCHER/' , '/GIFTCARD$/'),
+            'BPIMPERFECT'   => array('/^IMPERFECT1$/' , '/^IMPERFECT20$/', '/^IMPERFECT17$/', '/^IMPERFECT25$/'),
+            'DS-VPL'           => array('/^VPL\s+/'),
+            '30.1229'       => array('/30.1229R/'),
+            'DS-YMPC'       => array('/^YMPC\s+/'),
+            'DS-ASLB'       => array('/^ASLB\s+/'), // really a DS-???
+            'DS-YMSB'       => array('/^YMSB\s+/'),
+            'YMSR'       => array('/^YMSR\s+/'),
+            'YMAS'       => array('/^YMAS\s+/'),
+            'DS-RILFC'       => array('/^RILFC-.+/'),
+            'DS-VAL'       => array('/^VAL\s+/'),
+            'DS-RICMNLU'       => array('/^RICMNLU-/'),
+            'DS-IOL'       => array('/^IOL\s/'),
+           
+        );
+        
+        foreach ($match as $k => $v){
+            foreach ($v as $pattern){
+                if(preg_match($pattern, $sku)){
+                    if($i->get('item_number', $k)){
+                        $cache[$sku] = $i;
+                        return $i;     
+                    }
+                }
+            }
+        }
+        $cache[$sku] = false;
+        
+        return false;
+        
+        
+    }
+    
+    /*
+     * 
+     * check if this sku appear in other database
+     * Return other database name with id if exist as an array 
+     * 
+     * 
+     */
+    function checkSKU($old, $new, $roo)
+    {
+        
+        $system = $roo->uiConfig['xtuple_offices']; // define in Pman.php
+        
+        $ourdb = substr($this->database(), -2);
+        
+        $exist = array();
+        
+        $error = array();
+        
+        foreach ($system as $k => $s){
+            
+            if($s == $ourdb){
+                continue;
+            }
+            
+            $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Item?lookup[item_number]={$old}&_rename_sku={$new}";
+            
+            $ret = json_decode(file_get_contents($url),true);
+            if(!$ret['success']){
+                $roo->jerr("Error occur on getting item in {$s}, item_number : {$item_number}");
+            }
+
+            if(!count($ret['data']) || !$ret['data']['item_id']){
+                continue;
+            }
+            
+            if($ret['data']['is_exist']){
+                $error[] = "{$new} is already exist in {$s}";
+                continue;
+            }
+            
+            $exist[$s] = $ret['data']['item_id'];
+             
+        }
+        
+        if(count($error)){
+            $roo->jerr(implode("<BR/>", $error));
+        }
+        
+        return $exist;
+       
+        
+    }
+    
+    function changeSKU($old, $new, $roo)
+    {
+        $target = $this->checkSKU($old, $new, $roo);
+        
+        foreach ($target as $s => $id){
+            $url = "http://localhost{$roo->rootURL}/{$s}.php";
+            
+            require_once 'HTTP/Request.php';
+       
+            $req = new HTTP_Request( $url . '/Roo/Item' );
+            $req->setMethod(HTTP_REQUEST_METHOD_POST);
+            
+            $req->addPostData( array(
+                '_rename_sku' => $new,
+                'item_id' => $id
+            ));
+            
+            $res = $req->sendRequest();
+            
+            if (is_a($res,'PEAR_Error')) {
+                $roo->jerr("REMOTE REQUEST RETURNED: ". $res->toString());
+            }
+            $res = json_decode($req->getResponseBody());
+            
+            if (!is_object($res)) {
+                $roo->jerr("REMOTE REQUEST RETURNED: ". $req->getResponseBody());
+            }
+
+            if (!$res->success) {
+                $roo->jerr("REMOTE REQUEST RETURNED: ". $res->errorMsg);
+            }
+            
+        }
+        
+        return $target;
+
+    }
+    
+}
diff --git a/DataObjects/Itemalias.php b/DataObjects/Itemalias.php
new file mode 100644 (file)
index 0000000..7459dce
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for itemalias
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemalias extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemalias';           // table name
+    public $itemalias_id;                    // int4(4)  not_null default_nextval%28%28%22itemalias_itemalias_id_seq%22%29%3A%3Aregclass%29 primary_key primary_key
+    public $itemalias_item_id;               // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $itemalias_number;                // text(-1)  not_null unique_key multiple_key unique_key multiple_key
+    public $itemalias_comments;              // text(-1)  
+    public $itemalias_usedescrip;            // bool(1)  not_null
+    public $itemalias_descrip1;              // text(-1)  
+    public $itemalias_descrip2;              // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $itemalias_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemalias_item_id', func_get_arg(0)) : $this->link('itemalias_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemcost.php b/DataObjects/Itemcost.php
new file mode 100644 (file)
index 0000000..6155eb6
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Table Definition for itemcost
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemcost extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemcost';            // table name
+    public $itemcost_id;                     // int4(4)  not_null default_nextval%28%28itemcost_itemcost_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $itemcost_item_id;                // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $itemcost_costelem_id;            // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $itemcost_lowlevel;               // bool(1)  not_null default_false unique_key multiple_key unique_key multiple_key
+    public $itemcost_stdcost;                // numeric(-1)  not_null default_0
+    public $itemcost_posted;                 // date(4)  
+    public $itemcost_actcost;                // numeric(-1)  not_null default_0
+    public $itemcost_updated;                // date(4)  
+    public $itemcost_curr_id;                // int4(4)  not_null default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $itemcost_costelem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function costelem() {
+        return func_num_args() ? $this->link('itemcost_costelem_id', func_get_arg(0)) : $this->link('itemcost_costelem_id');
+    }
+
+   /**
+    * Getter / Setter for $itemcost_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('itemcost_curr_id', func_get_arg(0)) : $this->link('itemcost_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $itemcost_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemcost_item_id', func_get_arg(0)) : $this->link('itemcost_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function updateItemCost($roo, $item, $curr, $cost, $date) {
+       
+        
+        $itemcost = DB_DataObject::Factory('itemcost');
+        $itemcost2  = false;
+        if ($itemcost->get('itemcost_item_id', $item->pid())){
+            $itemcost2 = clone($itemcost);
+        }
+        
+        $cost = max(0.01, $cost); // most unitcosts entered have been including shipping.
+        //$cost = max($itemcost->itemcost_stdcost , $cost); // maximum please..
+        
+        // this is not a valid check -- stdcost is in base currency, however cost above should be in local currency.
+        
+        //if ($itemcost2 && $itemcost2->itemcost_stdcost == $cost) {
+        //    return;
+        //}
+        //DB_DataObject::debugLevel(1);
+        $cursym = DB_DataObject::Factory('curr_symbol');
+        if (!$cursym->get('curr_name', $curr)) {
+            $roo->jerr("invalid currency look for curr_name='$curr'");
+        }
+        $curr_id = $cursym->pid();
+        //DB_DataObject::debugLevel(1);
+        $date = empty($date) ? 'NOW()' : $date;
+        $itemcost->setFrom(array(
+        
+            // all cost have to be done in the base currency..
+           'itemcost_item_id'       => $item->pid(),
+           'itemcost_costelem_id'   => $itemcost->sqlValue("(SELECT costelem_id FROM costelem where costelem_type='Material' LIMIT 1)"),
+           'itemcost_stdcost'       => $itemcost->sqlValue("currtobase( $curr_id , $cost, '$date'::date ) * 1.1"),
+           
+           'itemcost_posted'        => $itemcost->sqlValue('startOfTime()'),
+           'itemcost_actcost'       => $cost,
+           'itemcost_updated'       => $itemcost->sqlValue('NOW()'),
+           
+           'itemcost_curr_id'       => $curr_id,
+           
+           'itemcost_lowlevel'      => false,
+        ));
+         
+        
+        $itemcost2   ? $itemcost->update($itemcost2) : $itemcost->insert();
+        
+        $ic = DB_DataObject::Factory('itemcost');
+        $ic->get($itemcost->pid());
+       
+        
+        
+        
+            
+    } 
+    
+}
diff --git a/DataObjects/Itemfile.php b/DataObjects/Itemfile.php
new file mode 100644 (file)
index 0000000..b87a7a7
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for itemfile
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemfile extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemfile';            // table name
+    public $itemfile_id;                     // int4(4)  
+    public $itemfile_item_id;                // int4(4)  
+    public $itemfile_title;                  // text(-1)  
+    public $itemfile_url;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemgrp.php b/DataObjects/Itemgrp.php
new file mode 100644 (file)
index 0000000..40e1618
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for itemgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemgrp';             // table name
+    public $itemgrp_id;                      // int4(4)  not_null default_nextval%28%28%22itemgrp_itemgrp_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $itemgrp_name;                    // text(-1)  
+    public $itemgrp_descrip;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemgrpitem.php b/DataObjects/Itemgrpitem.php
new file mode 100644 (file)
index 0000000..83ad898
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for itemgrpitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemgrpitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemgrpitem';         // table name
+    public $itemgrpitem_id;                  // int4(4)  not_null default_nextval%28%28%22itemgrpitem_itemgrpitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $itemgrpitem_itemgrp_id;          // int4(4)  unique_key multiple_key
+    public $itemgrpitem_item_id;             // int4(4)  unique_key multiple_key
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemimage.php b/DataObjects/Itemimage.php
new file mode 100644 (file)
index 0000000..80e5d3f
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for itemimage
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemimage extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemimage';           // table name
+    public $itemimage_id;                    // int4(4)  
+    public $itemimage_item_id;               // int4(4)  
+    public $itemimage_image_id;              // int4(4)  
+    public $itemimage_purpose;               // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemloc.php b/DataObjects/Itemloc.php
new file mode 100644 (file)
index 0000000..517fa81
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+/**
+ * Table Definition for itemloc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemloc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemloc';             // table name
+    public $itemloc_id;                      // int4(4)  not_null default_nextval%28%28%22itemloc_itemloc_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $itemloc_itemsite_id;             // int4(4)  not_null
+    public $itemloc_location_id;             // int4(4)  not_null
+    public $itemloc_qty;                     // numeric(-1)  not_null
+    public $itemloc_expiration;              // date(4)  not_null
+    public $itemloc_consolflag;              // bool(1)  
+    public $itemloc_ls_id;                   // int4(4)  
+    public $itemloc_warrpurc;                // date(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+     function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['_availqty'])) {
+            return $this->availQty($roo, json_decode($q['_availqty']), $q);
+        }
+        if (!empty($q['item_id'])) {
+            $it = DB_DataObject::Factory('itemsite');
+            $it->get('itemsite_item_id', $q['item_id']);
+            $this->itemloc_itemsite_id = $it->pid();
+            $this->orderBy('location_name ASC');
+        }
+        $this->joinAddLocation();
+        $this->selectAdd(' invdetail_atdate(NOW()::date, itemloc_location_id, itemloc_itemsite_id) as itemloc_realqty');
+        $this->whereAdd(' 0 != invdetail_atdate(NOW()::date, itemloc_location_id, itemloc_itemsite_id)  ');
+        
+    }
+    
+    function joinAddLocation()
+    {
+        $this->_join .= "
+            LEFT JOIN location 
+            ON location_id = itemloc_location_id
+        ";
+        $l = DB_DataObject::Factory('location');
+        $this->selectAs($l, '%s');
+        
+        
+    }
+    
+         /**
+          *
+     * look up how much stock is available at locations listed..
+     *[0] => stdClass Object
+        (
+            [item] => UI1002
+            [loc] => Kerry MY
+        )
+
+     */
+         
+    function itemsite()
+    {
+        $is  = DB_DataObject::Factory('itemsite');
+        $is->get($this->itemloc_itemsite_id);
+        return $is;
+    }
+    
+    
+    function beforeInsert($q, $roo)
+    {
+        if (isset($q['_availqty'])) {
+            // has to be post to allow long lists of items..
+            return $this->availQty($roo, json_decode($q['_availqty']),$q);
+            
+        }
+    }
+    
+    function availQty($roo,$q, $req)
+    {
+        $locs = array();
+        if (empty($q)) {
+            $roo->jdata(array());
+        }
+        foreach($q as $r) {
+            $locs[$r->loc] = 1;     
+            $items[$r->item] = 1;
+            
+        }
+        
+        //DB_DataObject::DebugLevel(1);
+        $loc = DB_DataObject::factory('location');
+        $loc->whereAddIn('location_name', array_keys($locs), 'string');
+        $lmap = $loc->fetchAll('location_name', 'location_id');
+        
+
+        $it = DB_DataObject::factory('itemsite');
+        $it->autoJoin();
+        $it->whereAddIn('join_itemsite_item_id_item_id.item_number', array_keys( $items ), 'string');
+        $imaps = $it->fetchAll('itemsite_item_id_item_number', 'itemsite_id');
+        
+          //$roo->jerr(print_r($q,true));
+        //DB_DAtaObject::DebugLevel(1);
+        // let's hammer the db...
+        $cn = false;
+        if (isset($req['curr_name'])) {
+               $cn = $this->escape( $req['curr_name']);
+        }
+        foreach($q as $r) {
+            if (!isset($imaps[$r->item]) || !isset($lmap[$r->loc])) {
+                $r->qty = 'UNKNOWN';
+                $ret[$r->id] = $r;
+                continue;
+            }
+            
+            $x = DB_DAtaObject::factory('itemloc');
+            $x->itemloc_itemsite_id = $imaps[$r->item];
+            $x->itemloc_location_id = $lmap[$r->loc];
+            $x->selectAdd();
+            //-- qtylocation(itemloc_location_id, -1, endoftime(), endoftime(), itemloc_itemsite_id, '', -1, -1) as qty
+            $x->selectAdd("
+                          
+                invdetail_atdate(endoftime(), itemloc_location_id, itemloc_itemsite_id)  as qty
+                
+                
+                
+            ");
+            if ($cn) {
+                $x->selectAdd("
+                    currtocurr(baseCurrId(), getcurrid('{$cn}'), stdcost(itemloc_itemsite_id), NOW()::date) as unitcost
+                ");
+            } else {
+                $x->selectAdd("
+                    stdcost(itemloc_itemsite_id) as unitcost
+                ");
+            }
+            
+            $x->limit(1);
+            if (!$x->find(true)) {
+                $xx = DB_DAtaObject::factory('itemloc');
+                if ($cn) {
+                    $xx->query("SELECT
+                        currtocurr(baseCurrId(), getcurrid('{$cn}'), stdcost({$imaps[$r->item]}), NOW()::date) as unitcost
+                    ");
+                } else {
+                    $xx->query("SELECT
+                        stdcost({$imaps[$r->item]}) as unitcost
+                    ");
+                }
+                $xx->fetch();
+                $x->unitcost = $xx->unitcost;
+
+                
+                
+            }
+            
+            
+            
+            $r->itemsite_id = $imaps[$r->item];
+            $r->qty = !empty($x->qty) ? $x->qty : 0;
+            $r->unitcost = !empty($x->unitcost) ? sprintf("%0.3f", $x->unitcost) : 0;
+            $ret[$r->id] = $r;
+            
+        }
+        $roo->jdata($ret);
+        
+    }
+    
+}
diff --git a/DataObjects/Itemlocdist.php b/DataObjects/Itemlocdist.php
new file mode 100644 (file)
index 0000000..3b8faf1
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for itemlocdist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemlocdist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemlocdist';         // table name
+    public $itemlocdist_id;                  // int4(4)  not_null default_nextval%28%28%22itemlocdist_itemlocdist_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $itemlocdist_itemlocdist_id;      // int4(4)  
+    public $itemlocdist_source_type;         // bpchar(-1)  
+    public $itemlocdist_source_id;           // int4(4)  
+    public $itemlocdist_qty;                 // numeric(-1)  
+    public $itemlocdist_series;              // int4(4)  
+    public $itemlocdist_invhist_id;          // int4(4)  
+    public $itemlocdist_itemsite_id;         // int4(4)  
+    public $itemlocdist_reqlotserial;        // bool(1)  default_false
+    public $itemlocdist_flush;               // bool(1)  default_false
+    public $itemlocdist_expiration;          // date(4)  
+    public $itemlocdist_distlotserial;       // bool(1)  
+    public $itemlocdist_warranty;            // date(4)  
+    public $itemlocdist_ls_id;               // int4(4)  
+    public $itemlocdist_order_type;          // text(-1)  
+    public $itemlocdist_order_id;            // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemlocpost.php b/DataObjects/Itemlocpost.php
new file mode 100644 (file)
index 0000000..0059937
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for itemlocpost
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemlocpost extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemlocpost';         // table name
+    public $itemlocpost_id;                  // int4(4)  not_null default_nextval%28itemlocpost_itemlocpost_id_seq%29 primary_key
+    public $itemlocpost_itemlocseries;       // int4(4)  
+    public $itemlocpost_glseq;               // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemsite.php b/DataObjects/Itemsite.php
new file mode 100644 (file)
index 0000000..c5cbef8
--- /dev/null
@@ -0,0 +1,743 @@
+<?php
+/**
+ * Table Definition for itemsite
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemsite extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemsite';            // table name
+    public $itemsite_id;                     // int4(4)  not_null default_nextval%28%28itemsite_itemsite_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $itemsite_item_id;                // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $itemsite_warehous_id;            // int4(4)  unique_key multiple_key unique_key multiple_key
+    public $itemsite_qtyonhand;              // numeric(-1)  not_null
+    public $itemsite_reorderlevel;           // numeric(-1)  not_null
+    public $itemsite_ordertoqty;             // numeric(-1)  not_null
+    public $itemsite_cyclecountfreq;         // int4(4)  not_null
+    public $itemsite_datelastcount;          // date(4)  
+    public $itemsite_datelastused;           // date(4)  
+    public $itemsite_loccntrl;               // bool(1)  not_null
+    public $itemsite_safetystock;            // numeric(-1)  not_null
+    public $itemsite_minordqty;              // numeric(-1)  not_null
+    public $itemsite_multordqty;             // numeric(-1)  not_null
+    public $itemsite_leadtime;               // int4(4)  not_null
+    public $itemsite_abcclass;               // bpchar(-1)  
+    public $itemsite_issuemethod;            // bpchar(-1)  
+    public $itemsite_controlmethod;          // bpchar(-1)  
+    public $itemsite_active;                 // bool(1)  not_null
+    public $itemsite_plancode_id;            // int4(4)  not_null
+    public $itemsite_costcat_id;             // int4(4)  not_null
+    public $itemsite_eventfence;             // int4(4)  not_null
+    public $itemsite_sold;                   // bool(1)  not_null
+    public $itemsite_stocked;                // bool(1)  not_null
+    public $itemsite_freeze;                 // bool(1)  not_null default_false
+    public $itemsite_location_id;            // int4(4)  not_null
+    public $itemsite_useparams;              // bool(1)  not_null
+    public $itemsite_useparamsmanual;        // bool(1)  not_null
+    public $itemsite_soldranking;            // int4(4)  default_1
+    public $itemsite_createpr;               // bool(1)  
+    public $itemsite_location;               // text(-1)  
+    public $itemsite_location_comments;      // text(-1)  
+    public $itemsite_notes;                  // text(-1)  
+    public $itemsite_perishable;             // bool(1)  not_null
+    public $itemsite_nnqoh;                  // numeric(-1)  not_null default_0
+    public $itemsite_autoabcclass;           // bool(1)  not_null
+    public $itemsite_ordergroup;             // int4(4)  not_null default_1
+    public $itemsite_disallowblankwip;       // bool(1)  not_null default_false
+    public $itemsite_maxordqty;              // numeric(-1)  not_null default_0.0
+    public $itemsite_mps_timefence;          // int4(4)  not_null default_0
+    public $itemsite_createwo;               // bool(1)  not_null default_false
+    public $itemsite_warrpurc;               // bool(1)  not_null default_false
+    public $itemsite_autoreg;                // bool(1)  default_false
+    public $itemsite_costmethod;             // bpchar(-1)  not_null
+    public $itemsite_value;                  // numeric(-1)  not_null
+    public $itemsite_ordergroup_first;       // bool(1)  not_null default_false
+    public $itemsite_supply_itemsite_id;     // int4(4)  
+    public $itemsite_planning_type;          // bpchar(-1)  not_null default_M
+    public $itemsite_wosupply;               // bool(1)  not_null default_false
+    public $itemsite_posupply;               // bool(1)  not_null default_false
+    public $itemsite_lsseq_id;               // int4(4)  
+    public $itemsite_cosdefault;             // bpchar(-1)  
+    public $itemsite_createsopr;             // bool(1)  default_false
+    public $itemsite_createsopo;             // bool(1)  default_false
+    public $itemsite_dropship;               // bool(1)  default_false
+
+    
+   /**
+    * Getter / Setter for $itemsite_costcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function costcat() {
+        return func_num_args() ? $this->link('itemsite_costcat_id', func_get_arg(0)) : $this->link('itemsite_costcat_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsite_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemsite_item_id', func_get_arg(0)) : $this->link('itemsite_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsite_plancode_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function plancode() {
+        return func_num_args() ? $this->link('itemsite_plancode_id', func_get_arg(0)) : $this->link('itemsite_plancode_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsite_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('itemsite_warehous_id', func_get_arg(0)) : $this->link('itemsite_warehous_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (!empty($q['_has_invdetail_location_id'])) {
+            $loc = (int) $q['_has_invdetail_location_id'];
+            $this->whereAdd("
+                itemsite_id IN (SELECT distinct(invhist_itemsite_id) FROM invdetailview WHERE invdetail_location_id = $loc)
+                            
+            ");
+        
+        
+        }
+        
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['query']['number'])) {
+            //DB_DataObject::debugLevel(1);
+            $v = $this->escape($q['query']['number']);
+            $this->whereAdd("join_itemsite_item_id_item_id.item_number ilike '$v%'");
+            
+            
+        }
+        
+        if (!empty($q['query']['number_or_name'])) {
+            //DB_DataObject::debugLevel(1);
+            $v = $this->escape($q['query']['number_or_name']);
+            $this->whereAdd("
+                    join_itemsite_item_id_item_id.item_number ilike '$v%'
+                    OR
+                    join_itemsite_item_id_item_id.item_descrip1 ilike '%$v%'
+                    ");
+            
+            
+        }
+        
+        
+        if (!empty($q['query']['cohead_id'])) {
+            $coid = (int) $q['query']['cohead_id'];
+            $this->selectAdd("
+                ROUND(COALESCE(qtyavailable(itemsite_id, (SELECT cohead_targetdate FROM cohead WHERE cohead_id  =$coid LIMIT 1)), 0 ),0) as avail_qty 
+                
+            
+            ");
+            $this->whereAdd('join_itemsite_item_id_item_id.item_sold = true');
+            
+            
+            
+        } else {
+            // no reference
+            $this->selectAdd("
+                'n/a' as avail_qty
+                 
+                
+            ");
+            
+        }
+        
+        if (!empty($q['query']['at_location'])) {
+             $loc = (int)$q['query']['at_location'];
+             $this->selectAdd("
+                ROUND(COALESCE(
+                        (SELECT itemloc_qty FROM
+                                itemloc
+                            WHERE
+                                itemloc_itemsite_id  = itemsite_id
+                                AND
+                                itemloc_location_id = $loc
+                        ),0)) as avail_at_location
+            ");
+        }
+        
+        if(!empty($q['_atdate']) && !empty($q['_location'])){
+            $loc = (int)$q['_location'];
+            $this->selectAdd("
+                (SELECT ROUND(COALESCE(invdetail_atdate('{$q['_atdate']}'::date, $loc, itemsite_id), 0),0)) AS balance_atdate
+            ");
+            
+        }
+        
+        if (!empty($q['_with_stock_and_value'])) {
+            // work out the total qty of stock at the location at that time..
+            $dt = date('Y-m-d', strtotime($q['_as_of']));
+            $loc = (int)$q['location_id'];
+            
+            $location = DB_DataObject::factory('Location');
+            $location->get($loc);
+            $cust = $location->customer();
+            $pl = $cust ? $cust->priceList() : false;
+            if ($pl) {
+                $curr =  $pl->curr();
+                
+                $this->selectAdd("
+                    '{$this->escape($curr->curr_symbol)}' as curr_symbol,
+                    (SELECT ipsitem_price FROM ipsitem where ipsitem_item_id = itemsite_item_id AND ipsitem_ipshead_id={$pl->pid()}) as customer_price_each,
+                    
+                    ROUND(
+                        (SELECT ipsitem_price FROM ipsitem where ipsitem_item_id = itemsite_item_id AND ipsitem_ipshead_id={$pl->pid()})
+                        *
+                        invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)
+                    ,2 ) as customer_total_value
+                    
+                    
+                ");
+             } else {
+                $this->selectAdd("
+                    'NO PRICELIST' as curr_symbol,
+                    0 as customer_price_each,
+                    0 as customer_total_value
+                    
+                ");
+                
+                
+            }
+            
+            $match = '<> 0.0';
+            if (isset($q['_viewtype'] )) {
+                $match = '> 0.0';
+                
+                if ($q['_viewtype'] < 1)  {
+                    $match = '<= 0.0';
+                }
+                
+                
+            }
+            $ormatch = '';
+            if (!empty($q['_with_ns_all_stock'])) {
+                /*
+                 *$ormatch  = "
+                    OR
+                    (SELECT
+                                sum(qty) as sum_qty
+                            FROM
+                                netsuite_stock
+                            WHERE
+                                location_id = $loc
+                            AND
+                                trans_date < ('$dt'::date + INTERVAL '1 DAY')::date
+                            AND
+                                item_id = itemsite_item_id
+                            
+                    ) != 0.0";
+                    */
+            }
+            if(empty($q['_with_qty_detail'])){
+                $this->whereAdd("itemsite_id IN (
+                    SELECT
+                            distinct(invhist_itemsite_id)
+                        FROM
+                            invdetailview
+                        WHERE
+                            invdetail_location_id = $loc
+
+                    ) 
+                "); 
+                if ($match == '> 0.0') {
+                    $this->whereAdd("   invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)  $match
+                                    OR
+                                    (
+                                        invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id) = 0.0
+                                        AND
+                                        ABS(invdetail_cost_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)) > 0.01
+                                    )
+
+                                    ");
+                } else {
+                    $this->whereAdd("   invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)  $match ");
+                }
+            }
+           
+             $this->selectAdd( "
+                invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id) as itemsite_qty, 
+                invdetail_cost_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)  as itemsite_value,
+                ROUND(stdcost(itemsite_item_id),2) as standard_cost,
+                
+                ROUND(invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id)  * stdcost(itemsite_item_id),2) as standard_cost_total,
+                
+                (SELECT max(invhist_transdate)::date FROM invdetailview WHERE invhist_itemsite_id = itemsite_id and invhist_transdate <= '$dt'::date ) as last_transaction,
+                0 AS netsuite_qty
+            ");
+             
+             if(!empty($q['_with_brand'])){
+                $this->selectAdd("
+                   charass_getvalue('I', itemsite_item_id, 'BRAND') as item_brand_name
+               ");
+             }
+             
+             if(!empty($q['_with_qty_detail'])){
+                 $invdetail = DB_DataObject::factory('invdetail');
+                 $invdetail->autoJoin();
+                 $invdetail->autoJoinItem();
+                 $invdetail->autoJoinLocation();
+                 $invdetail->whereAdd("
+                        invhist_transdate::date <= '$dt'
+                        AND
+                        invhist_posted
+                        AND
+                        invdetail_location_id = {$loc}
+                    ");
+                 $invdetail->selectAdd();
+                 $invdetail->selectAdd('DISTINCT(invhist_itemsite_id)');
+                 $itemsite_ids = $invdetail->fetchAll('invhist_itemsite_id');
+                 
+                 $this->whereAddIn('itemsite_id', $itemsite_ids, 'int');
+                 
+                 $this->selectAdd("
+                     invdetail_sold_atdate('$dt'::date, $loc, itemsite_id) as itemsite_sold_atdate,
+                     invdetail_atdate('$dt'::date, $loc, itemsite_id) as itemsite_qty_before, 
+                     invdetail_sold_after( '$dt'::date, $loc, itemsite_id) as itemsite_sold_after
+                 ");
+             }
+             
+             if(!empty($q['_with_last_purchase_price'])){
+                /* THIS IS TOO SLOW.? */
+                
+                // AND -- ignore location
+                //       pohead_location_id = $loc
+                $this->selectAdd("
+                    (SELECT 
+                       currtobase(pohead_curr_id, poitem_unitprice,  pohead_orderdate)
+                    FROM 
+                       poitem
+                    LEFT JOIN
+                        pohead ON pohead_id = poitem_pohead_id
+                    WHERE 
+                       poitem_itemsite_id = itemsite_id
+                       AND
+                       (poitem_qty_received - poitem_qty_returned) > 0.0
+                    ORDER BY
+                        poitem_duedate DESC,
+                        poitem_linenumber DESC
+                    LIMIT 1) AS item_last_purchase_price
+               ");
+              
+             }
+               
+            
+            $this->orderBy("
+               
+                    CASE WHEN invdetail_atdate('$dt'::date + INTERVAL '1 DAY', $loc, itemsite_id) !=  0 THEN 1
+                    ELSE 0 END
+                DESC       
+                           
+            ");
+           
+            //$this->having( "$loc_query > 0 " );
+           
+             
+            
+        }
+           
+        if (!empty($q['customer_id'])) {
+            
+            $ch = false;
+            $cm = false;
+            if (isset($q['cohead_id'])) {
+                $ch = DB_DataObject::Factory('cohead');
+                $ch->get($q['cohead_id']);
+                
+            }
+            if(isset($q['query']['cmhead_id'])){
+                $cm = DB_DataObject::factory('cmhead');
+                $cm->get($q['query']['cmhead_id']);
+            }
+            
+             
+            $cid = (int)$q['customer_id'];
+            $cust = DB_DataObject::Factory('custinfo');
+            $cust->get($cid);
+            
+            $curr_id = $cust->cust_curr_id;
+            if ($ch) {
+                $curr_id = $ch->cohead_curr_id;
+            }
+            if($cm){
+                $curr_id = $cm->cmhead_curr_id;
+            }
+            // seems to depend on ipass_shipto_id
+            //$cur = DB_DataObject::Factory('curr_symbol');
+            //$cur->get('curr_abbr', 'USD');
+            //  itemprice(itemid, custid, shiptoid, qty,   currid,  effective
+            $this->selectAdd("
+                    round(itemprice(itemsite_item_id, $cid, -1, 1,   {$curr_id},  NOW()::date),3)
+                        as item_price,
+                    round(itemprice(itemsite_item_id, $cid, -1, 1,   {$curr_id},  NOW()::date),3)
+                        as item_listprice,
+                        
+                    itemprice_wrp(itemsite_id, {$curr_id})
+                        as item_wrpprice
+                    
+                    
+            ");
+             
+              
+            
+            //echo '<PRE>';print_r($ret);exit;
+            
+            
+        }
+    }
+    /*
+    function toRooArray($q)
+    {
+        
+        $ret = $this->toArray();
+        
+        if (!empty($q['customer_id'])) {
+            
+            $ch = false;
+            $cm = false;
+            if (isset($q['cohead_id'])) {
+                $ch = DB_DataObject::Factory('cohead');
+                $ch->get($q['cohead_id']);
+                
+            }
+            if(isset($q['query']['cmhead_id'])){
+                $cm = DB_DataObject::factory('cmhead');
+                $cm->get($q['query']['cmhead_id']);
+            }
+            
+            $is = DB_DataObject::Factory('itemsite');
+            $is->whereAdd("itemsite_id = {$this->itemsite_id}"); //<< will that work??
+            $is->autoJoin();
+            $is->selectAdd();
+            $is->limit(1);
+            $cid = (int)$q['customer_id'];
+            $cust = DB_DataObject::Factory('custinfo');
+            $cust->get($cid);
+            
+            $curr_id = $cust->cust_curr_id;
+            if ($ch) {
+                $curr_id = $ch->cohead_curr_id;
+            }
+            if($cm){
+                $curr_id = $cm->cmhead_curr_id;
+            }
+            // seems to depend on ipass_shipto_id
+            //$cur = DB_DataObject::Factory('curr_symbol');
+            //$cur->get('curr_abbr', 'USD');
+            //  itemprice(itemid, custid, shiptoid, qty,   currid,  effective
+            $is->selectAdd("
+                    round(itemprice(itemsite_item_id, $cid, -1, 1,   {$curr_id},  NOW()::date),3)
+                        as item_price,
+                    round(itemprice(itemsite_item_id, $cid, -1, 1,   {$curr_id},  NOW()::date),3)
+                        as item_listprice,
+                        
+                    itemprice_wrp(itemsite_id, {$curr_id})
+                        as item_wrpprice
+                    
+                    
+            ");
+             
+              
+            $is->find(true);
+            $add = $is->toArray('%s', true);
+            $ret = array_merge($ret, $add);
+            //echo '<PRE>';print_r($ret);exit;
+            
+            
+        }
+        return $ret;
+        
+        
+         
+    }
+    */
+    function cogsprice($qty)
+    {
+        
+        // technically should be the fifo cost..
+        
+        
+        $q = DB_DAtaObject::factory('itemcost');
+        $q->query("select stdcost({$this->item()->pid()}) as unitprice");
+        $q->fetch();
+        
+         
+        return empty($q->unitprice) ? false : $q->unitprice;
+        
+    }
+    
+    /**
+     * look up how much stock is available at locations listed..
+     *[0] => stdClass Object
+        (
+            [item] => UI1002
+            [loc] => Kerry MY
+        )
+
+     */
+    
+    function availQty($q)
+    {
+        
+        
+        
+        
+    }
+    
+    function defaults($item_type = 'P')
+    {
+        static $locid = false;
+        if (!$locid) {
+        
+            $loc = DB_DataObject::factory('location');
+            $loc = $loc->defaultConfigLocation();
+            $locid = $loc->pid(); 
+        }
+       // if SG -> use 'Kerry SG'
+        
+        $ret =  array( 
+            // 'itemsite_id'        =>     2723,
+             //'itemsite_item_id'        =>     $itemid,
+             'itemsite_warehous_id'        =>    $this->sqlValue("
+                                            (SELECT warehous_id FROM whsinfo ORDER by warehous_id LIMIT 1)
+                                        "),
+             'itemsite_qtyonhand'        =>     0,
+             
+             'itemsite_reorderlevel'        =>    100,
+             'itemsite_ordertoqty'        =>     0,
+             'itemsite_cyclecountfreq'        =>     0,
+             'itemsite_datelastcount'        =>     $this->sqlValue('NULL'),
+             'itemsite_datelastused'        =>     '1970-01-01',
+             'itemsite_loccntrl'        =>    $item_type == 'P' ?  true : false,
+             'itemsite_safetystock'        =>     0,
+             'itemsite_minordqty'        =>     0,
+             'itemsite_multordqty'        =>     0,
+             'itemsite_leadtime'        =>     30,
+             'itemsite_abcclass'        =>     'A',
+             'itemsite_issuemethod'        =>     $this->sqlValue('NULL'),
+             'itemsite_controlmethod'        =>     'R',
+             'itemsite_active'        =>     true,
+             'itemsite_plancode_id'        =>     $this->sqlValue(
+                        "(SELECT plancode_id FROM plancode WHERE plancode_code = 'REGULAR' LIMIT 1)"),
+             
+             'itemsite_costcat_id'=> $this->sqlValue("(SELECT costcat_id FROM costcat WHERE costcat_code = 'CATEGORY1' LIMIT 1)"),
+             
+             'itemsite_eventfence'        =>     10,
+             'itemsite_sold'        =>     true,
+             'itemsite_stocked'        =>      $item_type == 'P' ?  true : false, 
+             'itemsite_freeze'        =>     false,
+             'itemsite_location_id'=> $locid,
+
+             'itemsite_useparams'        =>     true,
+             'itemsite_useparamsmanual'        =>     false,
+             'itemsite_soldranking'        =>     1,
+             'itemsite_createpr'        =>     false,
+             'itemsite_location'        =>     $this->sqlValue('NULL'),
+             'itemsite_location_comments'        =>     $this->sqlValue('NULL'),
+             'itemsite_notes'        =>     $this->sqlValue('NULL'),
+             'itemsite_perishable'        =>     false,
+             'itemsite_nnqoh'        =>     0,
+             'itemsite_autoabcclass'        =>     false,
+             'itemsite_ordergroup'        =>     1,
+             'itemsite_disallowblankwip'        =>     false,
+             'itemsite_maxordqty'        =>     0,
+             'itemsite_mps_timefence'        =>     0,
+             
+             'itemsite_createwo'        =>     false,
+             'itemsite_warrpurc'        =>     false,
+             'itemsite_autoreg'        =>     false,
+             'itemsite_costmethod'        =>     'S',
+             'itemsite_value'        =>     '',
+             'itemsite_ordergroup_first'        =>     false,
+             'itemsite_supply_itemsite_id'        =>   $this->sqlValue('NULL'),
+             'itemsite_planning_type'        =>     'N',
+             'itemsite_wosupply'        =>     false,
+             'itemsite_posupply'        =>     true,
+             'itemsite_lsseq_id'        =>     $this->sqlValue('NULL'),
+             'itemsite_cosdefault'        =>     $this->sqlValue('NULL'),
+             'itemsite_createsopr'        =>     false,
+             'itemsite_createsopo'        =>     false,
+             'itemsite_dropship'        =>     false,
+            );
+    
+        //HTML_FlexyFramework::get()->page->jerr(var_export($ret));
+         return $ret;
+        
+        
+    
+    }
+    
+    function fixItemsite($item = false)
+    {
+        $item_type = 'P';
+        if (!empty($item) && $item->item_type == 'R') {
+            $item_type = 'R';
+            
+            
+        }
+        $defaults = $this->defaults($item_type);
+        $zemptyfix = array(
+            'itemsite_reorderlevel'
+        );
+            
+        
+        
+        $fix = array(
+            'itemsite_loccntrl', 'itemsite_active',
+            'itemsite_controlmethod', 
+             'itemsite_sold', 'itemsite_stocked',
+             'itemsite_location_id',
+             'itemsite_useparams',
+             'itemsite_costmethod',
+             'itemsite_planning_type',
+             'itemsite_posupply'
+             
+        );
+        $up = false;
+        $old = clone($this);
+        foreach($fix as $k) {
+            if ($this->$k != $defaults[$k]) {
+                $up = true;
+                $this->$k = $defaults[$k];
+            }
+        }
+        
+        foreach($zemptyfix as $k) {
+            if (empty($this->$k) || $this->$k == 0.0) {
+                $up = true;
+                $this->$k = $defaults[$k];
+            }
+        }
+        
+        //print_R($this->toArray());
+     
+        
+        
+        if ($up) {
+            $this->update($old);
+        }
+        
+    }
+     
+    function createOrFetchFromItem($roo, $item)
+    {
+        
+        $is = DB_DataObject::Factory('itemsite');
+        if ($is->get('itemsite_item_id', $item->pid())) {
+            if (!$is->itemsite_active) {
+                $ii = clone($is);
+                
+                $ii->itemsite_active = true;
+                $ii->update($is);
+            }
+             
+            return $is;
+        }
+        
+        
+        $is = DB_DataObject::Factory('itemsite');
+        foreach($this->defaults($item->item_type) as $k=>$v) {
+            $is->$k = $v;
+        }
+        $is->itemsite_item_id = $item->pid();
+        $is->insert();
+        $is = DB_DataObject::Factory('itemsite');
+
+        if (!$is->get('itemsite_item_id', $item->pid())) {
+            $roo->jerr("item site creation failed");
+        }
+        return $is;
+    }
+        
+    function syncFromHK($roo,  $new_item, $data)
+    {
+        if (empty($data->item_itemsite_id)) {
+            return;
+        }
+        $is = DB_DataObject::Factory('itemsite');
+        if (!$is->get('itemsite_item_id', $new_item->pid())) {
+            
+            $loc = DB_DataObject::factory('location');
+            $loc = $loc->defaultConfigLocation();
+            
+            //print_R($loc);exit;
+            $is = DB_DataObject::Factory('itemsite');
+            $is->setFrom($is->defaults());
+            $is->itemsite_item_id = $new_item->pid();
+            
+            foreach(array(
+            
+                 'itemsite_loccntrl',
+                 'itemsite_safetystock',
+                 'itemsite_multordqty',
+                 'itemsite_leadtime',
+                 'itemsite_abcclass',
+                 'itemsite_controlmethod',
+                 'itemsite_active',
+                 'itemsite_eventfence',
+                 'itemsite_sold',
+                 'itemsite_stocked',
+                'itemsite_soldranking',
+                'itemsite_ordergroup',
+                'itemsite_costmethod',
+                'itemsite_planning_type',
+                'itemsite_posupply',
+                ) as $k) {
+                $is->$k = $data->{'item_itemsite_id_' . $k};
+            }
+            
+            $cc = DB_DataObject::factory('plancode');
+            if (!$cc->get('plancode_code', $data->plancode_code)) {
+                $cc = DB_DataObject::factory('plancode');
+                $cc->setFrom($data);
+                $cc->insert();
+                
+                
+                
+                
+            }
+            $is->itemsite_plancode_id = $cc->pid();
+            
+            $cc = DB_DataObject::factory('costcat');
+            if (!$cc->get('costcat_code', $data->costcat_code)) {
+                $roo->jerr("no costcat_code name {$data->costcat_code}");
+            }
+            $is->itemsite_costcat_id = $cc->pid();
+            $is->itemsite_location_id = $loc->pid();
+            $is->insert();
+        }
+    }
+    
+    function checkLocationStock($location)
+    {
+        $itemsite = DB_DataObject::factory('itemsite');
+        $itemsite->query("SELECT invdetail_balance_byitem({$this->pid()}, {$location}) AS stock_balance");
+        $itemsite->fetch();
+        
+        return $itemsite->stock_balance;
+        
+    }
+    
+}
diff --git a/DataObjects/Itemsrc.php b/DataObjects/Itemsrc.php
new file mode 100644 (file)
index 0000000..5af486b
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for itemsrc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemsrc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemsrc';             // table name
+    public $itemsrc_id;                      // int4(4)  not_null default_nextval%28%28%22itemsrc_itemsrc_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $itemsrc_item_id;                 // int4(4)  not_null unique_key multiple_key
+    public $itemsrc_vend_id;                 // int4(4)  not_null unique_key multiple_key
+    public $itemsrc_vend_item_number;        // text(-1)  unique_key multiple_key
+    public $itemsrc_vend_item_descrip;       // text(-1)  
+    public $itemsrc_comments;                // text(-1)  
+    public $itemsrc_vend_uom;                // text(-1)  not_null
+    public $itemsrc_invvendoruomratio;       // numeric(-1)  not_null
+    public $itemsrc_minordqty;               // numeric(-1)  not_null
+    public $itemsrc_multordqty;              // numeric(-1)  not_null
+    public $itemsrc_leadtime;                // int4(4)  not_null
+    public $itemsrc_ranking;                 // int4(4)  not_null
+    public $itemsrc_active;                  // bool(1)  not_null
+    public $itemsrc_manuf_name;              // text(-1)  not_null default_ unique_key multiple_key
+    public $itemsrc_manuf_item_number;       // text(-1)  not_null default_ unique_key multiple_key
+    public $itemsrc_manuf_item_descrip;      // text(-1)  
+    public $itemsrc_default;                 // bool(1)  
+    public $itemsrc_upccode;                 // text(-1)  
+    
+    
+    
+    function beforeInsert($req,$roo)
+    {
+        if(isset($req['_update_by_item'])){
+            $is = DB_DataObject::factory('itemsrc');
+            $is->itemsrc_item_id = $req['item_id'];
+            $is->find();
+            while ($is->fetch()){
+                $ii = clone ($is);
+                $is->itemsrc_active = $req['itemsrc_active'];
+                $is->update($ii);
+            }
+            $roo->jok('DONE');
+        }
+    }
+    
+   /**
+    * Getter / Setter for $itemsrc_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemsrc_item_id', func_get_arg(0)) : $this->link('itemsrc_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsrc_vend_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vend() {
+        return func_num_args() ? $this->link('itemsrc_vend_id', func_get_arg(0)) : $this->link('itemsrc_vend_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+}
diff --git a/DataObjects/Itemsrcp.php b/DataObjects/Itemsrcp.php
new file mode 100644 (file)
index 0000000..18544bb
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Table Definition for itemsrcp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemsrcp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemsrcp';            // table name
+    public $itemsrcp_id;                     // int4(4)  not_null default_nextval%28%28itemsrcp_itemsrcp_id_seq%29%3A%3Aregclass%29 primary_key
+    public $itemsrcp_itemsrc_id;             // int4(4)  not_null unique_key multiple_key
+    public $itemsrcp_qtybreak;               // numeric(-1)  not_null unique_key multiple_key
+    public $itemsrcp_price;                  // numeric(-1)  not_null
+    public $itemsrcp_updated;                // date(4)  
+    public $itemsrcp_curr_id;                // int4(4)  not_null default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $itemsrcp_itemsrc_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsrc() {
+        return func_num_args() ? $this->link('itemsrcp_itemsrc_id', func_get_arg(0)) : $this->link('itemsrcp_itemsrc_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsrcp_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('itemsrcp_curr_id', func_get_arg(0)) : $this->link('itemsrcp_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemsub.php b/DataObjects/Itemsub.php
new file mode 100644 (file)
index 0000000..052b0eb
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for itemsub
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemsub extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemsub';             // table name
+    public $itemsub_id;                      // int4(4)  not_null default_nextval%28%28itemsub_itemsub_id_seq%29%3A%3Aregclass%29 primary_key
+    public $itemsub_parent_item_id;          // int4(4)  not_null unique_key multiple_key
+    public $itemsub_sub_item_id;             // int4(4)  not_null unique_key multiple_key
+    public $itemsub_uomratio;                // numeric(-1)  not_null
+    public $itemsub_rank;                    // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $itemsub_parent_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent_item() {
+        return func_num_args() ? $this->link('itemsub_parent_item_id', func_get_arg(0)) : $this->link('itemsub_parent_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemsub_sub_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function sub_item() {
+        return func_num_args() ? $this->link('itemsub_sub_item_id', func_get_arg(0)) : $this->link('itemsub_sub_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemtax.php b/DataObjects/Itemtax.php
new file mode 100644 (file)
index 0000000..3f07860
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Table Definition for itemtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemtax';             // table name
+    public $itemtax_id;                      // int4(4)  not_null default_nextval%28itemtax_itemtax_id_seq%29 primary_key
+    public $itemtax_item_id;                 // int4(4)  not_null
+    public $itemtax_taxtype_id;              // int4(4)  not_null
+    public $itemtax_taxzone_id;              // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $itemtax_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemtax_item_id', func_get_arg(0)) : $this->link('itemtax_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemtax_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('itemtax_taxtype_id', func_get_arg(0)) : $this->link('itemtax_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $itemtax_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('itemtax_taxzone_id', func_get_arg(0)) : $this->link('itemtax_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemtrans.php b/DataObjects/Itemtrans.php
new file mode 100644 (file)
index 0000000..5913139
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Table Definition for itemtrans
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemtrans extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemtrans';           // table name
+    public $itemtrans_id;                    // int4(4)  not_null default_nextval%28itemtrans_itemtrans_id_seq%29 primary_key
+    public $itemtrans_source_item_id;        // int4(4)  unique_key multiple_key
+    public $itemtrans_target_item_id;        // int4(4)  unique_key multiple_key
+
+    
+   /**
+    * Getter / Setter for $itemtrans_source_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function source_item() {
+        return func_num_args() ? $this->link('itemtrans_source_item_id', func_get_arg(0)) : $this->link('itemtrans_source_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemtrans_target_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function target_item() {
+        return func_num_args() ? $this->link('itemtrans_target_item_id', func_get_arg(0)) : $this->link('itemtrans_target_item_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemuom.php b/DataObjects/Itemuom.php
new file mode 100644 (file)
index 0000000..3b632cd
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Table Definition for itemuom
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemuom extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemuom';             // table name
+    public $itemuom_id;                      // int4(4)  not_null default_nextval%28itemuom_itemuom_id_seq%29 primary_key
+    public $itemuom_itemuomconv_id;          // int4(4)  not_null
+    public $itemuom_uomtype_id;              // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $itemuom_itemuomconv_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemuomconv() {
+        return func_num_args() ? $this->link('itemuom_itemuomconv_id', func_get_arg(0)) : $this->link('itemuom_itemuomconv_id');
+    }
+
+   /**
+    * Getter / Setter for $itemuom_uomtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function uomtype() {
+        return func_num_args() ? $this->link('itemuom_uomtype_id', func_get_arg(0)) : $this->link('itemuom_uomtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Itemuomconv.php b/DataObjects/Itemuomconv.php
new file mode 100644 (file)
index 0000000..44069a7
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Table Definition for itemuomconv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Itemuomconv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'itemuomconv';         // table name
+    public $itemuomconv_id;                  // int4(4)  not_null default_nextval%28itemuomconv_itemuomconv_id_seq%29 primary_key
+    public $itemuomconv_item_id;             // int4(4)  not_null
+    public $itemuomconv_from_uom_id;         // int4(4)  not_null
+    public $itemuomconv_from_value;          // numeric(-1)  not_null
+    public $itemuomconv_to_uom_id;           // int4(4)  not_null
+    public $itemuomconv_to_value;            // numeric(-1)  not_null
+    public $itemuomconv_fractional;          // bool(1)  not_null default_false
+
+    
+   /**
+    * Getter / Setter for $itemuomconv_from_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function from_uom() {
+        return func_num_args() ? $this->link('itemuomconv_from_uom_id', func_get_arg(0)) : $this->link('itemuomconv_from_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $itemuomconv_item_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function item() {
+        return func_num_args() ? $this->link('itemuomconv_item_id', func_get_arg(0)) : $this->link('itemuomconv_item_id');
+    }
+
+   /**
+    * Getter / Setter for $itemuomconv_to_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function to_uom() {
+        return func_num_args() ? $this->link('itemuomconv_to_uom_id', func_get_arg(0)) : $this->link('itemuomconv_to_uom_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Jrnluse.php b/DataObjects/Jrnluse.php
new file mode 100644 (file)
index 0000000..ea4d243
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for jrnluse
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Jrnluse extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'jrnluse';             // table name
+    public $jrnluse_id;                      // int4(4)  not_null default_nextval%28%28%22jrnluse_jrnluse_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $jrnluse_date;                    // timestamp(8)  
+    public $jrnluse_number;                  // int4(4)  
+    public $jrnluse_use;                     // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Labelform.php b/DataObjects/Labelform.php
new file mode 100644 (file)
index 0000000..82a6362
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for labelform
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Labelform extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'labelform';           // table name
+    public $labelform_id;                    // int4(4)  not_null default_nextval%28%28%22labelform_labelform_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $labelform_name;                  // text(-1)  
+    public $labelform_report_id;             // int4(4)  
+    public $labelform_perpage;               // int4(4)  
+    public $labelform_report_name;           // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Lang.php b/DataObjects/Lang.php
new file mode 100644 (file)
index 0000000..5d5eed6
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for lang
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Lang extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'lang';                // table name
+    public $lang_id;                         // int4(4)  not_null default_nextval%28lang_lang_id_seq%29 primary_key
+    public $lang_qt_number;                  // int4(4)  
+    public $lang_abbr3;                      // text(-1)  
+    public $lang_abbr2;                      // text(-1)  
+    public $lang_name;                       // text(-1)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Locale.php b/DataObjects/Locale.php
new file mode 100644 (file)
index 0000000..3f1e378
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Table Definition for locale
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Locale extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'locale';              // table name
+    public $locale_id;                       // int4(4)  not_null default_nextval%28%28locale_locale_id_seq%29%3A%3Aregclass%29 primary_key
+    public $locale_code;                     // text(-1)  
+    public $locale_descrip;                  // text(-1)  
+    public $locale_lang_file;                // text(-1)  
+    public $locale_dateformat;               // text(-1)  
+    public $locale_currformat;               // text(-1)  
+    public $locale_qtyformat;                // text(-1)  
+    public $locale_comments;                 // text(-1)  
+    public $locale_qtyperformat;             // text(-1)  
+    public $locale_salespriceformat;         // text(-1)  
+    public $locale_extpriceformat;           // text(-1)  
+    public $locale_timeformat;               // text(-1)  
+    public $locale_timestampformat;          // text(-1)  
+    public $local_costformat;                // text(-1)  
+    public $locale_costformat;               // text(-1)  
+    public $locale_purchpriceformat;         // text(-1)  
+    public $locale_uomratioformat;           // text(-1)  
+    public $locale_intervalformat;           // text(-1)  
+    public $locale_lang_id;                  // int4(4)  
+    public $locale_country_id;               // int4(4)  
+    public $locale_error_color;              // text(-1)  
+    public $locale_warning_color;            // text(-1)  
+    public $locale_emphasis_color;           // text(-1)  
+    public $locale_altemphasis_color;        // text(-1)  
+    public $locale_expired_color;            // text(-1)  
+    public $locale_future_color;             // text(-1)  
+    public $locale_curr_scale;               // int4(4)  
+    public $locale_salesprice_scale;         // int4(4)  
+    public $locale_purchprice_scale;         // int4(4)  
+    public $locale_extprice_scale;           // int4(4)  
+    public $locale_cost_scale;               // int4(4)  
+    public $locale_qty_scale;                // int4(4)  
+    public $locale_qtyper_scale;             // int4(4)  
+    public $locale_uomratio_scale;           // int4(4)  
+    public $locale_percent_scale;            // int4(4)  default_2
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Location.php b/DataObjects/Location.php
new file mode 100644 (file)
index 0000000..ac5dfa4
--- /dev/null
@@ -0,0 +1,405 @@
+<?php
+/**
+ * Table Definition for location
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Location extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'location';            // table name
+    public $location_id;                     // int4(4)  not_null default_nextval%28%28location_location_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $location_warehous_id;            // int4(4)  not_null
+    public $location_name;                   // text(-1)  not_null
+    public $location_descrip;                // text(-1)  
+    public $location_restrict;               // bool(1)  
+    public $location_netable;                // bool(1)  
+    public $location_whsezone_id;            // int4(4)  
+    public $location_aisle;                  // text(-1)  
+    public $location_rack;                   // text(-1)  
+    public $location_bin;                    // text(-1)  
+    public $location_cust_id;                    // text(-1)  
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function customer()
+    {
+        $c = DB_DataObject::Factory('custinfo');
+        if (!$this->location_cust_id || !$c->get($this->location_cust_id)) {
+            return false;
+        }
+        return $c;
+        
+    }
+    
+    
+    function applyFilters($q, $au)
+    {
+        //DB_DataObject::debugLevel(1);
+        if (!empty($q['query']['location_name'])) {
+           
+            $v = $this->escape($q['query']['location_name']);
+            $this->whereAdd("location_name ilike '$v%'");
+            
+        }
+        if(isset($q['_with_internalcompany'])){
+            $this->selectAdd("(SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY')) as cust_to_internalcompany");
+        }
+        
+        if(!empty($q['_viewType'])){
+            $db = substr($this->database(),-2);
+            
+            switch($q['_viewType']) {
+                case 'local':
+                    $this->whereAdd("
+                        (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY'))  IN ('', '{$db}')
+                        AND
+                        location_restrict = false
+                    ");
+                    break;
+                
+                case 'remote':
+                    $this->whereAdd("
+                        (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY'))  NOT IN ('', '{$db}')
+                        AND
+                        location_restrict = false
+                    ");
+                    break;
+                    
+                case 'disabled':
+                    $this->location_restrict = true;
+                    break;
+                    
+                    
+            }
+            
+        }
+        
+        
+        
+        if (isset($q['query']['for_cohead_id'])) {
+            $cid = (int)$q['query']['for_cohead_id'];
+            $this->whereAdd("
+                location_id IN (SELECT coitem_location_src FROM coitem where coitem_cohead_id = $cid )
+                            ");
+        
+        }
+        if (!empty($q['_notinternalcompany'])) {
+            $this->whereAdd(" LENGTH(charass_getvalue('C', location_cust_id,'INTERNALCOMPANY')) < 1 ");
+        }
+         if (!empty($q['_has_invdetail'])) {
+            $this->whereAdd("
+                location_id IN (SELECT distinct(invdetail_location_id) FROM invdetail)
+            ");
+        
+        }
+        if (!empty($q['_has_invdetail_item'])) {
+            $item = DB_DataObject::Factory('item');
+            $item->get('item_number', $q['_has_invdetail_item']);
+            $itemsite = $item->itemsite();
+               $this->whereAdd("
+                location_id IN (SELECT distinct(invdetail_location_id) FROM invdetailview where invhist_itemsite_id =  {$itemsite->pid()} )
+            ");                            
+        }
+        if (isset($q['_stock_for_item_id'])) {
+            $item = DB_DataObject::factory('item');
+            $item->get($q['_stock_for_item_id']);
+            $itemsite = $item->itemsite();
+            if (!empty($itemsite->itemsite_id)) {
+            
+                $this->selectAdd(" invdetail_atdate(NOW()::date, location_id, {$itemsite->pid()}) as itemloc_realqty");
+                $this->whereAdd(" 0 != invdetail_atdate(NOW()::date, location_id, {$itemsite->pid()})  ");
+            } else {
+                $this->selectAdd(" 0 as itemloc_realqty");
+            }
+            
+        }
+        
+        
+        
+        if (isset($q['query']['item_itemsite_id'])) {
+            if (!isset($q['query']['cohead_id'])) {
+                $roo->jerr("no order specified");
+            }
+            // we are searching for a product availability.
+            //DB_DataObject::debugLevel(1);
+            $itemsite_id = (int) $q['query']['item_itemsite_id'];
+            $order_id = (int) $q['query']['cohead_id'];
+            //$this->location_netable = 1;
+            
+            
+            // why look in itemoc? - that get's created on the fly when
+            // adding removing data.
+            //$il = $this->factory('itemloc');
+            //$il->itemloc_itemsite_id = $itemsite_id;
+            //$locs = $il->fetchAll('itemloc_location_id');
+            //$this->whereAddIn('location_id', $locs, 'int');
+            
+            
+            // available..
+            
+             //qtylocation(pLocationId, NULL, NULL, NULL, pItemsiteId, pOrderType, pOrderId, pItemlocdistId)
+                 // itemlocdist.. - this might have to be worked out if
+                // items have already been distributed for this order line
+            //
+            $this->selectAdd("
+                round(qtylocation(location_id, NULL, NULL, NULL, {$itemsite_id}, 'SO', {$order_id}, 0),0) AS qty_avail
+            ");
+            
+            // grabbing qty at a location at a specific date..
+            // invhist < contains all the in/out dates for inventory..
+            // itemlocdist << contains the distribution into specific locations.
+            /// .. joins on itemlocdist_invhist_id ...
+            
+            
+            // select sum(itemlocdist_qty) from itemlocdist
+            //        LEFT JOIN invhist ON itemlocdist_invhist_id = invhist
+            //        where itemlocdist_itemsite_id = 2068 AND
+            //        invhist_transdate < ... date;
+            
+            // that will not account for future reservations...
+            //  --which have already been deducted from itemlocdist....
+            
+            
+        }
+        if (!empty($q['_with_stock_and_value'])) {
+            // work out the total qty of stock at the location at that time..
+            $dt = date('Y-m-d', strtotime($q['_as_of']));
+            
+            
+            
+            if ($q['_with_stock_and_value'] == 'dragon' || $q['_with_stock_and_value'] == 'both' ) {
+            
+                $this->selectAdd( "
+                    invdetail_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id, 1)
+                    as  location_qty,
+                    invdetail_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id , -1)
+                    as  location_qty_neg,
+                    invcost_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id)
+                     as location_value
+
+                    
+                    
+                    
+                    ");
+            } else {
+                $this->selectAdd( "
+                    0 as  location_qty,
+                    0 location_qty_neg,
+                    0 as location_value
+                    ");
+                
+            }
+            
+            // need to fetch last invdetail_id for each itemsite_id
+            // where date < current date..
+            //DB_DataObject::debugLevel(1);
+            
+           /* if ($q['_with_stock_and_value'] == 'netsuite' || $q['_with_stock_and_value'] == 'both' ) {
+            //if ($q['_with_stock_and_value'] == 'netsuite') {
+                
+                // netsuite..
+                $this->selectAdd( "
+                    (SELECT sum(sum_qty) FROM 
+                        (SELECT
+                                netsuite_stock.item_id as item_id, sum(qty) as sum_qty
+                            FROM
+                                netsuite_stock
+                            LEFT JOIN
+                                item
+                            ON
+                                item.item_id = netsuite_stock.item_id
+                            WHERE
+                                netsuite_stock.location_id = location.location_id
+                            AND
+                                trans_date < ('$dt'::date + INTERVAL '1 DAY')::date
+                            AND
+                                item.item_type = 'P'
+                            GROUP BY
+                                netsuite_stock.item_id
+                            HAVING
+                                sum(qty) > 0
+                        ) stock_pos
+                    ) as location_netsuite_stock,
+                        
+                    (SELECT sum(sum_qty) FROM 
+                        (SELECT
+                                 netsuite_stock.item_id as item_id, sum(qty) as sum_qty
+                            FROM
+                                netsuite_stock
+                            LEFT JOIN
+                                item
+                            ON
+                                item.item_id = netsuite_stock.item_id
+                            WHERE
+                                netsuite_stock.location_id = location.location_id
+                            AND
+                                trans_date < ('$dt'::date + INTERVAL '1 DAY')::date
+                            AND
+                                item.item_type = 'P'
+                            GROUP BY
+                                netsuite_stock.item_id
+                            HAVING
+                                sum(qty) < 0
+                        ) stock_pos
+                    ) as location_netsuite_stock_neg
+                ");
+            } else {
+            */
+                 $this->selectAdd( "
+                    0 as location_netsuite_stock,
+                    0 location_netsuite_stock_neg
+                ");
+            //}
+            /*
+             *,
+                
+                invdetail_cost_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id)
+                as location_value
+                */
+            //$this->having( "$loc_query > 0 " );
+           
+            
+            
+            
+            
+            
+        }
+        
+        $this->joinAddCustomer();
+        
+        
+    }
+    
+    
+    function defaults()
+    {
+        return array(
+            'location_warehous_id' => $this->sqlValue('(SELECT warehous_id FROM whsinfo ORDER by warehous_id LIMIT 1)'),
+            'location_restrict' => false,
+            'location_whsezone_id' => -1,
+            'location_aisle' => '',
+            'location_rack'=> '',
+            'location_bin'=> '',
+            'location_netable' => 1,
+        );
+    }
+    
+    
+    function beforeInsert($q,$roo)
+    {
+        foreach($this->defaults() as $k=>$v) {
+            if (!isset($q[$k])) {
+                $this->$k = $v;
+            }
+        }
+        
+        
+    }
+    
+    
+    function joinAddCustomer()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN custinfo AS join_location_cust_id_cust_id
+                    ON (join_location_cust_id_cust_id.cust_id= location.location_cust_id)
+        ";
+        $t = DB_DataObject::Factory('custinfo');
+        $this->selectAs($t, 'location_cust_id_%s', 'join_location_cust_id_cust_id');
+       
+        $this->selectAdd(" charass_getvalue('C', location_cust_id,'INTERNALCOMPANY')
+                         as location_cust_id_char_internalcompany ");
+    }
+    
+    
+    function postListFilter($data, $authUser, $q)
+    {
+        if (!isset($q['_with_stock_and_value'])) {
+            return $data;
+        }
+        //if (!empty($q['_with_empty'])) {
+            return $data;
+        //}
+        
+        $ret = array();
+        foreach($data as $r) {
+            if ($r['location_qty'] == 0.0 && $r['location_qty_neg'] == 0.0 ) {
+                continue;
+            }
+            $ret[] = $r;
+        }
+        
+        return $ret;
+        
+        
+    }
+    /**
+     *
+     * depricated -- should be configured in bootstarp..
+     * probably not used now..
+     */
+    function defaultLocation()
+    {
+        // based on config...
+        
+        return $this->defaultConfigLocation();
+        /*
+        $l = DB_DataObject::factory('location');
+        $locamap = array(
+            'hk' => 'OLL',
+            'sg' => 'Kerry SG',
+            'my' => 'Kerry MY'
+        );
+        $l->get('location_name', $locamap[substr($this->database(),-2)]);
+        return $l;
+        */
+        
+    }
+    
+    function defaultByItemsite()
+    {   
+        // get the best location id
+        $is = DB_DataObject::factory('itemsite');
+        $is->selectAdd();
+        $is->selectAdd("DISTINCT('itemsite_location_id'), count(itemsite_id) as count_id, itemsite_location_id");
+        $is->groupBy('itemsite_location_id');
+        $is->orderBy('count_id DESC');
+        $is->limit(1);
+        $is->find(true);
+        
+        return $is;
+    }
+    
+    function defaultConfigLocation()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if(!isset($ff->Xtuple['default_location']) || empty($ff->Xtuple['default_location'])){
+            $ff->page->jerr('Xtuple default location has not been set');
+        }
+            
+        $l = DB_DataObject::factory('location');
+        if(!$l->get('location_name', $ff->Xtuple['default_location'])){
+            $ff->page->jerr('Can not found the default location : ' . $ff->Xtuple['default_location']);
+        }
+        
+        return $l;
+    }
+    
+    function importFromArray($roo, $locations)
+    {
+        foreach ($locations as $location){
+            $l = DB_DataObject::factory('location');
+            if($l->get('location_name', $location['location_name'])){
+                continue;
+            }
+            $l->setFrom($l->defaults());
+            $l->location_name = $location['location_name'];
+            $l->insert();
+        }
+    }
+    
+}
diff --git a/DataObjects/Locbal.php b/DataObjects/Locbal.php
new file mode 100644 (file)
index 0000000..54e1eee
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Table Definition for locitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Locbal extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'locbal';             // table name
+    public $locbal_id;                      // int4(4)  not_null default_nextval%28%28%22locitem_locitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $locbal_location_id;             // int4(4)  
+    public $locbal_itemsite_id;                 // int4(4)
+    public $locbal_ending;
+    
+    public $locbal_beginning;
+    public $locbal_credit;
+    public $locbal_debit;
+    
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q,$au, $roo)
+    {
+        if (!empty($q['_sync'])) {
+            $this->sync($roo,$q);
+        }
+        
+        
+        
+        
+    }
+    
+    function sync($roo,$q)
+    {
+        $limit = 5;
+        
+        $t = DB_DataObject::Factory('itemsite');
+        $off = isseT($q['offset']) ? (int)$q['offset'] : 0;
+        $total = $t->count();
+        if ($off > $total) {
+            $roo->jok(array('total' => 0));
+        }
+        
+        $t->orderBy('itemsite_id ASC');
+        $t->limit($off, $limit  );
+        $ids = $t->fetchAll('itemsite_id');
+        foreach($ids as $id) {
+            
+            $qq = DB_DataObject::factory('locbal');
+            $qq->query("SELECT locbal_update_location_itemsite(a,b,c)
+                    FROM (
+                        SELECT distinct(invhist_itemsite_id) b, invdetail_location_id a, MAX(invhist_transdate)::date c
+                        FROM invdetailview
+                        WHERE invhist_itemsite_id  = {$id}
+                        GROUP BY invhist_itemsite_id, invdetail_location_id  ) d;
+            ");
+            
+            
+        }
+        $roo->jok(array('total'=> $total, 'limit'=>$limit  ));
+        
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Locitem.php b/DataObjects/Locitem.php
new file mode 100644 (file)
index 0000000..daf016c
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for locitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Locitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'locitem';             // table name
+    public $locitem_id;                      // int4(4)  not_null default_nextval%28%28%22locitem_locitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $locitem_location_id;             // int4(4)  
+    public $locitem_item_id;                 // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Metasql.php b/DataObjects/Metasql.php
new file mode 100644 (file)
index 0000000..0b2a278
--- /dev/null
@@ -0,0 +1,687 @@
+<?php
+/**
+ * Table Definition for metasql
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Metasql extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'metasql';             // table name
+    public $metasql_id;                      // int4(4)  not_null default_nextval%28metasql_metasql_id_seq%29 primary_key
+    public $metasql_group;                   // text(-1)  unique_key multiple_key
+    public $metasql_name;                    // text(-1)  unique_key multiple_key
+    public $metasql_notes;                   // text(-1)  
+    public $metasql_query;                   // text(-1)  
+    public $metasql_lastuser;                // text(-1)  
+    public $metasql_lastupdate;              // date(4)  
+    public $metasql_grade;                   // int4(4)  not_null default_0 unique_key multiple_key
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    var $_debug = false;
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (isset($q['_updatefromfile']) && isset($q['_group']) && isset($q['_name'])) {
+            return $this->updateFromFile($q,$au,$roo);
+            
+            
+            
+        }
+        
+        if (isset($q['_group'])) {
+            if (!isset($q['_name'])) {
+                $roo->jerr("no name set");
+            }
+            
+            
+            $this->runReport($q, $roo);
+            return;
+        }
+        
+     
+     
+         
+    }
+    
+    function updateFromFile($q,$au,$roo)
+    {
+           $d = DB_DataObject::Factory('metasql');
+        $d->metasql_group = $q['_group'];
+        $d->metasql_name = $q['_name'];
+         //SELECT metasql_query   FROM metasql WHERE ((metasql_group='salesHistory')     AND (metasql_name='detail')) ORDER BY metasql_grade DESC LIMIT 1;
+        $d->limit(1);
+        $d->orderBy('metasql_grade DESC ');
+        if (!$d->find(true)) {
+            $roo->jerr("does not exist");
+        }
+        if (!file_exists(__DIR__.'/../metasql/'.$q['_group'].'.'.$q['_name'] . '.sql')) {
+            $roo->jerr("update file does not exist");
+        }
+        $dd = clone($d);
+        $d->metasql_query = file_get_contents(__DIR__.'/../metasql/'.$q['_group'].'.'.$q['_name'] . '.sql');
+        $d->update($dd);
+        $roo->jok("updated");
+    }
+    
+    /**
+     *
+     * usage example:
+     * _group=bankrec&_name=checks&bankrecid:number=99&bankaccntid:number=15
+     * 
+     *
+     */
+    
+    
+    function buildReportQuery($q,$roo)
+    {
+         $d = DB_DataObject::Factory('metasql');
+        $d->metasql_group = $q['_group'];
+        $d->metasql_name = $q['_name'];
+         //SELECT metasql_query   FROM metasql WHERE ((metasql_group='salesHistory')     AND (metasql_name='detail')) ORDER BY metasql_grade DESC LIMIT 1;
+        $d->limit(1);
+        $d->orderBy('metasql_grade DESC ');
+        $d->find(true); 
+        
+        // if we override it with a global report..
+        if (file_exists(__DIR__.'/../metasql/'.$q['_group'].'.'.$q['_name'] . '.sql')) {
+           // echo "LOADING FROM file";
+            $d->metasql_query = file_get_contents(__DIR__.'/../metasql/'.$q['_group'].'.'.$q['_name'] . '.sql');
+        }
+        
+        preg_match_all('/^\s*\-\-.*$/m', $d->metasql_query, $matches);
+        
+        $hitEnd = false;
+        $hitStart = false;
+        $titlesAndCols = new stdClass();
+        
+        $json = '';
+        foreach ($matches[0] as $k => $v){
+            $matches[0][$k] = trim(preg_replace('/^\s*\-\-/m', '', $v));
+            if(preg_match('/JSON START/', $matches[0][$k])){
+               $hitStart = true; 
+               continue;
+            }
+            if($hitEnd || !$hitStart){
+                continue;
+            }
+            if(preg_match('/JSON END/', $matches[0][$k])){
+                $hitEnd = true;
+                continue;
+            }
+            
+            $res = json_decode($matches[0][$k]);
+            //echo '<PRE>';            var_dump($res);
+            if ($res && (isset($res->TITLES) || isset($res->COLS))) {
+                // old format..
+                $titlesAndCols = (object)array_merge((array)$titlesAndCols, (array)$res);
+                //print_R($titlesAndCols );
+            } else {
+                // new format..
+                $json .=  "\n" . $matches[0][$k];
+            }
+            
+        }
+        
+        //echo '<PRE>';print_r($titlesAndCols); echo '<PRE>';print_r(json_decode($json)); echo $json;exit;
+        
+        $titlesAndCols->TITLES = isset($titlesAndCols->TITLES) ? $titlesAndCols->TITLES : '*';
+        $titlesAndCols->COLS = isset($titlesAndCols->COLS) ? $titlesAndCols->COLS : '*';
+        
+        $json = trim($json);
+        $cfg = false;
+        if (strlen($json)) {
+            require_once 'Services/JSON.php';
+            $sj = new Services_JSON();
+            $res = $sj->decode($json);
+            if (empty($res) || !count(array_keys((array) $res))) {
+                $roo->jerr("invalid config: ". $json);
+            }
+            if (!empty($q['_debug'])) { 
+                echo'<PRE>' .htmlspecialchars( print_r( $res,true));
+            }
+            //echo '<PRE>';print_r($res);
+            $cfg = (array)$res;
+            
+            
+        }
+        
+        
+        if (empty($d->metasql_query)) {
+            $roo->jerr("invalid report");
+        }
+        //echo $d->metasql_query ;exit;
+        
+        $this->request = $q;
+        $this->roo = $roo;
+        
+        if (!empty($q['_debug'])) {
+            $this->_debug = 1;
+            
+        }
+        if (!empty($q['_debug2'])) {
+            echo $d->metasql_query;
+            exit;
+        }
+        
+        return  array('query' => $this->toPHP($d->metasql_query), 'info' => $titlesAndCols, 'cfg' => $cfg);
+        
+        
+        
+    }
+    function toSimpleExcelGroupRow($x, $cfg, $q) {
+        $xx = array();
+        foreach($cfg as $col=>$value) {
+            if (is_string($value)) {
+                $xx[$col] = $x[$value];
+                continue;
+            }
+            if (isset($value->text)) {
+                $xx[$col] = $value->text;
+                continue;
+            }
+            // no evil / eval support..
+            
+        }
+        return $xx;
+        
+        
+    }
+    
+    function toSimpleExcelHeader($lines, $q) {
+        
+        $all = array();
+        foreach($lines as $line) {
+            if (!$line) {
+                continue;
+            }
+            $ret = array();
+            foreach($line as $col) {
+                if (is_string($col)) {
+                    $ret[] = $col;
+                    continue;
+                }
+                if (isset($col->req)) {
+                    //var_dump($col->req);
+                    $ret[] = isset($q[$col->req]) ?  $q[$col->req] : '';
+                    continue;
+                }
+                if (isset($col->req_lookup) ) {
+                    $x = DB_DAtaObject::Factory($col->req_lookup[0]);
+                    $x->get($col->req_lookup[1], (int) $q[$col->req_lookup[2]  ]);
+                    
+                    $ret[] = $x->{$col->req_lookup[3]};
+                    continue;
+                }
+                
+            }
+            $all[] = $ret;
+        }
+        
+         if (!empty($q['_debug'])) {
+            echo '<PRE>'.htmlspecialchars(print_r($all,true));
+            
+        }
+        return $all;
+        
+        
+    }
+    
+    
+    
+    function toSimpleExcel($roo,$q, $cfg, $xls = false)
+    {
+        
+        
+        $filename = empty($q['_filename']) ? '' : $q['_filename'];
+        $addDate = true;
+        $fn = (empty($filename) ? 'list-export-' : urlencode($filename)) . (($addDate) ? date('Y-m-d') : '') ;
+        
+        $roo->sessionState(0); // turn off sessions  - no locking..
+
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+
+        // fill in some defaults for the cols..
+        foreach($cfg['cols'] as $i=>$c) {
+            $cfg['cols'][$i] = (array)$cfg['cols'][$i] ;
+            
+            if (!isset($c->width)) {
+                $cfg['cols'][$i]['width'] = 100;
+            }
+        }
+        //echo '<PRE>';print_r($cfg);exit;
+               
+        $se_config=  array(
+            'workbook' => $xls ? $q['_name'] : substr($fn, 0, 31),
+            'cols' => $cfg['cols'],
+            'leave_open' => true,
+            'formats' => isset($cfg['formats']) ? $cfg['formats'] : array(),
+            'head' => isset($cfg['head']) ? $this->toSimpleExcelHeader($cfg['head'], $q) : array()
+        );
+        
+         
+        if ($xls) {
+            $se = is_object($xls) ? $xls : new Pman_Core_SimpleExcel(array(),  array(
+                'leave_open' => true,
+                //'workbooks' => array(  )
+            ));
+            $xls = $se;
+            //print_R($se_config);
+            $se->buildPage( array(), array(), $se_config);
+            
+        } else {
+            $se  = new Pman_Core_SimpleExcel(array(), $se_config);
+        }
+        
+        $lines = 0;
+        $rooar = method_exists($this, 'toRooArray');
+        
+        $grouping = false;
+        $last = false;
+        
+        
+        $group_col = isset($cfg['group']->col) ? $cfg['group']->col : false; // only support 1 grouping at present..
+   
+        while($this->fetch()) {
+            $lines ++;
+            $x = $rooar  ? $this->toRooArray($q) : $this->toArray();
+            
+            // handle grouping here.. or in pman_core?? - -later??
+            
+            if ($group_col && $x[$group_col] != $last[$group_col]) {
+                if ($last && isset ($cfg['group']->end)) {   
+                    $xx =  $this->toSimpleExcelGroupRow($x, $cfg['group']->end, $q);
+                    $se->addLine($se_config['workbook'], $xx);    
+                }
+                if (isset ($cfg['group']->split)) {   
+                    
+                    $se->addLine($se_config['workbook'], array());    
+                }
+                
+                if (isset ($cfg['group']->start)) {   
+                    $xx =  $this->toSimpleExcelGroupRow($x, $cfg['group']->start,$q);
+                    $se->addLine($se_config['workbook'], $xx);    
+                }
+            }
+            
+            
+            $se->addLine($se_config['workbook'], $x);
+            $last = $x;
+                
+        } 
+        
+        if(!$lines){
+                
+            $roo->jerr('no data found', false, 'text/plain');
+        }
+        
+        if ($last && isset ($cfg['group']->end)) {   
+            $xx =  $this->toSimpleExcelGroupRow($last, $cfg['group']->end,$q);
+            $se->addLine($se_config['workbook'], $xx);    
+        }
+        if ($xls !== false) {
+            return $xls;
+        }
+        
+        $se->send($fn .'.xls');
+        exit;
+            
+    } 
+
+    
+    
+    
+    
+    function runReport($q, $roo)
+    {
+        $roo->sessionState(0);
+        set_time_limit(0);
+        
+        if (is_array($q['_name'])) {
+            $qq = $q;
+            $xls = true;
+            foreach($q['_name'] as $rpt) {
+                $qq['_name'] = $rpt;
+                $qthis = clone($this);
+                
+                $queryinfo =  $this->buildReportQuery($qq,$roo);
+                $query = $queryinfo['query'];
+                $info = $queryinfo['info'];
+                
+                if (empty($queryinfo['cfg'])) {
+                    $roo->jerr("multipage reports require json config in metasql - missing from ".$qq['_name']);
+                }
+                /*
+                 *no support for limitng in multipage?
+                $from =  empty($q['start']) ? 0 : (int)$q['start'];
+                // this allows insane limits.
+                
+                $to = min(empty($q['limit']) ? 25 : (int)$q['limit'], 100000);
+                */
+                $query = preg_replace('#;$#', '', trim($query));
+                
+                //$qq =clone($this);
+                //$qq->query($query); // runs query without 
+                //$total = $qq->N;
+                
+                
+                
+                //$query .= " LIMIT $to OFFSET $from ";
+                
+                ini_set('memory_limit', '256M');
+                $qthis->query($query);
+                
+                
+                
+                $xls = $qthis->toSimpleExcel($roo,$qq, $queryinfo['cfg'], $xls);
+                
+                
+            }
+            $filename = empty($q['_filename']) ? '' : $q['_filename'];
+     
+            $addDate = true;
+        
+            $fn = (empty($filename) ? 'list-export-' : urlencode($filename)) . (($addDate) ? date('Y-m-d') : '') ;
+    
+            $xls->send($fn .'.xls');
+            exit;
+            
+        }
+        
+        
+        
+        $queryinfo =  $this->buildReportQuery($q,$roo);
+        $query = $queryinfo['query'];
+        $info = $queryinfo['info'];
+        
+        $from =  empty($q['start']) ? 0 : (int)$q['start'];
+        // this allows insane limits.
+        
+        $to = min(empty($q['limit']) ? 25 : (int)$q['limit'], 100000);
+        
+        $query = preg_replace('#;$#', '', trim($query));
+        
+        $qq =clone($this);
+        $qq->query($query);
+        $total = $qq->N;
+        
+        $query .= " LIMIT $to OFFSET $from ";
+        
+        ini_set('memory_limit', '256M');
+        $this->query($query);
+        
+        
+        if (!empty($queryinfo['cfg']) && isset($q['csvCols'])) {
+            $this->toSimpleExcel($roo,$q, $queryinfo['cfg']);
+        }
+        
+        $rooar = method_exists($this, 'toRooArray');
+        $ret = array();
+        
+        
+        
+        
+        if (!empty($q['csvCols']) && !empty($q['csvTitles']) ) {
+            $csvCols = ($q['csvCols'] == '*') ? $info->COLS : $q['csvCols'];
+            $csvTitles = ($q['csvTitles'] == '*') ? $info->TITLES : $q['csvTitles'];
+            
+            $roo->toCsv($this, $csvCols, $csvTitles,
+                        empty($q['csvFilename']) ? '' : $q['csvFilename']
+            );
+            exit;
+        }
+        
+        
+        
+        
+        while ($this->fetch()) {
+            //print_R($x);exit;
+            $add = $rooar  ? $this->toRooArray($q) : $this->toArray();
+            
+            $ret[] = $add; //!$_columns ? $add : array_intersect_key($add, $_columnsf);
+        }
+        
+        //$total = 0; // we can not work this out.
+        $extra = array();
+        
+        $meta = array();
+         
+        if (!empty($ret)) {
+            foreach(array_keys($ret[0]) as  $c ) {
+                 // all strings..
+                $meta[] = $c;
+            }
+            $extra['metaData']  = array(
+                'totalProperty' =>  'total',
+                'successProperty' => 'success',
+                'root' => 'data',
+                'id' => 'id',
+                'fields' => $meta
+            );
+            
+        }
+        $extra = array_merge($this->postListExtra($q, $roo), $extra);
+        
+        
+        
+        $roo->jdata($ret, max(count($ret), $total), $extra );
+        // roo???
+        
+        die("DONE?");
+        return $this->toCsv($d, false);
+        
+    }
+    function toPHP($q) {
+        
+        
+        
+        
+        //echo'<PRE>' .htmlspecialchars(  $q);
+        
+        $q = preg_replace('/^\s*\-\-.*$/m', '', $q);
+        
+        preg_match_all('#\<\?([^?]+)\?\>#', $q, $matches);
+        ///echo '<PRE>' . htmlspecialchars(print_r($matches,true));
+        foreach($matches[0] as $i=>$full) {
+            $q = str_replace($full, $this->toEl($matches[1][$i]), $q);
+        }
+        if ($this->_debug) {
+            echo'<PRE>' .htmlspecialchars( print_r(explode("\n", $q),true));
+        }
+        
+        
+        $meta = $this;
+        
+        
+        ob_start();
+        
+        
+        eval( '?>' . $q );
+        $data = ob_get_contents();
+        ob_end_clean();
+        //echo $data;
+        // finally strip out all the comments...
+        $lines = explode("\n", $data);
+        $out = array();
+        foreach($lines as $l) {
+            if (preg_match('#^\s*--#', $l)) {
+                continue;
+            }
+            $out[] = $l;
+        }
+        
+        
+         return implode("\n", $out);
+        
+        
+    }
+    function toEl($str) {
+        // replace all the strings with variable references;
+        $str= trim($str);
+        preg_match_all('#"([a-z0-9_]+)"#i', $str, $matches);
+        //print_R($matches);
+        
+        //foreach($matches[0] as $i=>$full) {
+        //    $sub = $matches[1][$i];
+        //    $str = str_replace($full, '$t->'. $sub, $str);
+        //}
+        
+        // functions..
+        $matches = array();
+        if (preg_match_all('#([a-z0-9_]+)\(([^\)]+)\)?#i', $str, $matches)) {
+            
+            //print_R($matches);
+            
+            foreach($matches[0] as $i=>$full) {
+                $sub = $matches[1][$i];
+                $args = $matches[2][$i];
+                
+                
+                $str = str_replace($full, '$this->meta'. $sub .'(' . $args . ')', $str);
+            }
+        }
+        
+        
+        
+        
+        if (preg_match('#^if#', $str)) {
+            $str = preg_replace('/^if/', '', $str);
+            $str = 'if ( ' . $str .' ) {';
+            
+        } else  if (preg_match('#^endif$#', $str)) {
+            $str = '}';
+        } else if (preg_match('#^elseif#', $str)) {
+            $str = preg_replace('/^elseif/', '', $str);
+            $str = ' } else if ( ' . $str .' ) {';
+        } else if (preg_match('#^else#', $str)) {
+            $str = '} else {';
+        }
+        
+        return '<?php ' . $str . ' ?>';
+        
+        
+        
+    }
+    
+    function metaexists($a)
+    {
+        if (isset($this->request[$a.':number']) || isset($this->request[$a.':text'])) {
+            return true;
+        }
+        return false;
+        
+    }
+    
+    function metavalueor($a,$empty) {
+        if (!$this->metaexists($a)) {
+            echo $empty;
+            return;
+        }
+        return $this->metavalue($a);
+    }
+    
+    function metavalue($a) {
+        
+        static $do = false;
+        if (!$do) {
+            $do = DB_DataObject::Factory('metasql');
+        }
+        if (!$this->metaexists($a)) {
+            $this->roo->jerr("required variable not found: " . $a);
+        }
+        if (isset($this->request[$a.':number'])) {
+            echo (float) $this->request[$a.':number'];
+            return;
+        }
+        // it's text
+            // make sure debugging is off for output..
+           $old = DB_DataObject::debugLevel(0);   
+           echo "'". $do->escape($this->request[$a.':text']). "'";
+           DB_DataObject::debugLevel($old );   
+    }
+    
+    function postListExtra($q,$roo)
+    {   
+        if (!empty($q['_sum_prev'])) {
+            // run the above query and check the and do a sum(amount) as amount..
+            // this is used by bankrec...
+            // it adds 'amount' as an extra based on the total before this data..
+
+            $queryinfo  = $this->buildReportQuery($q,$roo);
+            $query = $queryinfo['query'];
+            $info = $queryinfo['info'];
+
+            $from =  empty($q['start']) ? 0 : (int)$q['start'];
+            // this allows insane limits.
+
+            $query = preg_replace('#;$#', '', trim($query));
+
+            $query .= " LIMIT $from OFFSET 0 ";
+
+            $col = $q['_sum_prev'];
+            $query = "SELECT COALESCE(sum( $col),0) as $col FROM (   $query ) mquery";
+             $do = DB_DataObject::Factory('metasql');
+             $do->query($query);
+             $do->fetch();
+             $ret = array();
+             $ret[$col] = $do->$col;
+             return $ret; 
+            
+        }
+        
+        
+        if(!empty($q['_cals']) && !empty($q['sortdate:text'])){
+            
+            $queryinfo  = $this->buildReportQuery($q,$roo);
+            $query = $queryinfo['query'];
+            $info = $queryinfo['info'];
+
+            $from =  empty($q['start']) ? 0 : (int)$q['start'];
+            // this allows insane limits.
+
+            $query = preg_replace('#;$#', '', trim($query));
+
+            $query .= " LIMIT $from OFFSET 0 ";
+
+            $col = $q['_cals'];
+            $query = "SELECT COALESCE(sum( $col),0) as $col FROM (   $query ) mquery";
+            $do = DB_DataObject::Factory('metasql');
+            $do->query($query);
+            $do->fetch();
+            $prev_amount = $do->$col;
+            
+            $q['cals:text'] = $q['sortdate:text'];
+            unset($q['sortdate:text']);
+           
+            $queryinfo  = $this->buildReportQuery($q,$roo);
+            $query = $queryinfo['query'];
+            $info = $queryinfo['info'];
+            
+            $query = preg_replace('#;$#', '', trim($query));
+            
+            $col = $q['_cals'];
+            $query = "SELECT COALESCE(sum( $col),0) as $col FROM (   $query ) mquery";
+             $do = DB_DataObject::Factory('metasql');
+             $do->query($query);
+             $do->fetch();
+             $ret = array();
+             $ret[$col] = $do->$col + $prev_amount;
+             return $ret; 
+           
+        }
+         
+         return array();
+        
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Metric.php b/DataObjects/Metric.php
new file mode 100644 (file)
index 0000000..6b9f8fc
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for metric
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Metric extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'metric';              // table name
+    public $metric_id;                       // int4(4)  not_null default_nextval%28%28metric_metric_id_seq%29%3A%3Aregclass%29 primary_key
+    public $metric_name;                     // text(-1)  
+    public $metric_value;                    // text(-1)  
+    public $metric_module;                   // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Metricenc.php b/DataObjects/Metricenc.php
new file mode 100644 (file)
index 0000000..5218763
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for metricenc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Metricenc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'metricenc';           // table name
+    public $metricenc_id;                    // int4(4)  not_null default_nextval%28metricenc_metricenc_id_seq%29 primary_key
+    public $metricenc_name;                  // text(-1)  
+    public $metricenc_value;                 // bytea(-1)  
+    public $metricenc_module;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Mrghist.php b/DataObjects/Mrghist.php
new file mode 100644 (file)
index 0000000..f667b52
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for mrghist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Mrghist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'mrghist';             // table name
+    public $mrghist_cntct_id;                // int4(4)  not_null primary_key multiple_key
+    public $mrghist_table;                   // text(-1)  not_null primary_key multiple_key
+    public $mrghist_pkey_col;                // text(-1)  not_null primary_key multiple_key
+    public $mrghist_pkey_id;                 // int4(4)  not_null primary_key multiple_key
+    public $mrghist_cntct_col;               // text(-1)  not_null primary_key multiple_key
+
+    
+   /**
+    * Getter / Setter for $mrghist_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('mrghist_cntct_id', func_get_arg(0)) : $this->link('mrghist_cntct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Msg.php b/DataObjects/Msg.php
new file mode 100644 (file)
index 0000000..9297a6e
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for msg
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Msg extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'msg';                 // table name
+    public $msg_id;                          // int4(4)  not_null default_nextval%28%28%22msg_msg_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $msg_posted;                      // timestamptz(8)  
+    public $msg_scheduled;                   // timestamptz(8)  
+    public $msg_text;                        // text(-1)  
+    public $msg_expires;                     // timestamptz(8)  
+    public $msg_username;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Msguser.php b/DataObjects/Msguser.php
new file mode 100644 (file)
index 0000000..a4bce29
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for msguser
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Msguser extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'msguser';             // table name
+    public $msguser_id;                      // int4(4)  not_null default_nextval%28%28%22msguser_msguser_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $msguser_msg_id;                  // int4(4)  
+    public $msguser_viewed;                  // timestamptz(8)  
+    public $msguser_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Netsuite_balance.php b/DataObjects/Netsuite_balance.php
new file mode 100644 (file)
index 0000000..4ce7425
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for msguser
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Netsuite_balance extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'netsuite_balance';             // table name
+    public $id;
+    
+      public $period_id;// integer,
+     public $accnt_id;// integer,
+     public $beginning;// numeric(10,2),
+     public $ending;// numeric(10,2),
+     public $hkd_beginning;// numeric(10,2),
+     public $hkd_ending;// numeric(10,2),
+     public $base_close;// numeric(10,2),
+     
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Netsuite_stock.php b/DataObjects/Netsuite_stock.php
new file mode 100644 (file)
index 0000000..ecd9416
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Table Definition for msguser
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Netsuite_stock extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'netsuite_stock';             // table name
+    public $id;
+    
+    
+    public $curr_id;  // integer,
+    public $location_id;  // integer,
+    public $item_id;  // integer,
+    public $qty;  // integer,
+    public $txref;  // text,
+    public $txtype;  // text,
+    public $amount;  // numeric(14,2),
+    public $amount_hkd;  // numeric(14,2),
+    
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Obsolete_tax.php b/DataObjects/Obsolete_tax.php
new file mode 100644 (file)
index 0000000..39a3507
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Table Definition for obsolete_tax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Obsolete_tax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'obsolete_tax';        // table name
+    public $tax_id;                          // int4(4)  not_null default_nextval%28%28%22tax_tax_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $tax_code;                        // text(-1)  
+    public $tax_descrip;                     // text(-1)  
+    public $tax_ratea;                       // numeric(-1)  
+    public $tax_sales_accnt_id;              // int4(4)  
+    public $tax_freight;                     // bool(1)  not_null default_false
+    public $tax_cumulative;                  // bool(1)  not_null default_false
+    public $tax_rateb;                       // numeric(-1)  
+    public $tax_salesb_accnt_id;             // int4(4)  
+    public $tax_ratec;                       // numeric(-1)  
+    public $tax_salesc_accnt_id;             // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Ophead.php b/DataObjects/Ophead.php
new file mode 100644 (file)
index 0000000..8fdac52
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Table Definition for ophead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Ophead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'ophead';              // table name
+    public $ophead_id;                       // int4(4)  not_null default_nextval%28ophead_ophead_id_seq%29 primary_key
+    public $ophead_name;                     // text(-1)  not_null
+    public $ophead_crmacct_id;               // int4(4)  
+    public $ophead_owner_username;           // text(-1)  
+    public $ophead_opstage_id;               // int4(4)  
+    public $ophead_opsource_id;              // int4(4)  
+    public $ophead_optype_id;                // int4(4)  
+    public $ophead_probability_prcnt;        // int4(4)  
+    public $ophead_amount;                   // numeric(-1)  
+    public $ophead_target_date;              // date(4)  
+    public $ophead_actual_date;              // date(4)  
+    public $ophead_notes;                    // text(-1)  
+    public $ophead_curr_id;                  // int4(4)  
+    public $ophead_active;                   // bool(1)  default_true
+    public $ophead_cntct_id;                 // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $ophead_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('ophead_cntct_id', func_get_arg(0)) : $this->link('ophead_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $ophead_crmacct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function crmacct() {
+        return func_num_args() ? $this->link('ophead_crmacct_id', func_get_arg(0)) : $this->link('ophead_crmacct_id');
+    }
+
+   /**
+    * Getter / Setter for $ophead_opsource_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function opsource() {
+        return func_num_args() ? $this->link('ophead_opsource_id', func_get_arg(0)) : $this->link('ophead_opsource_id');
+    }
+
+   /**
+    * Getter / Setter for $ophead_opstage_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function opstage() {
+        return func_num_args() ? $this->link('ophead_opstage_id', func_get_arg(0)) : $this->link('ophead_opstage_id');
+    }
+
+   /**
+    * Getter / Setter for $ophead_optype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function optype() {
+        return func_num_args() ? $this->link('ophead_optype_id', func_get_arg(0)) : $this->link('ophead_optype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Opsource.php b/DataObjects/Opsource.php
new file mode 100644 (file)
index 0000000..361ea0d
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for opsource
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Opsource extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'opsource';            // table name
+    public $opsource_id;                     // int4(4)  not_null default_nextval%28opsource_opsource_id_seq%29 primary_key
+    public $opsource_name;                   // text(-1)  not_null unique_key
+    public $opsource_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Opstage.php b/DataObjects/Opstage.php
new file mode 100644 (file)
index 0000000..1b67432
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for opstage
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Opstage extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'opstage';             // table name
+    public $opstage_id;                      // int4(4)  not_null default_nextval%28opstage_opstage_id_seq%29 primary_key
+    public $opstage_name;                    // text(-1)  not_null unique_key
+    public $opstage_descrip;                 // text(-1)  
+    public $opstage_order;                   // int4(4)  not_null default_0
+    public $opstage_opinactive;              // bool(1)  default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Optype.php b/DataObjects/Optype.php
new file mode 100644 (file)
index 0000000..9c774ac
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for optype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Optype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'optype';              // table name
+    public $optype_id;                       // int4(4)  not_null default_nextval%28optype_optype_id_seq%29 primary_key
+    public $optype_name;                     // text(-1)  not_null unique_key
+    public $optype_descrip;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Orderhead.php b/DataObjects/Orderhead.php
new file mode 100644 (file)
index 0000000..dee873f
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Table Definition for orderhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Orderhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'orderhead';           // table name
+    public $orderhead_id;                    // int4(4)  
+    public $orderhead_type;                  // text(-1)  
+    public $orderhead_number;                // text(-1)  
+    public $orderhead_status;                // bpchar(-1)  
+    public $orderhead_orderdate;             // date(4)  
+    public $orderhead_linecount;             // int8(8)  
+    public $orderhead_from_id;               // int4(4)  
+    public $orderhead_from;                  // text(-1)  
+    public $orderhead_to_id;                 // int4(4)  
+    public $orderhead_to;                    // text(-1)  
+    public $orderhead_curr_id;               // int4(4)  
+    public $orderhead_agent_username;        // text(-1)  
+    public $orderhead_shipvia;               // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Orderitem.php b/DataObjects/Orderitem.php
new file mode 100644 (file)
index 0000000..dc07395
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Table Definition for orderitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Orderitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'orderitem';           // table name
+    public $orderitem_id;                    // int4(4)  
+    public $orderitem_orderhead_type;        // text(-1)  
+    public $orderitem_orderhead_id;          // int4(4)  
+    public $orderitem_linenumber;            // int4(4)  
+    public $orderitem_status;                // bpchar(-1)  
+    public $orderitem_itemsite_id;           // int4(4)  
+    public $orderitem_scheddate;             // date(4)  
+    public $orderitem_qty_ordered;           // numeric(-1)  
+    public $orderitem_qty_shipped;           // numeric(-1)  
+    public $orderitem_qty_received;          // numeric(-1)  
+    public $orderitem_qty_uom_id;            // int4(4)  
+    public $orderitem_qty_invuomratio;       // numeric(-1)  
+    public $orderitem_unitcost;              // numeric(-1)  
+    public $orderitem_unitcost_curr_id;      // int4(4)  
+    public $orderitem_freight;               // numeric(-1)  
+    public $orderitem_freight_received;      // numeric(-1)  
+    public $orderitem_freight_curr_id;       // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Orderseq.php b/DataObjects/Orderseq.php
new file mode 100644 (file)
index 0000000..007d7d5
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for orderseq
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Orderseq extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'orderseq';            // table name
+    public $orderseq_id;                     // int4(4)  not_null default_nextval%28%28orderseq_orderseq_id_seq%29%3A%3Aregclass%29 primary_key
+    public $orderseq_name;                   // text(-1)  
+    public $orderseq_number;                 // int4(4)  
+    public $orderseq_table;                  // text(-1)  
+    public $orderseq_numcol;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Pack.php b/DataObjects/Pack.php
new file mode 100644 (file)
index 0000000..89f2f53
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for pack
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pack extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pack';                // table name
+    public $pack_id;                         // int4(4)  not_null default_nextval%28pack_pack_id_seq%29 primary_key
+    public $pack_head_id;                    // int4(4)  not_null
+    public $pack_head_type;                  // text(-1)  not_null
+    public $pack_shiphead_id;                // int4(4)  
+    public $pack_printed;                    // bool(1)  not_null default_false
+
+    
+   /**
+    * Getter / Setter for $pack_shiphead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shiphead() {
+        return func_num_args() ? $this->link('pack_shiphead_id', func_get_arg(0)) : $this->link('pack_shiphead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Payaropen.php b/DataObjects/Payaropen.php
new file mode 100644 (file)
index 0000000..1147ac4
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for payaropen
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Payaropen extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'payaropen';           // table name
+    public $payaropen_ccpay_id;              // int4(4)  not_null primary_key multiple_key
+    public $payaropen_aropen_id;             // int4(4)  not_null primary_key multiple_key
+    public $payaropen_amount;                // numeric(-1)  not_null default_0.00
+    public $payaropen_curr_id;               // int4(4)  default_basecurrid%28%29
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Payco.php b/DataObjects/Payco.php
new file mode 100644 (file)
index 0000000..9f2ac30
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for payco
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Payco extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'payco';               // table name
+    public $payco_ccpay_id;                  // int4(4)  not_null
+    public $payco_cohead_id;                 // int4(4)  not_null
+    public $payco_amount;                    // numeric(-1)  not_null default_0.00
+    public $payco_curr_id;                   // int4(4)  default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $payco_ccpay_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ccpay() {
+        return func_num_args() ? $this->link('payco_ccpay_id', func_get_arg(0)) : $this->link('payco_ccpay_id');
+    }
+
+   /**
+    * Getter / Setter for $payco_cohead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cohead() {
+        return func_num_args() ? $this->link('payco_cohead_id', func_get_arg(0)) : $this->link('payco_cohead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Period.php b/DataObjects/Period.php
new file mode 100644 (file)
index 0000000..0407bd6
--- /dev/null
@@ -0,0 +1,442 @@
+<?php
+/**
+ * Table Definition for period
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Period extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'period';              // table name
+    public $period_id;                       // int4(4)  not_null default_nextval%28period_period_id_seq%29 primary_key
+    public $period_start;                    // date(4)  
+    public $period_end;                      // date(4)  
+    public $period_closed;                   // bool(1)  
+    public $period_freeze;                   // bool(1)  
+    public $period_initial;                  // bool(1)  default_false
+    public $period_name;                     // text(-1)  
+    public $period_yearperiod_id;            // int4(4)  
+    public $period_quarter;                  // int4(4)  
+    public $period_number;                   // int4(4)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function yearperiod()
+    {
+        $d = DB_DataObject::Factory('yearperiod');
+        $d->get($this->period_yearperiod_id);
+        return $d;
+    }
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['_initPeriods'])) {
+            $this->initPeriods($roo);
+            $roo->jok("DONE");
+        }
+        if (!empty($q['_renamePeriods'])) {
+            $this->renamePeriods($roo);
+            $roo->jok("DONE");
+        }
+        if(!empty($q['_with_transactions'])){
+            $this->selectAdd("
+                (
+                    SELECT 
+                            COUNT(gltrans_id)
+                    FROM
+                            gltrans
+                    WHERE
+                            (gltrans_date BETWEEN period_start AND period_end)
+                            AND
+                            (NOT gltrans_deleted)
+                            AND
+                            gltrans_posted
+                ) AS transactions
+            ");
+        }
+        if(!empty($q['_status'])){
+            switch ($q['_status']){
+                case 'O' :
+                    $this->period_closed = FALSE;
+                    break;
+                case 'C' :
+                    $this->period_closed = TRUE;
+                    break;
+                default :
+                    break;
+            }
+        }
+        
+        
+    }
+    
+    function initDatabase($roo)
+    {
+        $this->initPeriods($roo);
+    }
+    
+    
+    function initPeriods($roo)
+    {
+        
+        // should be configurable somewhere...
+        $db = substr($this->database(),-2);
+        switch($db) {
+            case 'au':
+                $start = '2006';
+                //HK: 1 May - 30 Apr
+                //SG: 1 Oct - 30 Sept
+                $sdate = '-07-01';
+                $edate = '-06-30';
+                break;
+            
+            case 'hk':
+            case 'cn':
+            case 'zh':
+            case 'my':
+                
+                $start = '2006';
+                //HK: 1 May - 30 Apr
+                //SG: 1 Oct - 30 Sept
+                $sdate = '-05-01';
+                $edate = '-04-30';
+                
+                break;
+            default:
+                $roo->jerr("not set up yet");
+        }
+        
+        
+        
+        $yp = DB_DataObject::factory('yearperiod');
+        
+        //DB_DataObject::debugLevel(1);
+        
+        for ($i = $start; $i < 2020;$i++ ) {
+            
+            
+             
+            // we should now have the period + id..
+            
+            for ($m=0; $m < 12; $m++) {
+                $ms = !$m ? ($i . $sdate) : date('Y-m-01', strtotime( $i . $sdate . ' + ' . $m . ' MONTHS' ));
+                $me = date('Y-m-d',strtotime( $ms .' + 1 MONTHS - 1 DAYS'));
+                
+                $p = DB_DataObject::factory('period');
+                $p->get('period_start', $ms);
+                     
+                $yp = $this->createYearPeriod($i, $sdate, $edate);
+                
+                $p->get('period_start', $ms);
+                
+                if ($p->period_closed || $p->period_freeze) {
+                    continue;
+                }
+                $end = date('Y-m-d',strtotime( "$ms + 1 MONTH - 1 DAY"));
+                
+                $p->setFrom(array(
+                    'period_closed' => false,
+                    'period_freeze' => false,
+                    'period_end' => $end,
+                    //'period_initial       | t
+                    'period_name'          =>  date('Y-m', strtotime($ms)) .' '. date('M', strtotime($ms)),
+                    'period_yearperiod_id'  => $yp->yearperiod_id,
+                    'period_quarter'   => floor($m/3) + 1,
+                    'period_number'  => $m + 1
+                ));
+                $p->period_id ? $p->update() : $p->insert();
+                
+            }
+          
+            
+            
+        }
+          
+        
+    }
+    function createYearPeriod($i, $sdate, $edate)
+    {   
+        $yp = DB_DataObject::factory('yearperiod');
+        if ( $yp->get('yearperiod_start', $i.$sdate)) {
+            return $yp;
+        }
+        $yp = DB_DataObject::factory('yearperiod');
+        $ni = $i+1;
+        $yp->whereAdd("yearperiod_start >= '{$i}-01-01' AND yearperiod_start < '{$ni}-01-01'");
+        $yp->limit(1);
+        $yp->find(true);
+        
+        $yp->setFrom(array(
+            'yearperiod_start' => $i . $sdate,
+            'yearperiod_end' => ($i+1) . $edate,
+            'yearperiod_closed' => false,
+        ));
+        if (!empty($yp->yearperiod_id)) {
+            $yp->update();
+        } else { 
+            $yp->insert();
+        }
+        return $yp;
+    }
+    
+    function renamePeriods()
+    {
+        $p = DB_DataObject::factory($this->tableName());
+        //$p->whereAdd("period_name not like  '____-__ %'");
+        $all = $p->fetchAll();
+        foreach($all as $p) {
+            $pp = clone($p);
+            
+            $yp = $p->yearperiod();
+            $fy = date('Y', strtotime($yp->yearperiod_start));
+            $fe = date('Y', strtotime($yp->yearperiod_end));
+            $fy_name = "(FY {$fy} - {$fe})";
+            
+            $ms = $p->period_start;
+            
+            $p->period_name = date('Y-m', strtotime($ms)) .' '. date('M', strtotime($ms)) . ' ' . $fy_name ;
+            $p->update($pp);
+        }
+        
+    }
+    
+    function isClosed($date)
+    {
+        $date = date('Y-m-d',strtotime($date));
+        $p = DB_DataObject::Factory('period');
+        $p->whereAdd("'{$date}' BETWEEN period_start AND period_end");
+        $p->find(true);
+        return ($p->period_closed || $p->period_freeze ) ? true : false;
+        
+    }
+    
+    function firstOpen()
+    {
+        $p = DB_DataObject::Factory('period');
+        $p->orderBy('period_start ASC');
+        $p->limit(1);
+        $p->period_closed = 0;
+        $p->period_freeze = 0;
+        $p->find(true);
+        return $p;
+    }
+    
+    function createPeriod($y)
+    {
+        $db = substr($this->database(),-2);
+        switch($db) {
+            case 'au':
+                $sdate = '-07-01';
+                $edate = '-06-30';
+                break;
+            
+            case 'hk':
+            case 'cn':
+            case 'my':
+                
+                $sdate = '-05-01';
+                $edate = '-04-30';
+                break;
+            default:
+                HTML_FlexyFramework::get()->page->jerr("not set up yet");
+        }
+        
+        $yp = $this->createYearPeriod($y, $sdate, $edate);
+        
+        for ($m=0; $m < 12; $m++) {
+            $ms = !$m ? ($y . $sdate) : date('Y-m-01', strtotime( $y . $sdate . ' + ' . $m . ' MONTHS' )); // period_start
+            $me = date('Y-m-d',strtotime( $ms .' + 1 MONTHS - 1 DAYS')); // period_end
+            
+            $p = DB_DataObject::factory('period');
+            $p->get('period_start', $ms);
+
+            if ($p->period_closed || $p->period_freeze) {
+                continue;
+            }
+            
+            $p->setFrom(array(
+                'period_closed' => false,
+                'period_freeze' => false,
+                'period_start' => $ms,
+                'period_end' => $me,
+                'period_name'          =>  date('Y', strtotime($ms)) .' '. date('M', strtotime($ms)),
+                'period_yearperiod_id'  => $yp->yearperiod_id,
+                'period_quarter'   => floor($m/3) + 1,
+                'period_number'  => $m + 1
+            ));
+            $p->period_id ? $p->update() : $p->insert();
+
+        }
+        
+        
+    }
+    
+    function beforeInsert($q,$roo)
+    {
+        if(isset($q['_group'])){
+            $roo->jerr("not supported");
+            
+            $list = json_decode($q['_group'], true);
+            foreach ($list as $l){
+                $period = DB_DataObject::factory('period');
+                if(!$period->get($l['period_id'])){
+                    $roo->jerr("Can not found the period id : {$l['period_id']}");
+                }
+                $period->close($roo);
+            }
+            $roo->jok("CLOSED");
+        }
+        
+        if(isset($q['_addExtraYear'])){
+            $yearperiod = DB_DataObject::factory('yearperiod');
+            $yearperiod->selectAdd();
+            $yearperiod->selectAdd("
+                (EXTRACT(year FROM MAX(yearperiod_end))) AS next_year
+            ");
+            $yearperiod->find(true);
+            $this->createPeriod($yearperiod->next_year);
+            $roo->jok("ADDED");
+        }
+    }
+    
+    function beforeUpdate($old, $q,$roo)
+    {
+        
+        $valid_actions = array('open','close','freeze','thaw');
+        
+        if(!empty($q['_action'])) {
+            if (!in_array($q['_action'], $valid_actions)) {
+                $roo->jerr("invalid action");
+            }
+            
+            $method = $q['_action'];
+            
+            
+            $this->$method($roo);
+            
+            if(!empty($q['_second_action']) && in_array($q['_second_action'], $valid_actions)) {
+                $method = $q['_second_action'];
+                $this->$method($roo);
+            }
+            
+            
+            $roo->jok("oops");
+        }
+        
+    }
+    
+    /*
+     * open the period
+     */
+    function open($roo)
+    {
+        $period = DB_DataObject::factory('period');
+        $period->query("SELECT openAccountingPeriod({$this->period_id}) AS result");
+        $period->fetch();
+        if($period->result < 0){
+            switch ($period->result){
+                case -1 :
+                    $roo->jerr("This period is already open! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -2 :
+                    $roo->jerr("This period is frozen! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -3 :
+                    $roo->jerr("Some period after this period have been closed! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -4 :
+                    $roo->jerr("This yearperiod of this period has been closed! name : {$this->period_name} result : {$period->result}");
+                default :
+                    $roo->jerr("Error occur on open accounting period! name : {$this->period_name} result : {$period->result}");
+                    break;
+            }
+        }
+    }
+    
+    /*
+     * close the period
+     */
+    function close($roo)
+    {
+       
+        
+        $period = DB_DataObject::factory('period');
+        $period->query("SELECT closeAccountingPeriod({$this->period_id}) AS result");
+        $period->fetch();
+        if($period->result < 0){
+            switch ($period->result){
+                case -1 :
+                    $roo->jerr("This period is already close! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -2 :
+                    $roo->jerr("The day before this period is not belongs to another period! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -3 :
+                    $roo->jerr("Pervious period is not closed! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -4 :
+                    $roo->jerr("Next period is not defined! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -5 :
+                    $roo->jerr("Prematurely close this period! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -6 : 
+                    $roo->jerr("Can not found the yearperiod of the next period! name : {$this->period_name} result : {$period->result}");
+                    break;
+                default :
+                    $roo->jerr("Error occur on close accounting period! name : {$this->period_name} result : {$period->result}");
+                    break;
+            }
+        }
+       
+        return true;
+    }
+    
+    /*
+     * freeze the period
+     */
+    function freeze($roo)
+    {
+        $period = DB_DataObject::factory('period');
+        $period->query("SELECT freezeAccountingPeriod({$this->period_id}) AS result");
+        $period->fetch();
+        if($period->result < 0){
+            switch ($period->result){
+                case -1 :
+                    $roo->jerr("This period is still open! name : {$this->period_name} result : {$period->result}");
+                    break;
+                case -2 :
+                    $roo->jerr("This period is already frozen! name : {$this->period_name} result : {$period->result}");
+                    break;
+                default :
+                    $roo->jerr("Error occur on close accounting period! name : {$this->period_name} result : {$period->result}");
+                    break;
+            }
+        }
+    }
+    
+    /*
+     * thaw the period
+     */
+    function thaw($roo)
+    {
+        $period = DB_DataObject::factory('period');
+        $period->query("SELECT thawAccountingPeriod({$this->period_id}) AS result");
+        $period->fetch();
+        if($period->result < 0){
+            switch ($period->result){
+                case -2 :
+                    $roo->jerr("This period is not frozen! name : {$this->period_name} result : {$period->result}");
+                    break;
+                default :
+                    $roo->jerr("Error occur on close accounting period! name : {$this->period_name} result : {$period->result}");
+                    break;
+            }
+        }
+    }
+}
diff --git a/DataObjects/Person.php b/DataObjects/Person.php
new file mode 100644 (file)
index 0000000..2b681cf
--- /dev/null
@@ -0,0 +1,389 @@
+<?php
+/*
+ this is a wrapper around the standard person object.
+ the point is
+ a) any update / delete / insert
+  = needs to modify the postgres authentication table.
+  
+ b) login needs to change the active postgress user..
+    
+*/
+
+require_once 'Pman/Core/DataObjects/Person.php';
+
+class Pman_Xtuple_DataObjects_Person extends Pman_Core_DataObjects_Person {
+    
+    
+    ###START_AUTOCODE
+    ###END_AUTOCODE
+
+    function isAuth()
+    {
+        static $auser = false;
+        $r = parent::isAuth();
+        if (!$r) {
+            return $r;
+        }
+        // only do this once per request..
+        $name = $this->pgname();
+        if ($auser == $name) {
+            return $r;
+        }
+        // change the postgres user..
+        $p = DB_DataObject::factory('Person');
+        // first see if a record exists..
+        
+        
+        $p->query("SELECT oid FROM pg_catalog.pg_authid WHERE rolname = '$name'");
+        if (!$p->fetch()) {
+            $this->syncUser();
+        }
+        
+        // we should now have a valid user..
+        $this->query("SET SESSION AUTHORIZATION '{$name}'");
+        $auser=  $name;
+        return $r;
+        
+    }
+    
+    
+    function beforeDelete($ar) {
+        
+        $this->err = "Deleting users is not permitted = do it via the main interface..";
+        return false;
+        
+    }
+    
+    function onUpdate($old, $request,$roo)
+    {
+        
+        // if old email != new email!!!! = we are in trouble..
+        
+        $this->syncUser();
+        // parent does not implement this..
+         
+        
+    }
+    function onInsert($request,$roo) 
+    {
+        $this->syncUser();
+         
+        
+    }
+    function pgname()
+    {
+        $name = strtolower(array_shift(explode('@', $this->email)));
+        return preg_replace('/[^a-z]+/i', '', $name);
+        
+    }
+    
+    function emp()
+    {
+        $emp = DB_DataObject::Factory('emp');
+        if ($emp->get('emp_code', strtoupper($this->pgname()))) {
+            return $emp;
+        }
+        $emp = DB_DataObject::Factory('emp');
+        // if we do not have one.. see if there is a bug..
+        if ($emp->get('emp_number', 'p-'. $this->id)) {
+            $old = clone($emp);
+            $emp->emp_code =  strtoupper($this->pgname());
+            $emp->update($old);
+            
+            return $emp;
+        }
+        
+        return  DB_DataObject::Factory('emp');
+    }
+    
+    
+    function cntct()
+    {
+        
+        $emp = DB_DataObject::Factory('emp');
+        if (!$emp->get('emp_code', strtoupper($this->pgname()))) {
+            // make emp?
+            $cntct = DB_DataObject::Factory('cntct');
+            if (!$cntct->get('cntct_email', $this->email)) {
+                $cntct = DB_DataObject::Factory('cntct');
+                
+                if (!$cntct->get('cntct_number', 'p-'. $this->id)) {
+                
+                    $cntct = DB_DataObject::Factory('cntct');
+                    $cntct->setFrom(array(
+                        'cntct_email' => $this->email,
+                        'cntct_number' => 'p-'. $this->id,
+                    
+                    ));
+                  
+                    $cntct->insert();
+                }  
+            }
+            $emp = $this->emp();
+            //create an employeee..
+            $emp = DB_DataObject::Factory('emp');
+            //DB_DataObject::DebugLevel(1);
+            if (!$emp->get('emp_code', strtoupper($this->pgname()))) {
+                $emp = DB_DataObject::Factory('emp');
+                //print_R($emp->keys());
+                $emp->setFrom(array(
+                
+                    'emp_code' =>  strtoupper($this->pgname()),
+                    'emp_name' =>  $this->pgname(),
+                    'emp_number' => 'p-'. $this->id,
+                    'emp_active' => true,
+                    'emp_cntct_id' => $cntct->cntct_id,
+                    //'emp_warehous_id' =>  -1,
+                    //'emp_mgr_emp_id' =>  -1,
+                    'emp_wage_type' =>  'S',
+                    'emp_wage' =>  0,
+                    //'emp_wage_curr_id' =>  integer DEFAULT basecurrid(),
+                    'emp_wage_period' =>  'M',
+                    //'emp_dept_id' =>  -1,
+                    //'emp_shift_id' =>  -1,
+                    'emp_notes' => '', 
+                    //'emp_image_id' integer,
+                    'emp_username' => $this->pgname(),
+                    'emp_extrate' => 0,
+                    'emp_extrate_period'=>'M'
+                    //'emp_startdate date D
+                                    
+                ));
+                $emp->insert();
+                // this should update salesrep..
+            }
+            return $cntct;
+            
+        }
+        
+        
+        // got emplyer..
+        return $emp->cntct();
+        //return the  cntct record for this person.
+        
+        
+    }
+    function salesrep()
+    {
+        $do = DB_DataObject::factory('salesrep');
+        if ($do->get('salesrep_number', strtoupper($this->pgname()))) {
+            // trash sales rep, if emplyee is not linked..
+            //echo '<PRE>'; print_R($do);exit;
+            
+            if ($do->salesrep_name != $this->name) {
+                // sync the names..
+                $dd = DB_DataObject::factory('salesrep');
+                $dd->query("
+                    UPDATE
+                        salesrep
+                    SET
+                        salesrep_name = '{$this->escape($this->name)}'
+                    WHERE
+                        salesrep_id = {$do->salesrep_id}
+                ");
+            }
+            
+            
+            if ($do->salesrep_emp_id) {
+                return $do;
+            }
+            
+            $emp = $this->emp();
+            if (!$emp->emp_id) {
+                $do->delete();
+                return  DB_DataObject::factory('salesrep');
+            }
+            $dd = clone($do);
+            $do->salesrep_emp_id = $emp->pid();
+            $do->update($dd);
+            return $do;
+            
+             
+            
+        }
+        
+    
+         // what
+         //DB_DataObject::debugLevel(1);
+         $cntct = $this->cntct(); // should create 'emp' if not exist..
+         
+         $emp = $this->emp(); 
+         $sr = DB_DataObject::factory('salesrep');
+         if ($sr->get('salesrep_number', strtoupper($this->pgname()))) {
+             $sr->delete();
+         }
+         
+         
+        
+         $sr->setFrom(array(
+             'salesrep_active' =>  true,
+             'salesrep_number' => strtoupper($this->pgname()),
+             'salesrep_name' =>  $this->name,
+             //'salesrep_commission' =>  0.0,
+             'salesrep_method ' => '',
+             'salesrep_emp_id' =>$emp->emp_id,
+             'salesrep_commission' => 2
+         ));
+
+         $sr->insert();
+            
+         
+        return $sr;
+        
+        //return  DB_DataObject::factory('salesrep');
+    }
+    
+    
+    function authUserArray()
+    {
+        
+        $aur = parent::authUserArray();
+        
+        // need sales
+        // emp
+        //DB_DataObject::DebugLevel(1);
+        $this->syncUser();
+       
+        $sr = $this->salesrep();
+        // echo '<PRE>'; print_R($sr);exit;
+            // generate a salesrep..
+        if (!$sr->salesrep_id) {
+            // what
+            //DB_DataObject::debugLevel(1);
+            $cntct = $this->cntct(); // should create 'emp' if not exist..
+            
+            $emp = $this->emp(); 
+            
+            if ($sr->get('salesrep_number', strtoupper($this->pgname()))) {
+                $sr->delete();
+            }
+            
+            $sr = $this->salesrep();
+           
+            $sr->setFrom(array(
+                'salesrep_active' =>  true,
+                'salesrep_number' => strtoupper($this->pgname()),
+                'salesrep_name' =>  $this->name,
+                'salesrep_commission' =>  0.0,
+                'salesrep_method ' => '',
+                'salesrep_emp_id' =>$emp->emp_id,
+            ));
+  
+            $sr->insert();
+            
+        }
+        
+        
+      
+        $aur['dbname'] = strtoupper(substr($this->database(), -2));
+        
+        
+        
+        $aur['salesrep'] = $sr->toArray();
+        return $aur;
+    }
+    
+    
+    
+    function syncUser()
+    {
+           // parent does not implement this..
+        $p = DB_DataObject::factory('Person');
+        // first see if a record exists..
+        $name = $this->pgname();
+        
+        $p->query("SELECT oid FROM pg_catalog.pg_authid WHERE rolname = '$name'");
+        
+        if ($p->fetch()) {
+            // got it..
+            if (!empty($this->passwd_raw)) {
+               $pw = $this->escape($this->passwd_raw);
+               $p->query("ALTER USER $name WITH PASSWORD '{$pw}'");
+                
+            }
+            
+        } else {
+            if (!empty($this->passwd_raw)) { 
+                $pw = $this->escape($this->passwd_raw);
+                $p->query("CREATE USER $name WITH PASSWORD '{$pw}'");
+            } else {
+                $p->query("CREATE USER $name");
+            }
+            
+            
+        }
+        
+        // add them to a group..
+        
+        $p->query("ALTER GROUP xtrole ADD USER $name");
+        
+        
+        
+        // need more groups!!
+        $x = DB_DataObject::Factory('usrgrp');
+        $x->syncGroups($this);
+         
+        
+        // Prefs..
+        $x = DB_DataObject::Factory('usrpref');
+        $x->usrpref_username = $name;
+        if (!$x->count()) {
+            $f = DB_DataObject::Factory('usrpref');
+            $f->usrpref_username = 'admin'; // default later??
+            $all = $f->fetchAll();
+            
+            foreach($all as $d) {
+                $f = DB_DataObject::Factory('usrpref');
+                $f->setFrom($d);
+                $f->usrpref_username  = $name;
+                if (!$f->count()) {
+                    $f->insert();
+                }
+            }
+        }
+        // make sure they have a sales rep record..
+        $this->salesrep();
+        
+        
+        /*
+        priv's are handled by groups.
+        
+        $x = DB_DataObject::Factory('usrpriv');
+        $x->usrpriv_username = $name;
+        if (!$x->count()) {
+        
+            // give all prev
+            $f = DB_DataObject::Factory('usrpriv');
+            $f->usrpriv_username = 'admin'; // default later??
+            $all = $f->fetchAll();
+             
+            
+            foreach($all as $d) {
+                $f = DB_DataObject::Factory('usrpriv');
+                $f->setFrom($d);
+                $f->usrpriv_username  = $name;
+                $f->insert();
+            }
+            
+            
+        }
+        */
+        
+        
+    }
+    
+    // set password..
+    
+    function setPassword($value) 
+    {
+        parent::setPassword($value);
+        $this->passwd_raw = $value;
+       
+       
+    }  
+    
+}
\ No newline at end of file
diff --git a/DataObjects/Pkgdep.php b/DataObjects/Pkgdep.php
new file mode 100644 (file)
index 0000000..8799d48
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Table Definition for pkgdep
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pkgdep extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pkgdep';              // table name
+    public $pkgdep_id;                       // int4(4)  not_null default_nextval%28pkgdep_pkgdep_id_seq%29 primary_key
+    public $pkgdep_pkghead_id;               // int4(4)  not_null
+    public $pkgdep_parent_pkghead_id;        // int4(4)  not_null
+
+    
+   /**
+    * Getter / Setter for $pkgdep_parent_pkghead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent_pkghead() {
+        return func_num_args() ? $this->link('pkgdep_parent_pkghead_id', func_get_arg(0)) : $this->link('pkgdep_parent_pkghead_id');
+    }
+
+   /**
+    * Getter / Setter for $pkgdep_pkghead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function pkghead() {
+        return func_num_args() ? $this->link('pkgdep_pkghead_id', func_get_arg(0)) : $this->link('pkgdep_pkghead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Pkghead.php b/DataObjects/Pkghead.php
new file mode 100644 (file)
index 0000000..6dce6f3
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for pkghead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pkghead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pkghead';             // table name
+    public $pkghead_id;                      // int4(4)  not_null default_nextval%28pkghead_pkghead_id_seq%29 primary_key
+    public $pkghead_name;                    // text(-1)  not_null
+    public $pkghead_descrip;                 // text(-1)  
+    public $pkghead_version;                 // text(-1)  not_null
+    public $pkghead_developer;               // text(-1)  not_null
+    public $pkghead_notes;                   // text(-1)  
+    public $pkghead_created;                 // timestamptz(8)  
+    public $pkghead_updated;                 // timestamptz(8)  
+    public $pkghead_indev;                   // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Pkgitem.php b/DataObjects/Pkgitem.php
new file mode 100644 (file)
index 0000000..6643e6a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Table Definition for pkgitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pkgitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pkgitem';             // table name
+    public $pkgitem_id;                      // int4(4)  not_null default_nextval%28pkgitem_pkgitem_id_seq%29 primary_key
+    public $pkgitem_pkghead_id;              // int4(4)  unique_key multiple_key unique_key multiple_key
+    public $pkgitem_type;                    // text(-1)  unique_key multiple_key unique_key multiple_key
+    public $pkgitem_item_id;                 // int4(4)  not_null unique_key multiple_key
+    public $pkgitem_name;                    // text(-1)  not_null unique_key multiple_key
+    public $pkgitem_descrip;                 // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $pkgitem_pkghead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function pkghead() {
+        return func_num_args() ? $this->link('pkgitem_pkghead_id', func_get_arg(0)) : $this->link('pkgitem_pkghead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Plancode.php b/DataObjects/Plancode.php
new file mode 100644 (file)
index 0000000..878e442
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Table Definition for plancode
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Plancode extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'plancode';            // table name
+    public $plancode_id;                     // int4(4)  not_null default_nextval%28%28plancode_plancode_id_seq%29%3A%3Aregclass%29 primary_key
+    public $plancode_code;                   // text(-1)  unique_key
+    public $plancode_name;                   // text(-1)  
+    public $plancode_mpsexplosion;           // bpchar(-1)  
+    public $plancode_consumefcst;            // bool(1)  
+    public $plancode_mrpexcp_resched;        // bool(1)  
+    public $plancode_mrpexcp_delete;         // bool(1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function initDatabase()
+    {
+        $pc = $this->factory($this->tableName());
+        if ($pc->get('plancode_code', 'REGULAR')) {
+            return;
+        }
+        $pc = $this->factory($this->tableName());
+        $pc->setFrom(array(
+            //itemloc_id  
+            'plancode_code' => 'REGULAR',
+            'plancode_name' => 'Regular',
+            'plancode_mpsexplosion' => 'N',
+            'plancode_consumefcst' => false
+            
+        ));
+        $pc->insert();
+         
+        
+        
+        
+    }
+    
+}
diff --git a/DataObjects/Pohead.php b/DataObjects/Pohead.php
new file mode 100644 (file)
index 0000000..7214185
--- /dev/null
@@ -0,0 +1,1099 @@
+<?php
+/**
+ * Table Definition for pohead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pohead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pohead';              // table name
+    public $pohead_id;                       // int4(4)  not_null default_nextval%28%28pohead_pohead_id_seq%29%3A%3Aregclass%29 primary_key
+    public $pohead_status;                   // bpchar(-1)  
+    public $pohead_number;                   // text(-1)  unique_key
+    public $pohead_orderdate;                // date(4)  
+    public $pohead_vend_id;                  // int4(4)  
+    public $pohead_fob;                      // text(-1)  
+    public $pohead_shipvia;                  // text(-1)  
+    public $pohead_comments;                 // text(-1)  
+    public $pohead_freight;                  // numeric(-1)  default_0
+    public $pohead_printed;                  // bool(1)  default_false
+    public $pohead_terms_id;                 // int4(4)  
+    public $pohead_warehous_id;              // int4(4)  
+    public $pohead_vendaddr_id;              // int4(4)  
+    public $pohead_agent_username;           // text(-1)  
+    public $pohead_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $pohead_saved;                    // bool(1)  not_null default_true
+    public $pohead_taxzone_id;               // int4(4)  
+    public $pohead_taxtype_id;               // int4(4)  
+    public $pohead_dropship;                 // bool(1)  default_false
+    public $pohead_vend_cntct_id;            // int4(4)
+    
+    
+    public $pohead_vend_cntct_honorific;     // text(-1)  
+    public $pohead_vend_cntct_first_name;    // text(-1)  
+    public $pohead_vend_cntct_middle;        // text(-1)  
+    public $pohead_vend_cntct_last_name;     // text(-1)  
+    public $pohead_vend_cntct_suffix;        // text(-1)  
+    public $pohead_vend_cntct_phone;         // text(-1)  
+    public $pohead_vend_cntct_title;         // text(-1)  
+    public $pohead_vend_cntct_fax;           // text(-1)  
+    public $pohead_vend_cntct_email;         // text(-1)  
+    public $pohead_vendaddress1;             // text(-1)  
+    public $pohead_vendaddress2;             // text(-1)  
+    public $pohead_vendaddress3;             // text(-1)  
+    public $pohead_vendcity;                 // text(-1)  
+    public $pohead_vendstate;                // text(-1)  
+    public $pohead_vendzipcode;              // text(-1)  
+    public $pohead_vendcountry;              // text(-1)  
+    public $pohead_shipto_cntct_id;          // int4(4)  
+    public $pohead_shipto_cntct_honorific;    // text(-1)  
+    public $pohead_shipto_cntct_first_name;    // text(-1)  
+    public $pohead_shipto_cntct_middle;      // text(-1)  
+    public $pohead_shipto_cntct_last_name;    // text(-1)  
+    public $pohead_shipto_cntct_suffix;      // text(-1)  
+    public $pohead_shipto_cntct_phone;       // text(-1)  
+    public $pohead_shipto_cntct_title;       // text(-1)  
+    public $pohead_shipto_cntct_fax;         // text(-1)  
+    public $pohead_shipto_cntct_email;       // text(-1)  
+    public $pohead_shiptoddress_id;          // int4(4)  
+    public $pohead_shiptoaddress1;           // text(-1)  
+    public $pohead_shiptoaddress2;           // text(-1)  
+    public $pohead_shiptoaddress3;           // text(-1)  
+    public $pohead_shiptocity;               // text(-1)  
+    public $pohead_shiptostate;              // text(-1)  
+    public $pohead_shiptozipcode;            // text(-1)  
+    public $pohead_shiptocountry;            // text(-1)  
+    public $pohead_cohead_id;                // int4(4)  
+    public $pohead_released;                 // date(4)  
+    
+    public $pohead_location_id;              // int
+    public $pohead_bg_va;                   // date
+    public $pohead_bg_arrival_est_day;      // date
+    public $pohead_bg_available_est_day;    // date
+    public $pohead_bg_available_latest_day;  // date
+    public $pohead_notes;                   // TEXT
+    //public $pohead_last_updated;            // date
+    
+
+    
+   /**
+    * Getter / Setter for $pohead_cohead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cohead() {
+        return func_num_args() ? $this->link('pohead_cohead_id', func_get_arg(0)) : $this->link('pohead_cohead_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_shipto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipto_cntct() {
+        return func_num_args() ? $this->link('pohead_shipto_cntct_id', func_get_arg(0)) : $this->link('pohead_shipto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_shiptoddress_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shiptoddress() {
+        return func_num_args() ? $this->link('pohead_shiptoddress_id', func_get_arg(0)) : $this->link('pohead_shiptoddress_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('pohead_taxtype_id', func_get_arg(0)) : $this->link('pohead_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('pohead_taxzone_id', func_get_arg(0)) : $this->link('pohead_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_terms_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function terms() {
+        return func_num_args() ? $this->link('pohead_terms_id', func_get_arg(0)) : $this->link('pohead_terms_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_vend_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vend_cntct() {
+        return func_num_args() ? $this->link('pohead_vend_cntct_id', func_get_arg(0)) : $this->link('pohead_vend_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_vend_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vend() {
+        return func_num_args() ? $this->link('pohead_vend_id', func_get_arg(0)) : $this->link('pohead_vend_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_vendaddr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vendaddr() {
+        return func_num_args() ? $this->link('pohead_vendaddr_id', func_get_arg(0)) : $this->link('pohead_vendaddr_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('pohead_warehous_id', func_get_arg(0)) : $this->link('pohead_warehous_id');
+    }
+
+   /**
+    * Getter / Setter for $pohead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('pohead_curr_id', func_get_arg(0)) : $this->link('pohead_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function applyFilters( $q, $au, $roo)
+    {
+        $this->joinAddLocation();
+        
+        if (!empty($q['_with_recv'])) {
+            $this->applyFiltersRecv($q,$au, $roo);
+        }
+        if (!empty($q['query']['number'])) {
+            $v = $this->escape($q['query']['number']);
+            $this->whereAdd("
+                pohead_number ilike '%$v%' OR
+                pohead_comments ilike '%$v%' OR
+                join_pohead_vend_id_vend_id.vend_name ilike '%$v%' 
+              
+            ");
+            
+        }
+        
+    }
+    function applyFiltersRecv($q, $au, $roo)
+    {
+        // not a good way to do this.
+        $tx_id  = 0;
+        $loc = DB_DataObject::Factory('location');
+        if ($loc->get('location_name', 'Import Goods in Transit')) {
+            $tx_id = $loc->pid();
+        }
+        
+        $this->selectAdd("
+            (SELECT sum(poitem_qty_ordered)
+                    FROM
+                        poitem
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        itemsite_id = poitem_itemsite_id
+                    LEFT JOIN
+                        item
+                    ON
+                        item_id = itemsite_item_id
+                    WHERE
+                        poitem_pohead_id = pohead_id
+                        AND
+                        item_type = 'P'
+                    ) as pohead_qty,
+                    
+                    
+                    
+            (SELECT sum(poitem_qty_received - poitem_qty_returned) FROM poitem where poitem_pohead_id = pohead_id) as pohead_qty_recv,
+            (SELECT sum(poitem_unitprice * poitem_qty_ordered) FROM poitem where poitem_pohead_id = pohead_id) as pohead_val,
+            
+            -- transit = delivered to Import 
+             COALESCE((
+                    SELECT
+                            sum(recv_qty)
+                        FROM
+                            recv
+                        LEFT JOIN
+                            recvgrp
+                        ON
+                            recv_recvgrp_id = recvgrp_id
+                        WHERE
+                            recvgrp_pohead_id = pohead_id
+                        AND
+                            recvgrp_location_id = $tx_id
+                        AND
+                            recv_posted
+                        AND
+                            recvgrp_void != 1
+                            
+            ),0) as  pohead_qty_in_transit,
+          
+            COALESCE((SELECT SUM(invhist_transfer_item_qty)
+                FROM
+                    invhist_transfer_item
+                LEFT JOIN 
+                    invhist_transfer
+                ON
+                    invhist_transfer_item_invhist_transfer_id = invhist_transfer_id
+                LEFT JOIN
+                    recvgrp
+                ON
+                    invhist_transfer_recvgrp_id = recvgrp_id
+                    
+                WHERE
+                    invhist_transfer_id IS NOT NULL
+                    AND
+                    invhist_transfer_item_invhist_transfer_id IS NOT NULL
+                    AND
+                    invhist_transfer_posted = true
+                    AND 
+                    recvgrp_pohead_id = pohead_id 
+                    
+                     
+            ),0) as pohead_qty_transfered,
+            
+            COALESCE((SELECT SUM(invhist_transfer_item_qty)
+                FROM
+                    invhist_transfer_item
+                LEFT JOIN 
+                    invhist_transfer
+                ON
+                    invhist_transfer_item_invhist_transfer_id = invhist_transfer_id
+                LEFT JOIN
+                    recvgrp
+                ON
+                    invhist_transfer_recvgrp_id = recvgrp_id
+                    
+                WHERE
+                    invhist_transfer_id IS NOT NULL
+                    AND
+                    invhist_transfer_item_invhist_transfer_id IS NOT NULL
+                    AND
+                    invhist_transfer_posted = false
+                    AND 
+                    recvgrp_pohead_id = pohead_id 
+                    
+                     
+            ),0) as pohead_qty_transfered_unposted
+                        
+            
+                        
+        ");
+        // landed cost.
+         $this->selectAdd("
+            ROUND ((SELECT
+                    sum(
+                        currtocurr(recvgrpland_curr_id, pohead_curr_id,
+                                recvgrpland_cost, gltrans_date)
+                    )
+                FROM
+                    recvgrpland
+                LEFT JOIN
+                    gltrans
+                ON
+                    gltrans_sequence = recvgrpland_glseries
+                    AND
+                    gltrans_amount > 0
+                LEFT JOIN
+                    recvgrp
+                ON
+                    recvgrpland_recvgrp_id = recvgrp_id
+                WHERE
+                    recvgrp_pohead_id = pohead_id
+                    
+            ),2) as landed_cost,
+            
+            0 as landed_missing
+                
+        ");
+    }
+    function beforeInsert($q,$roo)
+    { 
+        if(empty($this->pohead_number ) || $this->pohead_number == 'Automatic'){
+            foreach ($this->checkDefaults() as $k => $v){
+                if (!isset($this->$k)) {
+                    $this->$k = $v;
+                }
+            }
+            $this->pohead_number = $this->sqlValue("(SELECT fetchPoNumber())");
+        }
+        
+        if (!empty($q['_is_xfer'])) {
+            $this->factory('cohead')->lockTables();
+            // just create the raw data..
+            return $this->createFromXfer($q,$roo);
+        }
+        
+     
+    }
+    /**
+     * used by inventory transfer -
+     *
+     * IT does local -> remote.
+     *
+     * So it remotely creates a transfer by calling this.
+     * The source transfer knows all the prices, so this does not have to caluclate anything.
+     *
+     *  PO creation Transfers are done in two parts, before insert and after insert.
+     *  this is the 'before' part..' - see afterInsertFromXfer for the rest of it.
+     * 
+     *
+     */
+    
+    function createFromXfer($q,$roo)
+    {
+        
+        //if ($q['_is_xfer']  != 'test') {
+        //    file_put_contents('/tmp/xfertest', serialize($q));
+        //    $roo->jerr("testing file saved");
+        //} else {
+        //    $q=  unserialize(file_get_contents('/tmp/xfertest'));
+        //    $this->setFrom($q);
+        //}
+        //
+        
+        
+        if (empty($q['_vendor_internal_company'])) {
+                $roo->jerr("invalid source company");
+        }
+        
+        $po  = DB_DataObject::Factory('pohead');
+        if ($po->get('pohead_number', $q['pohead_number'])) {
+            $roo->jerr("purchase order already exists");
+        }
+        
+        
+        $cur = DB_DataObject::Factory('curr_symbol');
+        $cur->get('curr_name', $q['curr_name']);
+       
+        
+        // find the company.
+        $v = DB_DataObject::factory('vendinfo');
+        $v = $v->findInternal($q['_vendor_internal_company'], $cur);
+        if (!$v) {
+            $roo->jerr("Could not find vendor for internal company: " .
+                        $q['_vendor_internal_company'] .'/' . $q['curr_name']);
+        }
+        
+        $taxtype  = DB_DataObject::Factory('taxtype');
+        $taxtype->get('taxtype_name', 'Taxfree');
+        
+        $taxzone = DB_DataObject::Factory('taxzone'); // we use vend info..
+        $taxzone->get('taxzone_code', 'NO TAX');
+        
+        $this->setFrom($this->defaults());
+        
+        $this->setFrom(array(
+                             
+            'pohead_vend_id' => $v->pid(),
+                             
+             'pohead_terms_id' => $v->vend_terms_id,
+            //'pohead_freight' => 'total',
+           // 'pohead_released' =>  $q['->cohead_orderdate, /// filled from post..
+            
+            'pohead_curr_id' => $cur->pid(),
+             
+            'pohead_ordercomments' => 'Purchase order for Transfer : ' . $q['invhist_transfer_number'],
+            
+            
+            'pohead_taxzone_id' => $v->vend_taxzone_id,
+            'pohead_taxtype_id' => $taxtype->pid(),
+            
+        ));
+        
+        $this->vend_cntct($v->vend_cntct1_id);
+        $this->vendaddr($v->vend_addr_id);
+        $this->fillDetails();
+    
+    
+        
+        
+    }
+    
+    function afterInsertFromXfer($q,$roo)
+    {
+        //if ($q['_is_xfer']  != 'test') {
+        //     
+        //    $roo->jerr("testing raw disabled");
+        //}
+        //$q=  unserialize(file_get_contents('/tmp/xfertest'));
+            // add the items...
+        $items = json_decode($q['items']);
+        
+        $loc = DB_DataObject::Factory('location');
+        if (!$loc->get('location_name', $q['target_location'])) {
+            $roo->jerr("invalid location sent");
+        }
+        
+        // fetch all the items first..
+        $codes = array();
+        foreach($items as $item) {
+            $codes[] = $item->item_number;
+        }
+        
+        $item = DB_DataObject::factory('item');
+        $item->joinAddItemSite();
+        $item->whereAddIn('item_number', $codes, 'string');
+        $badctl = array();
+        $badtype = array();
+        foreach($item->fetchAll() as $item ) {
+            $imap[$item->item_number] = $item;
+            if (!$item->item_itemsite_id_itemsite_loccntrl) {
+                $badctl[] = $item->item_number;
+            }
+            if (!in_array($item->item_type,array('P','O','M','T'))) { // check purchase type
+                $badtype[] = $item->item_number . ' ('. $item->item_type .')';
+            }
+        }
+        if (!empty($badctl)) {
+            $roo->jerr("These products are not set as Multiple Location control '". implode("', '", $badctl));
+        }
+        if (!empty($badtype)) {
+            $roo->jerr("These products are not valid for purchase'". implode("', '", $badtype));
+        }
+        
+        foreach($items as $item) {
+        
+            
+            $poitem = DB_DataObject::factory('poitem');
+            $poitem->poitem_pohead_id = $this->pid();
+            // if it's got a decimal place == eg. 4.5
+            
+            if (!isset($imap[$item->item_number])) {
+                $roo->jerr("could not find item:  {$item->item_number}");
+            }
+            
+            
+            
+            $poitem->setFromTransferItem($roo,$item, $this, $imap[$item->item_number]);
+            
+             
+            $poitem->insert();
+            $poitems[$poitem->poitem_id] = clone($poitem);
+            
+        }
+        
+      
+        // all items added now..
+        $recvg = DB_DataObject::Factory('recvgrp');
+        $recvg->createFromPO($roo, $this, $loc);
+        
+         // $roo->jerr("stop");
+        
+        // large transfers do not create the vocher.
+        // this will have to be done manually..
+        //if (count($items) < 100) {
+        // finally ??? create bill?
+        $vohead = DB_DataObject::Factory('vohead');
+        $vohead->createFromPO($roo, $this);
+        $vohead->post($roo);
+      //     $roo->jerr("stop");  
+        //}
+        
+    }
+    
+    
+    function onInsert($q,$roo)
+    {
+        if (!empty($q['_is_xfer'])) {
+            return $this->afterInsertFromXfer($q,$roo);
+            
+        }
+        
+     
+    }
+    
+    
+    function beforeUpdate($old, $request,$roo)
+    {
+        if(!empty($request['_del'])){
+            $v = DB_DataObject::factory($this->tableName());
+            $v->query("SELECT invfifo_voidvoucher('{$this->pohead_number}')");
+            $v->fetch();
+            
+            $roo->jok("DELETED");
+            
+        }
+        
+        if(!empty($request['_variance'])){
+            $v = DB_DataObject::factory($this->tableName());
+            $v->query("SELECT invfifo_addVariance_all('{$this->pohead_number}')");
+            $v->fetch();
+            $roo->jok("ADDED");
+            
+        }
+        
+        if(!empty($request['_unitcost'])){
+            $v = DB_DataObject::factory($this->tableName());
+            $v->query("SELECT invfifo_fixUnitCost('{$this->pohead_number}')");
+            $v->fetch();
+            $roo->jok("FIXED");
+            
+        }
+        
+        if (!empty($request['_unrelease'])) {
+            if ($old->pohead_status != 'O') {
+                $roo->jerr("purchase order is not open");
+            }
+            $oo = clone($old);
+            $old->pohead_status = 'U';
+            $old->update($oo);
+            $pi = DB_DAtaObject::Factory('poitem');
+            $pi->query("UPDATE poitem SET poitem_status = 'U' WHERE poitem_pohead_id = {$old->pid()}");
+            $roo->jok("UPDATED");
+        }
+        
+        if(!empty($request['_close'])){
+            if($old->pohead_status == 'C'){
+                $roo->jerr("purchase order is already closed");
+            }
+            $this->query("
+                SELECT 
+                    closePO({$this->pid()}) 
+                AS
+                    result
+            ");
+            $this->fetch();
+            if($this->result < 1){
+                $roo->jerr('close purchase order failed');
+            }
+            $roo->jok("CLOSED");
+        
+        }
+        
+        if(!empty($request['_reopen'])){
+            if($old->pohead_status == 'O'){
+                 $roo->jerr("purchase order is already Open");
+            }
+            $oo = clone($old);
+            $old->pohead_status = 'O';
+            $old->update($oo);
+            
+            $pi = DB_DAtaObject::Factory('poitem');
+            $pi->query("UPDATE poitem SET poitem_status = 'O' WHERE poitem_pohead_id = {$old->pid()}");
+            $roo->jok("REOPEN");
+            
+        }
+        
+        if(!empty($request['_print'])){
+            
+            $oo = clone($old);
+            $old->pohead_printed = true;
+            $old->update($oo);
+            
+            $roo->jok("PRINT");
+            
+        }
+        
+        if(isset($request['change_type'])){
+            $poitem = DB_DataObject::factory('poitem');
+            $poitem->poitem_pohead_id = $this->pid();
+            if($request['change_type'] == 'E'){
+                $poitem->whereAdd('poitem_location_id = 0');
+            }
+            $poitem->find();
+            while ($poitem->fetch()){
+                $p = clone ($poitem);
+                $poitem->poitem_location_id = $this->pohead_location_id;
+                $poitem->update($p);
+            }
+        }
+        
+        
+    }
+    
+    
+    function fillAddress($addr, $pref)
+    {
+        
+        foreach($addr->toShortArray() as $k=>$v) {
+            switch(true) {
+                case (substr($k,0,4) == 'line'): 
+                    $this->{$pref . 'address' . $k[4] } = $v;
+                    break;
+                
+                case ($k == 'postalcode'):
+                    $this->{$pref.'zipcode'  } = $v;
+                    break;
+                
+                case in_array($k, array('city', 'state')):
+                    $this->{$pref.$k} =$v;
+                    break;
+                default :
+                    break;
+                
+            }
+            
+        }
+        
+        
+    }
+    
+    function items()
+    {
+        $pi = DB_DataObject::Factory('poitem');
+        $pi->poitem_pohead_id = $this->pid();
+        $pi->orderBY('poitem_linenumber ASC');
+        return $pi->fetchAll();
+    }
+    
+    
+    function fillDetails() {
+        
+        
+        
+        // use pohead_shiptoddress_id
+        if ($this->pohead_shiptoddress_id) {
+            $sa = $this->shiptoddress();
+            $this->fillAddress($sa,'pohead_shipto'); 
+        }
+        
+        if ($this->pohead_shipto_cntct_id) {
+            $c = $this->shipto_cntct();
+             
+            foreach($c->toArray() as $k=>$v) {
+                $this->{'pohead_shipto_'.$k} =$v;
+            }
+        }
+        
+        if ($this->pohead_vend_cntct_id) {
+            
+            $c = $this->vend_cntct();
+            
+            foreach($c->toArray() as $k=>$v) {
+                $this->{'pohead_vend_cntct_'.$k} =$v;
+            }
+        }
+        
+        if ($this->pohead_vendaddr_id) {
+            $sa = $this->vendaddr();
+            $this->fillAddress($sa,'pohead_vend');
+        }
+           
+        
+    }
+    
+    
+    
+    function defaults()
+    {
+        static $ret = false;
+        if ($ret) {
+            return $ret;
+        }
+        $ret = array( 
+            'pohead_saved' => false,
+            'pohead_freight' => 0,
+            'pohead_status' => 'O',
+            'pohead_printed' => false,
+     //       'pohead_warehous_id'      => '|(SELECT warehous_id FROM whsinfo LIMIT 1)',
+            'pohead_dropship' => false,
+        );
+        $w = DB_DataObject::Factory('whsinfo');
+        $w->find(true);
+        $ret['pohead_warehous_id'] = $w->warehous_id;
+        return $ret;
+    
+        
+    }
+    
+    function checkDefaults()
+    {
+        $d = array(
+            'pohead_saved' => false,
+            'pohead_freight' => 0,
+            'pohead_status' => 'O',
+            'pohead_printed' => false,
+            'pohead_dropship' => false,
+            'pohead_warehous_id' => $this->sqlValue("(SELECT warehous_id FROM whsinfo LIMIT 1)"),
+            'pohead_taxtype_id' => $this->sqlValue("gettaxtypeid('Taxable'::text)"),
+            'pohead_dropship' => false
+        );
+        return $d;
+    }
+    
+    /**
+     * Used by Shiphead to create a purchase order locally based on a shipment.
+     *
+     *
+     */
+    
+    function createAllFromShipment($roo, $shiphead, $remote_db, $cust, $loc)
+    {
+        $ord = $shiphead->order();
+        $num = 'XF-' . $shiphead->shiphead_number;
+        
+         
+         
+        // find the vendor 
+        $cur = DB_DataObject::Factory('curr_symbol');
+        $cur->get('curr_name', 'USD');
+       
+        
+        // find the company.
+        $v = DB_DataObject::factory('vendinfo');
+        $vend = $v->findInternal($remote_db, $cur);
+        
+        //DB_DataObject::DebugLevel(1);
+        if (!$vend) {
+            $roo->jerr("could not find vendor for $remote_db with USD currency");
+        }
+        
+
+        $taxtype  = DB_DataObject::Factory('taxtype');
+        $taxtype->get('taxtype_name', 'Taxfree');
+        $taxzone = DB_DataObject::Factory('taxzone');
+        $taxzone->get('taxzone_code', 'NO TAX');
+        
+       
+        
+        
+         
+        // find all the unit prices...
+        $orditems = array();
+        
+        $itemsites = array();
+        foreach($ord->items() as $coitem) {
+            $itemsite = $coitem->itemsite();
+            
+            
+            $item = $itemsite->item();
+            // skip Kits...
+            if ($item->item_type == 'K') {
+                continue; 
+            }
+            
+            $line =  $coitem->coitem_subnumber ?
+                ($coitem->coitem_linenumber * 10000  +   $coitem->coitem_subnumber) :
+                $coitem->coitem_linenumber;
+                
+            
+            $item_number = $item->item_number;
+            
+            
+            
+            $qty = $coitem->coitem_qtyord;
+            $coitem->item_number = $item_number;
+            
+            $itemsites[$item_number] = $itemsite->pid();
+            $orditems[$line] = $coitem;
+            
+            if (!isset($items[$item_number])) {
+                $items[$item_number] = 0;
+            }
+            $items[$item_number] += $qty;
+            
+           
+
+            
+        }
+        $po = DB_DataObject::factory('pohead');
+        
+        
+        
+       
+            
+        // does a purchase order already exist for this order?
+       
+        
+        if (!$po->get('pohead_number', $num)) {
+            $po = DB_DataObject::factory('pohead');
+            $po->setFrom($po->defaults());
+            $po->setFrom(array(
+                
+                'pohead_number' => $num,
+                'pohead_orderdate' => $ord->cohead_orderdate,
+                'pohead_terms_id' => $ord->cohead_terms_id,
+                //'pohead_freight' => 'total',
+                'pohead_released' =>  $ord->cohead_orderdate,
+                
+                'pohead_curr_id' => $cur->pid(),
+                 
+                
+                'pohead_vend_id'=>$vend->pid(), 
+                'pohead_ordercomments' => 'Purchase order for Sales Order: ' . $ord->cohead_number,
+                
+                'pohead_taxzone_id' => $taxzone->pid(),
+                'pohead_taxtype_id' => $taxtype->pid(),
+                'pohead_terms_id' => $vend->vend_terms_id,
+                
+            ));
+            $po->vend_cntct($vend->vend_cntct1_id);
+            $po->vendaddr($vend->vend_addr_id);
+            
+            //$po->shipto_cntct( ... );
+            //$po->shiptoddress( $vend->vend_addr_id  );
+            
+            
+            $po->fillDetails();
+            $po->insert();
+        } else {
+            $pp = clone($po);
+             $po->setFrom(array(     
+                'pohead_vend_id'=>$vend->pid(),
+            ));
+             $po->update($pp);
+            // mingore trick...
+            
+            
+        }
+        // made a purchase order...
+       
+        
+        $prices =  $po->fetchXferPrices($roo, $itemsites, $items, $cust);
+        
+        // if we are selling to HK - do not purchase it from them..
+        if ($shiphead->order()->cust()->cust_name == 'Bloom and Grow HK') {
+            return $prices;
+        }
+        
+        
+        
+        
+        //$roo->jerr($prices);
+        $locs = array();
+        
+        $poitems = array();
+        // need to make a copy of the Sales order items into this..
+        foreach($orditems as $line => $coitem) {
+            
+            
+            $poitem = DB_DataObject::factory('poitem');
+            $poitem->poitem_pohead_id = $po->pid();
+            // if it's got a decimal place == eg. 4.5
+            
+            $line =  $coitem->coitem_subnumber ?
+                ($coitem->coitem_linenumber * 10000  +   $coitem->coitem_subnumber) :
+                $coitem->coitem_linenumber;
+           
+            
+            $exist = $poitem->get('poitem_linenumber', $line);
+            
+            $poitem->setFromOrderItem($coitem);
+            
+            
+            //if (!$exist) {
+                $poitem->poitem_unitprice  = $prices[$coitem->item_number];
+                $poitem->poitem_stdcost = $prices[$coitem->item_number];
+            //}
+            
+            $exist ? $poitem->update() : $poitem->insert();
+            $poitems[$coitem->coitem_id] = clone($poitem);
+            $locs[$coitem->coitem_id] = $coitem->coitem_location_src;
+        }
+        
+        // we have now created the purchase order items for this order..
+        
+        // we need to create the receipts for all the items.
+        $recv = DB_DAtaObject::Factory('recv');
+        
+        $shitems = $shiphead->items();
+        // map of orderitem id -> 
+        
+        $done = 0;
+        foreach($poitems as $coitem_id=>$poitem) {
+            
+            // fetch the shipitem for this poitem..
+            if (!isset($shitems[$coitem_id])) {
+                
+                //$roo->jerr("could not find {$poitem->pid()} in shipments for shiphead_id = " . $shiphead->pid());
+                
+                continue;
+            }
+            
+            $shipitem = $shitems[$coitem_id];
+            
+            $recv->createFromShipItem($roo,   $shipitem, $poitem);
+            $done++;
+        }
+        if ($done != count($shitems)) {
+            $roo->jerr("could not create same number of itemrecv from shipitems?");
+        }
+        // do we need to conirm the shipitem.??
+        
+        $recvg = DB_DataObject::Factory('recvgrp');
+        $recvg->createFromPO($roo, $this, $loc);
+        
+         // $roo->jerr("stop");
+        
+        // large transfers do not create the vocher.
+        // this will have to be done manually..
+        //if (count($items) < 100) {
+        // finally ??? create bill?
+        $vohead = DB_DataObject::Factory('vohead');
+        $vohead->createFromPO($roo, $this);
+        $vohead->post($roo);
+        
+         
+        
+        
+        return $prices;
+        
+        
+    }
+    
+    
+    
+    
+    function fetchXferPrices($roo, $itemsites, $itemqtys,  $custinfo) {
+        
+         
+        
+        //die("got here");
+        
+        $cur = DB_DataObject::Factory('curr_symbol');
+        $cur->get('curr_name', 'USD');
+       
+        $ipsass = DB_DataObject::Factory('ipsass'); 
+        
+        if (!$ipsass->get('ipsass_cust_id', $custinfo->pid())){
+            $roo->jerr("Customer {$custinfo->cust_name} does not have a pricelist associated with it.");
+        }
+         
+        $bad_items = array();
+        // slow!!!
+        
+        foreach ($itemsites as $item_number=>$itemsite_id){
+            $itemsite = DB_DataObject::factory('itemsite');
+            $itemsite->get($itemsite_id);
+            
+            $ipsass = DB_DataObject::factory('ipsass');
+            $ipsass->query("SELECT itemprice(
+                            {$itemsite->itemsite_item_id}, 
+                            {$custinfo->pid()}, 
+                            null, 
+                            {$itemqtys[$item_number]}, 
+                            {$this->pohead_curr_id}, 
+                             '{$this->pohead_orderdate}'::date
+                        ) AS result");
+            $ipsass->fetch();
+            
+            if ( empty($ipsass->result) || $ipsass->result == 0.0) {
+                $bad_items[] = $item_number;
+                continue;
+            }
+            
+            
+            $priceLists[$item_number] = $ipsass->result;
+        }
+        
+        if (!empty($bad_items)) {
+            $item = DB_DataObject::Factory('item');
+            $item->whereAddIn('item_id', $bad_items, 'int');
+            $ar = $item->fetchAll('item_number');
+            $roo->jerr("These items do not have prices " . implode(', ', $ar));
+            
+        }
+        return $priceLists;
+        
+        
+        
+        
+         
+        
+        
+    }
+    
+    
+    
+     
+    
+    function revertAllFromShipment($roo, $shiphead)
+    {
+        
+        // if the order is a direct xfer - do not create a PO for it..
+        if ($shiphead->order()->cust()->cust_name == 'Bloom and Grow HK') {
+            return true;
+        }
+        
+        $ord = $shiphead->order();
+        $num = 'XF-' . $shiphead->shiphead_number;
+        
+        $cfg = HTML_FlexyFramework::get()->Xtuple;
+        // does a purchase order already exist for this order?
+        $po = DB_DataObject::factory('pohead');
+        
+        if (!$po->get('pohead_number', $num)) {
+             $roo->jerr("could not find matching purchase order for $num");
+            
+        }
+        // made a purchase order...
+         
+        
+        // we have now created the purchase order items for this order..
+        
+        // we need to create the receipts for all the items.
+        
+        
+        $shitems = $shiphead->items();
+        // map of orderitem id -> 
+        
+        $done = 0;
+        foreach($shitems as  $shipitem) {
+            
+            // fetch the shipitem for this poitem..
+            
+            $recv = DB_DataObject::Factory('recv');
+            $recv->revertFromShipItem($roo, $po, $shipitem );
+            
+
+        }
+        // do we need to conirm the shipitem.??
+        
+         
+        
+    }
+    
+    function joinAddLocation()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN location AS join_pohead_location_id
+                    ON (join_pohead_location_id.location_id = pohead_location_id)
+        ";
+        $t = DB_DataObject::Factory('location');
+        $this->selectAs($t, 'pohead_location_id_%s', 'join_pohead_location_id');
+       
+    }
+    
+   
+    
+}
diff --git a/DataObjects/Poitem.php b/DataObjects/Poitem.php
new file mode 100644 (file)
index 0000000..aaf1ccd
--- /dev/null
@@ -0,0 +1,465 @@
+<?php
+/**
+ * Table Definition for poitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Poitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'poitem';              // table name
+    public $poitem_id;                       // int4(4)  not_null default_nextval%28%28poitem_poitem_id_seq%29%3A%3Aregclass%29 primary_key
+    public $poitem_status;                   // bpchar(-1)  multiple_key
+    public $poitem_pohead_id;                // int4(4)  unique_key multiple_key
+    public $poitem_linenumber;               // int4(4)  unique_key multiple_key
+    public $poitem_duedate;                  // date(4)  multiple_key
+    public $poitem_wohead_id;                // int4(4)  
+    public $poitem_itemsite_id;              // int4(4)  multiple_key
+    public $poitem_vend_item_descrip;        // text(-1)  
+    public $poitem_vend_uom;                 // text(-1)  
+    public $poitem_invvenduomratio;          // numeric(-1)  
+    public $poitem_qty_ordered;              // numeric(-1)  not_null
+    public $poitem_qty_received;             // numeric(-1)  not_null default_0.0
+    public $poitem_qty_returned;             // numeric(-1)  not_null default_0.0
+    public $poitem_qty_vouchered;            // numeric(-1)  not_null default_0.0
+    public $poitem_unitprice;                // numeric(-1)  
+    public $poitem_vend_item_number;         // text(-1)  
+    public $poitem_comments;                 // text(-1)  
+    public $poitem_qty_toreceive;            // numeric(-1)  
+    public $poitem_expcat_id;                // int4(4)  
+    public $poitem_itemsrc_id;               // int4(4)  
+    public $poitem_freight;                  // numeric(-1)  not_null default_0.0
+    public $poitem_freight_received;         // numeric(-1)  not_null default_0.0
+    public $poitem_freight_vouchered;        // numeric(-1)  not_null default_0.0
+    public $poitem_soitem_id;                // int4(4)  
+    public $poitem_prj_id;                   // int4(4)  
+    public $poitem_stdcost;                  // numeric(-1)  
+    public $poitem_bom_rev_id;               // int4(4)  
+    public $poitem_boo_rev_id;               // int4(4)  
+    public $poitem_manuf_name;               // text(-1)  
+    public $poitem_manuf_item_number;        // text(-1)  
+    public $poitem_manuf_item_descrip;       // text(-1)  
+    public $poitem_taxtype_id;               // int4(4)  
+    public $poitem_tax_recoverable;          // bool(1)  not_null default_true
+    public $poitem_rlsd_duedate;             // date(4)  
+    public $poitem_location_id;              //int
+
+    
+   /**
+    * Getter / Setter for $poitem_expcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function expcat() {
+        return func_num_args() ? $this->link('poitem_expcat_id', func_get_arg(0)) : $this->link('poitem_expcat_id');
+    }
+
+   /**
+    * Getter / Setter for $poitem_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('poitem_itemsite_id', func_get_arg(0)) : $this->link('poitem_itemsite_id');
+    }
+
+   /**
+    * Getter / Setter for $poitem_itemsrc_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsrc() {
+        return func_num_args() ? $this->link('poitem_itemsrc_id', func_get_arg(0)) : $this->link('poitem_itemsrc_id');
+    }
+
+   /**
+    * Getter / Setter for $poitem_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('poitem_prj_id', func_get_arg(0)) : $this->link('poitem_prj_id');
+    }
+
+   /**
+    * Getter / Setter for $poitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('poitem_taxtype_id', func_get_arg(0)) : $this->link('poitem_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $poitem_wohead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function wohead() {
+        return func_num_args() ? $this->link('poitem_wohead_id', func_get_arg(0)) : $this->link('poitem_wohead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    public function pohead()
+    {
+        $po = DB_DataObject::Factory('pohead');
+        $po->get($this->poitem_pohead_id);
+        return $po;
+    }
+
+    
+     
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if(isset($q['_totals']) && isset($q['poitem_pohead_id'])){
+            $q['poitem_pohead_id'] = (int)$q['poitem_pohead_id'];
+            $this->selectAdd();
+            $this->selectAdd("
+                COALESCE(count(poitem_id),0) AS count_item,
+                COALESCE(SUM(ROUND(poitem_qty_ordered * poitem_unitprice,2)),0) AS totals
+            ");
+            $this->whereAdd("poitem_pohead_id = {$q['poitem_pohead_id']}");
+        }
+        
+        if (!empty($q['_with_item'])) {
+            $this->joinAdditem();
+            if (!empty($q['item_type'])) {
+                $this->whereAdd("join_poitem_item.item_type ='{$this->escape($q['item_type'])}'");
+                
+            }
+            
+            
+        }
+        
+        if (isset($q['recvgrp_id'])) {
+            
+            $loc = DB_DataObject::Factory('location');
+            $loc_id = $loc->get('location_name', 'Import Goods in Transit') ? $loc->pid() : -1;
+            
+            
+            
+            
+            if (empty($q['recvgrp_id'])) {
+                
+                // recieved = qty recived not into transit, and posted..
+                
+                $this->selectAdd(" 
+                                 
+                                 
+                    0 as  recv_qty,
+                            
+                            
+                                 
+                      COALESCE(  (SELECT
+                                SUM(recv_qty)
+                            FROM
+                                recv
+                            LEFT JOIN
+                                recvgrp
+                            ON
+                                recv_recvgrp_id = recvgrp_id    
+                            WHERE
+                                recvgrp_location_id = {$loc_id}
+                            AND
+                                recv_orderitem_id = poitem_id
+                            AND
+                                 recvgrp_void = 0
+                            ), 0) as recv_qty_in_transit,
+                                 
+                
+                    COALESCE((SELECT SUM(invhist_transfer_item_qty)
+                        FROM
+                            invhist_transfer_item
+                        LEFT JOIN 
+                            invhist_transfer
+                        ON
+                            invhist_transfer_item_invhist_transfer_id = invhist_transfer_id
+                        LEFT JOIN
+                            recvgrp
+                        ON
+                            invhist_transfer_recvgrp_id = recvgrp_id
+                            
+                        WHERE
+                            invhist_transfer_id IS NOT NULL
+                            AND
+                            invhist_transfer_item_invhist_transfer_id IS NOT NULL
+                            AND
+                            invhist_transfer_posted = true
+                            AND 
+                            recvgrp_pohead_id = poitem_pohead_id
+                            AND
+                            invhist_transfer_item_itemsite_id = poitem_itemsite_id
+                            
+                             
+                    ),0) as poitem_qty_transfered,
+                    
+                    COALESCE((SELECT SUM(invhist_transfer_item_qty)
+                        FROM
+                            invhist_transfer_item
+                        LEFT JOIN 
+                            invhist_transfer
+                        ON
+                            invhist_transfer_item_invhist_transfer_id = invhist_transfer_id
+                        LEFT JOIN
+                            recvgrp
+                        ON
+                            invhist_transfer_recvgrp_id = recvgrp_id
+                            
+                        WHERE
+                            invhist_transfer_id IS NOT NULL
+                            AND
+                            invhist_transfer_item_invhist_transfer_id IS NOT NULL
+                            AND
+                            invhist_transfer_posted = false
+                            AND 
+                            recvgrp_pohead_id = poitem_pohead_id 
+                            AND
+                            invhist_transfer_item_itemsite_id = poitem_itemsite_id
+                             
+                    ),0) as poitem_qty_transfered_unposted
+                    
+                    
+                    
+                    ");
+            } else {
+                $id = (int)$q['recvgrp_id'];
+                $this->selectAdd("
+                    COALESCE(  (SELECT
+                                SUM(recv_qty)
+                            FROM
+                                recv
+                            LEFT JOIN
+                                recvgrp
+                            ON
+                                recv_recvgrp_id = recvgrp_id    
+                            WHERE
+                                recv_recvgrp_id = $id
+                            AND
+                                recv_orderitem_id = poitem_id
+                            AND
+                                recvgrp_location_id != {$loc_id}
+                           
+                            ), 0) as recv_qty,
+                    
+                    
+                    COALESCE(  (SELECT
+                                SUM(recv_qty)
+                            FROM
+                                recv
+                            LEFT JOIN
+                                recvgrp
+                            ON
+                                recv_recvgrp_id = recvgrp_id    
+                            WHERE
+                                    recv_recvgrp_id = $id
+                                AND
+                                    recvgrp_location_id = {$loc_id}
+                                AND
+                                    recv_orderitem_id = poitem_id
+                               
+                            ), 0) as recv_qty_in_transit,
+                            
+                    0 as poitem_qty_transfered_unposted,
+                    0 as poitem_qty_transfered
+                   ");
+            }
+        }
+        
+        if(!empty($q['search']['name'])){
+            $this->whereAdd("
+                join_poitem_item.item_number ILIKE '%{$this->escape($q['search']['name'])}%'
+                OR
+                join_poitem_item.item_descrip1 ILIKE '%{$this->escape($q['search']['name'])}%'
+                OR
+                join_poitem_pohead.pohead_number ILIKE '%{$this->escape($q['search']['name'])}%'
+                OR
+                charass_getvalue('I', join_poitem_item.item_id, 'BRAND') ILIKE '%{$this->escape($q['search']['name'])}%'
+            ");
+        }
+        
+        if(!empty($q['search']['location'])){
+            $q['search']['location'] = (int) $q['search']['location'];
+            $this->whereAdd("
+                poitem_location_id = {$q['search']['location']}
+            ");
+        }
+       
+        if(isset($q['_incoming_stock'])){
+            $this->selectAdd();
+            $this->autoJoinPohead();
+            $this->joinAdditem();
+            $this->joinAddLocation();
+            $this->selectAdd("
+                poitem_id,
+                join_poitem_pohead.pohead_number AS join_poitem_pohead_number,
+                join_poitem_pohead.pohead_orderdate AS join_poitem_pohead_orderdate,
+                (SELECT vend_name FROM vendinfo WHERE vend_id = join_poitem_pohead.pohead_vend_id) AS join_poitem_vend_name,
+                join_poitem_pohead.pohead_vendcountry AS join_poitem_pohead_vendcountry,
+                poitem_duedate,
+                join_poitem_item.item_number AS item_name,
+                join_poitem_item.item_descrip1 AS item_descrip,
+                charass_getvalue('I', join_poitem_item.item_id, 'BRAND') AS brand_value,
+                poitem_qty_ordered,
+                join_poitem_pohead.pohead_comments AS join_poitem_pohead_pohead_comments
+            ");
+            if(!preg_match('/sandbox/', $roo->rootURL)){
+                $this->whereAdd("poitem_duedate >= NOW()");
+            }
+            $this->orderBy('poitem_duedate  ASC');
+            
+        }
+        
+    }
+    function joinAdditem()
+    {
+        $this->_join .= "
+            LEFT JOIN item AS join_poitem_item
+                    ON (join_poitem_item.item_id =join_poitem_itemsite_id_itemsite_id.itemsite_item_id)
+        ";
+        $t = DB_DataObject::Factory('item');
+        $this->selectAs($t, '%s', 'join_poitem_item');
+        
+    }
+    
+    function defaults()
+    {
+        static $ret = false;
+        if ($ret) {
+           return $ret;
+        }
+        $ret = array(
+            'poitem_status' =>  'O', //open
+            'poitem_invvenduomratio' => 1,
+            'poitem_qty_returned' =>   0.000000,
+            'poitem_qty_vouchered' =>  0.000000,
+            'poitem_vend_uom' => 'EA',
+            'poitem_freight'        => 0,
+            'poitem_freight_received'=> 0,
+            'poitem_freight_vouchered' => 0,
+            'poitem_qty_received'   => 0,
+            'poitem_tax_recoverable' => false,
+        );
+        
+        //$wh = DB_DAtaObject_Faction('warehous')
+        
+       // 'poitem_wohead_id'=> NOT NEEDED..
+       // 'poitem_expcat_id'=> NOT NEEDED..
+        
+     
+        //   'poitem_itemsrc_id'=>"| (SELECT itemsrc_id from itemsrc LIMIT 1)" ,//FIXME needs to define correct WHERE clause
+     //   'poitem_prj_id'=> NOT NEEDED..
+        return $ret;
+    }
+
+    function setFromOrderItem($coitem ) 
+    {
+        if (!$this->poitem_id) {
+            $this->setFrom($this->defaults());
+        }
+        $pohead = $this->pohead();
+        $line =  $coitem->coitem_subnumber ?
+                ($coitem->coitem_linenumber * 10000  +   $coitem->coitem_subnumber) :
+                $coitem->coitem_linenumber;
+           
+        $this->setFrom(array(
+            //'poitem_pohead_id'      => 'poitem_pohead_id',
+            'poitem_itemsite_id' => $coitem->coitem_itemsite_id,
+            'poitem_linenumber'     => $line,
+            'poitem_qty_ordered'    => $coitem->coitem_qtyord,
+           
+           // 'poitem_vend_item_number'=>'item',
+            'poitem_vend_item_descrip'       =>   $coitem->coitem_memo,
+            'poitem_comments'       => $coitem->coitem_memo,
+            
+         
+            'poitem_taxtype_id'     => $pohead->pohead_taxtype_id,
+            
+            'poitem_duedate'        => $coitem->coitem_scheddate,
+            // not available.. here
+              //  'poitem_unitprice'      =>  $unitprice,
+             //  'poitem_stdcost'        => $unitprice,  // not really...???
+        ));
+        
+        
+        
+        
+    }
+    
+    // used by remote posting...
+    
+    
+    function setFromTransferItem($roo, $coitem, $pohead , $item) 
+    {
+        if (!$this->poitem_id) {
+            $this->setFrom($this->defaults());
+        }
+
+       
+        
+           
+        $this->setFrom(array(
+            //'poitem_pohead_id'      => 'poitem_pohead_id',
+            'poitem_itemsite_id' => $item->item_itemsite_id_itemsite_id,
+            'poitem_linenumber'     => $coitem->line, 
+            'poitem_qty_ordered'    => $coitem->qty,
+           
+           // 'poitem_vend_item_number'=>'item',
+            'poitem_vend_item_descrip'       =>   $item->item_descrip1,
+            
+            'poitem_comments'       => '', //$coitem->coitem_memo,
+            
+         
+            'poitem_taxtype_id'     => $pohead->pohead_taxtype_id,
+            
+            'poitem_duedate'        => $coitem->duedate,
+            // not available.. here
+            'poitem_unitprice'      =>  round($coitem->cost,2),
+            'poitem_stdcost'        => round($coitem->cost,2),  // ??? is this correct - should it be set?
+        ));
+         
+        
+    }
+    
+    function autoJoinCurr()
+    {
+        $this->_join .= "
+            LEFT JOIN curr_symbol AS join_poitem_curr_symbol
+                ON (join_poitem_pohead.pohead_curr_id = join_poitem_curr_symbol.curr_id)
+        ";
+        $add = DB_DataObject::Factory('curr_symbol');
+        $this->selectAs($add, 'join_poitem_%s', 'join_poitem_curr_symbol');
+    }
+    
+    function autoJoinPohead()
+    {
+        $this->_join .= "
+            LEFT JOIN pohead AS join_poitem_pohead
+                ON (join_poitem_pohead.pohead_id = poitem_pohead_id)
+        ";
+        $add = DB_DataObject::Factory('pohead');
+        $this->selectAs($add, 'join_poitem_%s', 'join_poitem_pohead');
+    }
+    
+    function joinAddLocation()
+    {
+        $this->_join .= "
+            LEFT JOIN location AS join_poitem_location
+            ON join_poitem_location.location_id = poitem_location_id
+        ";
+        $l = DB_DataObject::Factory('location');
+        $this->selectAs($l, 'join_poitem_%s', 'join_poitem_location');
+    }
+    
+}
diff --git a/DataObjects/Porecv.php b/DataObjects/Porecv.php
new file mode 100644 (file)
index 0000000..e1c117c
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Table Definition for porecv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Porecv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'porecv';              // table name
+    public $porecv_id;                       // int4(4)  
+    public $porecv_date;                     // timestamptz(8)  
+    public $porecv_rlsd_duedate;             // date(4)  
+    public $porecv_orderdate;                // date(4)  
+    public $porecv_released;                 // date(4)  
+    public $porecv_ponumber;                 // text(-1)  
+    public $porecv_itemsite_id;              // int4(4)  
+    public $porecv_vend_id;                  // int4(4)  
+    public $porecv_item_number;              // text(-1)  
+    public $porecv_vend_item_number;         // text(-1)  
+    public $porecv_vend_item_descrip;        // text(-1)  
+    public $porecv_vend_uom;                 // text(-1)  
+    public $porecv_qty;                      // numeric(-1)  
+    public $porecv_posted;                   // bool(1)  
+    public $porecv_invoiced;                 // bool(1)  
+    public $porecv_trans_usr_id;             // int4(4)  
+    public $porecv_poitem_id;                // int4(4)  
+    public $porecv_linenumber;               // int4(4)  
+    public $porecv_purchcost;                // numeric(-1)  
+    public $porecv_vohead_id;                // int4(4)  
+    public $porecv_recvcost;                 // numeric(-1)  
+    public $porecv_duedate;                  // date(4)  
+    public $porecv_agent_username;           // text(-1)  
+    public $porecv_notes;                    // text(-1)  
+    public $porecv_freight;                  // numeric(-1)  
+    public $porecv_curr_id;                  // int4(4)  
+    public $porecv_gldistdate;               // date(4)  
+    public $porecv_voitem_id;                // int4(4)  
+    public $porecv_value;                    // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Poreject.php b/DataObjects/Poreject.php
new file mode 100644 (file)
index 0000000..6620185
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Table Definition for poreject
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Poreject extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'poreject';            // table name
+    public $poreject_id;                     // int4(4)  not_null default_nextval%28%28%22poreject_poreject_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $poreject_date;                   // timestamptz(8)  
+    public $poreject_ponumber;               // text(-1)  
+    public $poreject_itemsite_id;            // int4(4)  
+    public $poreject_vend_id;                // int4(4)  
+    public $poreject_vend_item_number;       // text(-1)  
+    public $poreject_vend_item_descrip;      // text(-1)  
+    public $poreject_vend_uom;               // text(-1)  
+    public $poreject_qty;                    // numeric(-1)  
+    public $poreject_posted;                 // bool(1)  
+    public $poreject_rjctcode_id;            // int4(4)  
+    public $poreject_poitem_id;              // int4(4)  
+    public $poreject_invoiced;               // bool(1)  
+    public $poreject_vohead_id;              // int4(4)  
+    public $poreject_agent_username;         // text(-1)  
+    public $poreject_voitem_id;              // int4(4)  
+    public $poreject_value;                  // numeric(-1)  
+    public $poreject_trans_username;         // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Potype.php b/DataObjects/Potype.php
new file mode 100644 (file)
index 0000000..7466a5f
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for potype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Potype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'potype';              // table name
+    public $potype_id;                       // int4(4)  not_null default_nextval%28potype_potype_id_seq%29 primary_key
+    public $potype_name;                     // text(-1)  
+    public $potype_descrip;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Pr.php b/DataObjects/Pr.php
new file mode 100644 (file)
index 0000000..44e2c32
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Table Definition for pr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Pr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'pr';                  // table name
+    public $pr_id;                           // int4(4)  not_null default_nextval%28%28%22pr_pr_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $pr_number;                       // int4(4)  
+    public $pr_subnumber;                    // int4(4)  
+    public $pr_status;                       // bpchar(-1)  
+    public $pr_order_type;                   // bpchar(-1)  
+    public $pr_order_id;                     // int4(4)  
+    public $pr_poitem_id;                    // int4(4)  
+    public $pr_duedate;                      // date(4)  
+    public $pr_itemsite_id;                  // int4(4)  
+    public $pr_qtyreq;                       // numeric(-1)  
+    public $pr_prj_id;                       // int4(4)  
+    public $pr_releasenote;                  // text(-1)  
+    public $pr_createdate;                   // timestamp(8)  default_now%28%29
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Prftcntr.php b/DataObjects/Prftcntr.php
new file mode 100644 (file)
index 0000000..43979e9
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for prftcntr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prftcntr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prftcntr';            // table name
+    public $prftcntr_id;                     // int4(4)  not_null default_nextval%28prftcntr_prftcntr_id_seq%29 primary_key
+    public $prftcntr_number;                 // text(-1)  unique_key
+    public $prftcntr_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Priv.php b/DataObjects/Priv.php
new file mode 100644 (file)
index 0000000..916f6b3
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for priv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Priv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'priv';                // table name
+    public $priv_id;                         // int4(4)  not_null default_nextval%28%28priv_priv_id_seq%29%3A%3Aregclass%29 primary_key
+    public $priv_module;                     // text(-1)  
+    public $priv_name;                       // text(-1)  unique_key
+    public $priv_descrip;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Prj.php b/DataObjects/Prj.php
new file mode 100644 (file)
index 0000000..521eef0
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Table Definition for prj
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prj extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prj';                 // table name
+    public $prj_id;                          // int4(4)  not_null default_nextval%28prj_prj_id_seq%29 primary_key
+    public $prj_number;                      // text(-1)  not_null unique_key
+    public $prj_name;                        // text(-1)  not_null
+    public $prj_descrip;                     // text(-1)  
+    public $prj_status;                      // bpchar(-1)  not_null
+    public $prj_so;                          // bool(1)  
+    public $prj_wo;                          // bool(1)  
+    public $prj_po;                          // bool(1)  
+    public $prj_owner_username;              // text(-1)  
+    public $prj_start_date;                  // date(4)  
+    public $prj_due_date;                    // date(4)  
+    public $prj_assigned_date;               // date(4)  
+    public $prj_completed_date;              // date(4)  
+    public $prj_username;                    // text(-1)  
+    public $prj_recurring_prj_id;            // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $prj_recurring_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function recurring_prj() {
+        return func_num_args() ? $this->link('prj_recurring_prj_id', func_get_arg(0)) : $this->link('prj_recurring_prj_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Prjtask.php b/DataObjects/Prjtask.php
new file mode 100644 (file)
index 0000000..d3348bd
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for prjtask
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prjtask extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prjtask';             // table name
+    public $prjtask_id;                      // int4(4)  not_null default_nextval%28prjtask_prjtask_id_seq%29 primary_key
+    public $prjtask_number;                  // text(-1)  not_null unique_key multiple_key
+    public $prjtask_name;                    // text(-1)  not_null
+    public $prjtask_descrip;                 // text(-1)  
+    public $prjtask_prj_id;                  // int4(4)  not_null unique_key multiple_key
+    public $prjtask_anyuser;                 // bool(1)  
+    public $prjtask_status;                  // bpchar(-1)  not_null
+    public $prjtask_hours_budget;            // numeric(-1)  not_null
+    public $prjtask_hours_actual;            // numeric(-1)  not_null
+    public $prjtask_exp_budget;              // numeric(-1)  not_null
+    public $prjtask_exp_actual;              // numeric(-1)  not_null
+    public $prjtask_owner_username;          // text(-1)  
+    public $prjtask_start_date;              // date(4)  
+    public $prjtask_due_date;                // date(4)  
+    public $prjtask_assigned_date;           // date(4)  
+    public $prjtask_completed_date;          // date(4)  
+    public $prjtask_username;                // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $prjtask_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('prjtask_prj_id', func_get_arg(0)) : $this->link('prjtask_prj_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Prjtaskuser.php b/DataObjects/Prjtaskuser.php
new file mode 100644 (file)
index 0000000..abcffdb
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for prjtaskuser
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prjtaskuser extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prjtaskuser';         // table name
+    public $prjtaskuser_id;                  // int4(4)  not_null default_nextval%28prjtaskuser_prjtaskuser_id_seq%29 primary_key
+    public $prjtaskuser_prjtask_id;          // int4(4)  
+    public $prjtaskuser_username;            // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Prodcat.php b/DataObjects/Prodcat.php
new file mode 100644 (file)
index 0000000..48094eb
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Table Definition for prodcat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prodcat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prodcat';             // table name
+    public $prodcat_id;                      // int4(4)  not_null default_nextval%28%28prodcat_prodcat_id_seq%29%3A%3Aregclass%29 primary_key
+    public $prodcat_code;                    // text(-1)  
+    public $prodcat_descrip;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function initDatabase($roo)
+    {
+        
+        static $ar = array(
+            'STANDARD' => 'Standard'  ,
+            'PRODUCT' => 'Standard Product',
+            'NONPRODUCT'=> 'Non Product'
+        );
+        
+        foreach($ar as $k=>$v) {
+            $pc = DB_DataObject::Factory('prodcat');
+            if ($pc->get('prodcat_code', $k)) {
+                continue;
+            }
+            $pc->setFrom(array(
+                'prodcat_code' => $k,
+                'prodcat_descrip' => $v
+            ));
+            $pc->insert();
+        }
+        
+        
+    }
+    
+    function beforeInsert($q,$roo)
+    {
+        $this->checkProdcatCode($roo);
+    }
+    
+    function beforeUpdate($old, $request,$roo)
+    {
+        if($old->prodcat_code != $this->prodcat_code){
+            $this->checkProdcatCode($roo);
+        }
+        
+    }
+    
+    function onInsert($q,$roo)
+    {
+        $this->updateSalesaccnt($q, $roo);
+    }
+    
+    function onUpdate($old, $q,$roo)
+    {
+        $this->updateSalesaccnt($q, $roo);
+    }
+    
+    function toRooSingleArray($au, $q)
+    {
+        $ret = $this->toArray();
+        
+        if(!isset($q['_with_salesaccnt'])){
+            return $ret;
+        }
+        
+        $salesaccnt = DB_DataObject::factory('salesaccnt');
+        $salesaccnt->selectAdd("
+            CASE WHEN ( (salesaccnt_custtype_id<>-1) AND (salesaccnt_prodcat_id<>-1) ) THEN 'A'
+                WHEN ( (salesaccnt_custtype_id<>-1) AND (salesaccnt_prodcat_id=-1) ) THEN 'B'
+                WHEN ( (salesaccnt_custtype_id=-1) AND (salesaccnt_prodcat_id<>-1) ) THEN 'C'
+            ELSE 'D'
+           END AS orderby
+        ");
+        $salesaccnt->whereAdd("
+                (salesaccnt_warehous_id=-1)
+            AND  
+                ( 
+                        (salesaccnt_prodcat='.*') 
+                        OR
+                        ( 
+                                (salesaccnt_prodcat_id=-1)
+                                AND
+                                (salesaccnt_prodcat <> '')
+                        ) 
+                        OR
+                        ( 
+                                (salesaccnt_prodcat_id={$ret['prodcat_id']}) 
+                        ) 
+                )
+            AND  
+                ( 
+                        (salesaccnt_custtype='.*') 
+                        OR
+                        ( 
+                                (salesaccnt_custtype_id=-1) 
+                                AND
+                                (salesaccnt_custtype<>'') 
+                                
+                        ) 
+                )
+        ");
+                                
+        $salesaccnt->orderBy('orderby,salesaccnt_custtype DESC, salesaccnt_prodcat DESC');
+        $salesaccnt->find(true);
+        
+        $ret['salesaccnt_id'] = $salesaccnt->salesaccnt_id;
+        
+        $accounts = array(
+            'salesaccnt_sales_accnt_id',
+            'salesaccnt_credit_accnt_id',
+            'salesaccnt_cos_accnt_id'
+        );
+        
+        foreach ($accounts as $a){
+            $accnt = DB_DataObject::factory('accnt');
+            if(!$accnt->get($salesaccnt->$a)){
+                continue;
+            }
+            $ret["{$a}"] = $accnt->pid();
+            $ret["{$a}_name"] = $accnt->accnt_name;
+            $ret["{$a}_descrip"] = $accnt->accnt_descrip;
+        }
+        
+        return $ret;
+    }
+    
+    function checkProdcatCode($roo)
+    {
+        $this->prodcat_code = strtoupper(trim(str_replace(' ', '', $this->prodcat_code)));
+        
+        if(empty($this->prodcat_code)){
+            $roo->jerr('Missing product categroy code');
+        }
+        
+        $prodcat = DB_DataObject::factory('prodcat');
+        if($prodcat->get('prodcat_code', $this->prodcat_code)){
+            $roo->jerr("Product category code already exist! code : {$this->prodcat_code}");
+        }
+        
+        return;
+    }
+    
+    function updateSalesaccnt($q, $roo)
+    {
+        if(empty($q['salesaccnt_sales_accnt_id']) || empty($q['salesaccnt_credit_accnt_id']) || empty($q['salesaccnt_cos_accnt_id'])){
+            $roo->jerr('Missing account setting for this product category');
+        }
+        
+        $salesaccnt = DB_DataObject::factory('salesaccnt');
+        
+        if(!empty($q['salesaccnt_id'])){
+            if(!$salesaccnt->get($q['salesaccnt_id'])){
+                $roo->jerr("Error occur on getting the salesaccnt! salesaccnt_id : {$q['salesaccnt_id']}");
+            }
+            
+            $old = clone($salesaccnt);
+        }
+        
+        $salesaccnt->setFrom($q);
+        
+        if(!isset($salesaccnt->salesaccnt_prodcat)){
+            $salesaccnt->salesaccnt_prodcat = '[^a-zA-Z0-9_]';
+        }
+        
+        if(!isset($salesaccnt->salesaccnt_prodcat_id)){
+            $salesaccnt->salesaccnt_prodcat_id = $this->pid();
+        }
+        
+        foreach($salesaccnt->defaults() as $k=>$v) {
+            if (!isset($salesaccnt->$k)) {
+                $salesaccnt->$k = $v;
+            }
+        }
+        
+        empty($salesaccnt->salesaccnt_id) ? $salesaccnt->insert() : $salesaccnt->update($old);
+        
+        return;
+        
+    }
+    
+}
+
diff --git a/DataObjects/Prospect.php b/DataObjects/Prospect.php
new file mode 100644 (file)
index 0000000..8ef286d
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Table Definition for prospect
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Prospect extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'prospect';            // table name
+    public $prospect_id;                     // int4(4)  not_null default_nextval%28cust_cust_id_seq%29 primary_key primary_key
+    public $prospect_active;                 // bool(1)  not_null default_true
+    public $prospect_number;                 // text(-1)  not_null
+    public $prospect_name;                   // text(-1)  not_null
+    public $prospect_cntct_id;               // int4(4)  
+    public $prospect_comments;               // text(-1)  
+    public $prospect_created;                // date(4)  not_null default_%28now%29%3A%3Adate
+    public $prospect_salesrep_id;            // int4(4)  
+    public $prospect_warehous_id;            // int4(4)  
+    public $prospect_taxzone_id;             // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $prospect_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('prospect_cntct_id', func_get_arg(0)) : $this->link('prospect_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $prospect_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('prospect_salesrep_id', func_get_arg(0)) : $this->link('prospect_salesrep_id');
+    }
+
+   /**
+    * Getter / Setter for $prospect_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('prospect_taxzone_id', func_get_arg(0)) : $this->link('prospect_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $prospect_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('prospect_warehous_id', func_get_arg(0)) : $this->link('prospect_warehous_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Qryhead.php b/DataObjects/Qryhead.php
new file mode 100644 (file)
index 0000000..9baef66
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for qryhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Qryhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'qryhead';             // table name
+    public $qryhead_id;                      // int4(4)  not_null default_nextval%28qryhead_qryhead_id_seq%29 primary_key
+    public $qryhead_name;                    // text(-1)  unique_key
+    public $qryhead_descrip;                 // text(-1)  
+    public $qryhead_notes;                   // text(-1)  
+    public $qryhead_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $qryhead_updated;                 // date(4)  not_null default_%28now%29%3A%3Adate
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Qryitem.php b/DataObjects/Qryitem.php
new file mode 100644 (file)
index 0000000..aee2162
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Table Definition for qryitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Qryitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'qryitem';             // table name
+    public $qryitem_id;                      // int4(4)  not_null default_nextval%28qryitem_qryitem_id_seq%29
+    public $qryitem_qryhead_id;              // int4(4)  not_null unique_key multiple_key unique_key multiple_key
+    public $qryitem_name;                    // text(-1)  not_null unique_key multiple_key
+    public $qryitem_order;                   // int4(4)  not_null unique_key multiple_key
+    public $qryitem_src;                     // text(-1)  not_null
+    public $qryitem_group;                   // text(-1)  
+    public $qryitem_detail;                  // text(-1)  not_null
+    public $qryitem_notes;                   // text(-1)  not_null default_
+    public $qryitem_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $qryitem_updated;                 // date(4)  not_null default_%28now%29%3A%3Adate
+
+    
+   /**
+    * Getter / Setter for $qryitem_qryhead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qryhead() {
+        return func_num_args() ? $this->link('qryitem_qryhead_id', func_get_arg(0)) : $this->link('qryitem_qryhead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Quhead.php b/DataObjects/Quhead.php
new file mode 100644 (file)
index 0000000..1376b28
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Table Definition for quhead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Quhead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'quhead';              // table name
+    public $quhead_id;                       // int4(4)  not_null default_nextval%28%28%22quhead_quhead_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $quhead_number;                   // text(-1)  unique_key
+    public $quhead_cust_id;                  // int4(4)  not_null
+    public $quhead_quotedate;                // date(4)  
+    public $quhead_shipto_id;                // int4(4)  
+    public $quhead_shiptoname;               // text(-1)  
+    public $quhead_shiptoaddress1;           // text(-1)  
+    public $quhead_shiptoaddress2;           // text(-1)  
+    public $quhead_shiptoaddress3;           // text(-1)  
+    public $quhead_shiptocity;               // text(-1)  
+    public $quhead_shiptostate;              // text(-1)  
+    public $quhead_shiptozipcode;            // text(-1)  
+    public $quhead_shiptophone;              // text(-1)  
+    public $quhead_salesrep_id;              // int4(4)  
+    public $quhead_terms_id;                 // int4(4)  
+    public $quhead_origin;                   // bpchar(-1)  
+    public $quhead_freight;                  // numeric(-1)  
+    public $quhead_ordercomments;            // text(-1)  
+    public $quhead_shipcomments;             // text(-1)  
+    public $quhead_billtoname;               // text(-1)  
+    public $quhead_billtoaddress1;           // text(-1)  
+    public $quhead_billtoaddress2;           // text(-1)  
+    public $quhead_billtoaddress3;           // text(-1)  
+    public $quhead_billtocity;               // text(-1)  
+    public $quhead_billtostate;              // text(-1)  
+    public $quhead_billtozip;                // text(-1)  
+    public $quhead_commission;               // numeric(-1)  
+    public $quhead_custponumber;             // text(-1)  
+    public $quhead_fob;                      // text(-1)  
+    public $quhead_shipvia;                  // text(-1)  
+    public $quhead_warehous_id;              // int4(4)  
+    public $quhead_packdate;                 // date(4)  
+    public $quhead_prj_id;                   // int4(4)  
+    public $quhead_misc;                     // numeric(-1)  not_null default_0
+    public $quhead_misc_accnt_id;            // int4(4)  
+    public $quhead_misc_descrip;             // text(-1)  
+    public $quhead_billtocountry;            // text(-1)  
+    public $quhead_shiptocountry;            // text(-1)  
+    public $quhead_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $quhead_imported;                 // bool(1)  default_false
+    public $quhead_expire;                   // date(4)  
+    public $quhead_calcfreight;              // bool(1)  not_null default_false
+    public $quhead_shipto_cntct_id;          // int4(4)  
+    public $quhead_shipto_cntct_honorific;    // text(-1)  
+    public $quhead_shipto_cntct_first_name;    // text(-1)  
+    public $quhead_shipto_cntct_middle;      // text(-1)  
+    public $quhead_shipto_cntct_last_name;    // text(-1)  
+    public $quhead_shipto_cntct_suffix;      // text(-1)  
+    public $quhead_shipto_cntct_phone;       // text(-1)  
+    public $quhead_shipto_cntct_title;       // text(-1)  
+    public $quhead_shipto_cntct_fax;         // text(-1)  
+    public $quhead_shipto_cntct_email;       // text(-1)  
+    public $quhead_billto_cntct_id;          // int4(4)  
+    public $quhead_billto_cntct_honorific;    // text(-1)  
+    public $quhead_billto_cntct_first_name;    // text(-1)  
+    public $quhead_billto_cntct_middle;      // text(-1)  
+    public $quhead_billto_cntct_last_name;    // text(-1)  
+    public $quhead_billto_cntct_suffix;      // text(-1)  
+    public $quhead_billto_cntct_phone;       // text(-1)  
+    public $quhead_billto_cntct_title;       // text(-1)  
+    public $quhead_billto_cntct_fax;         // text(-1)  
+    public $quhead_billto_cntct_email;       // text(-1)  
+    public $quhead_taxzone_id;               // int4(4)  
+    public $quhead_taxtype_id;               // int4(4)  
+    public $quhead_ophead_id;                // int4(4)  
+    public $quhead_status;                   // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $quhead_billto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function billto_cntct() {
+        return func_num_args() ? $this->link('quhead_billto_cntct_id', func_get_arg(0)) : $this->link('quhead_billto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_misc_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function misc_accnt() {
+        return func_num_args() ? $this->link('quhead_misc_accnt_id', func_get_arg(0)) : $this->link('quhead_misc_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_ophead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ophead() {
+        return func_num_args() ? $this->link('quhead_ophead_id', func_get_arg(0)) : $this->link('quhead_ophead_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_prj_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function prj() {
+        return func_num_args() ? $this->link('quhead_prj_id', func_get_arg(0)) : $this->link('quhead_prj_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('quhead_salesrep_id', func_get_arg(0)) : $this->link('quhead_salesrep_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_shipto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipto_cntct() {
+        return func_num_args() ? $this->link('quhead_shipto_cntct_id', func_get_arg(0)) : $this->link('quhead_shipto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_shipto_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipto() {
+        return func_num_args() ? $this->link('quhead_shipto_id', func_get_arg(0)) : $this->link('quhead_shipto_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('quhead_taxtype_id', func_get_arg(0)) : $this->link('quhead_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('quhead_taxzone_id', func_get_arg(0)) : $this->link('quhead_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_terms_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function terms() {
+        return func_num_args() ? $this->link('quhead_terms_id', func_get_arg(0)) : $this->link('quhead_terms_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_warehous_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function warehous() {
+        return func_num_args() ? $this->link('quhead_warehous_id', func_get_arg(0)) : $this->link('quhead_warehous_id');
+    }
+
+   /**
+    * Getter / Setter for $quhead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('quhead_curr_id', func_get_arg(0)) : $this->link('quhead_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Quitem.php b/DataObjects/Quitem.php
new file mode 100644 (file)
index 0000000..e9cbc58
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Table Definition for quitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Quitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'quitem';              // table name
+    public $quitem_id;                       // int4(4)  not_null default_nextval%28%28%22quitem_quitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $quitem_quhead_id;                // int4(4)  
+    public $quitem_linenumber;               // int4(4)  
+    public $quitem_itemsite_id;              // int4(4)  
+    public $quitem_scheddate;                // date(4)  
+    public $quitem_qtyord;                   // numeric(-1)  
+    public $quitem_unitcost;                 // numeric(-1)  
+    public $quitem_price;                    // numeric(-1)  
+    public $quitem_custprice;                // numeric(-1)  
+    public $quitem_memo;                     // text(-1)  
+    public $quitem_custpn;                   // text(-1)  
+    public $quitem_createorder;              // bool(1)  
+    public $quitem_order_warehous_id;        // int4(4)  
+    public $quitem_item_id;                  // int4(4)  
+    public $quitem_prcost;                   // numeric(-1)  
+    public $quitem_imported;                 // bool(1)  default_false
+    public $quitem_qty_uom_id;               // int4(4)  not_null
+    public $quitem_qty_invuomratio;          // numeric(-1)  not_null
+    public $quitem_price_uom_id;             // int4(4)  not_null
+    public $quitem_price_invuomratio;        // numeric(-1)  not_null
+    public $quitem_promdate;                 // date(4)  
+    public $quitem_taxtype_id;               // int4(4)  
+    public $quitem_dropship;                 // bool(1)  default_false
+    public $quitem_itemsrc_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $quitem_itemsrc_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsrc() {
+        return func_num_args() ? $this->link('quitem_itemsrc_id', func_get_arg(0)) : $this->link('quitem_itemsrc_id');
+    }
+
+   /**
+    * Getter / Setter for $quitem_price_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function price_uom() {
+        return func_num_args() ? $this->link('quitem_price_uom_id', func_get_arg(0)) : $this->link('quitem_price_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $quitem_qty_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function qty_uom() {
+        return func_num_args() ? $this->link('quitem_qty_uom_id', func_get_arg(0)) : $this->link('quitem_qty_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $quitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('quitem_taxtype_id', func_get_arg(0)) : $this->link('quitem_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Rcalitem.php b/DataObjects/Rcalitem.php
new file mode 100644 (file)
index 0000000..7c5f13b
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for rcalitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Rcalitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'rcalitem';            // table name
+    public $rcalitem_id;                     // int4(4)  not_null default_nextval%28%28%22xcalitem_xcalitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $rcalitem_calhead_id;             // int4(4)  
+    public $rcalitem_offsettype;             // bpchar(-1)  
+    public $rcalitem_offsetcount;            // int4(4)  
+    public $rcalitem_periodtype;             // bpchar(-1)  
+    public $rcalitem_periodcount;            // int4(4)  
+    public $rcalitem_name;                   // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Recur.php b/DataObjects/Recur.php
new file mode 100644 (file)
index 0000000..98136c3
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for recur
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Recur extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'recur';               // table name
+    public $recur_id;                        // int4(4)  not_null default_nextval%28recur_recur_id_seq%29 primary_key
+    public $recur_parent_id;                 // int4(4)  not_null unique_key multiple_key
+    public $recur_parent_type;               // text(-1)  not_null unique_key multiple_key
+    public $recur_period;                    // text(-1)  not_null
+    public $recur_freq;                      // int4(4)  not_null default_1
+    public $recur_start;                     // timestamptz(8)  default_now%28%29
+    public $recur_end;                       // timestamptz(8)  
+    public $recur_max;                       // int4(4)  
+    public $recur_data;                      // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Recurtype.php b/DataObjects/Recurtype.php
new file mode 100644 (file)
index 0000000..5d79578
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for recurtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Recurtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'recurtype';           // table name
+    public $recurtype_id;                    // int4(4)  not_null default_nextval%28recurtype_recurtype_id_seq%29 primary_key
+    public $recurtype_type;                  // text(-1)  not_null unique_key
+    public $recurtype_table;                 // text(-1)  not_null
+    public $recurtype_donecheck;             // text(-1)  not_null
+    public $recurtype_schedcol;              // text(-1)  not_null
+    public $recurtype_limit;                 // text(-1)  
+    public $recurtype_copyfunc;              // text(-1)  not_null
+    public $recurtype_copyargs;              // _text(-1)  not_null
+    public $recurtype_delfunc;               // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Recv.php b/DataObjects/Recv.php
new file mode 100644 (file)
index 0000000..b0897e5
--- /dev/null
@@ -0,0 +1,523 @@
+<?php
+/**
+ * Table Definition for recv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Recv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'recv';                // table name
+    public $recv_id;                         // int4(4)  not_null default_nextval%28recv_recv_id_seq%29 primary_key
+    public $recv_order_type;                 // text(-1)  not_null multiple_key
+    public $recv_order_number;               // text(-1)  not_null
+    public $recv_orderitem_id;               // int4(4)  not_null multiple_key
+    public $recv_agent_username;             // text(-1)  
+    public $recv_itemsite_id;                // int4(4)  
+    public $recv_vend_id;                    // int4(4)  
+    public $recv_vend_item_number;           // text(-1)  
+    public $recv_vend_item_descrip;          // text(-1)  
+    public $recv_vend_uom;                   // text(-1)  
+    public $recv_purchcost;                  // numeric(-1)  
+    public $recv_purchcost_curr_id;          // int4(4)  
+    public $recv_duedate;                    // date(4)  
+    public $recv_qty;                        // numeric(-1)  
+    public $recv_recvcost;                   // numeric(-1)  
+    public $recv_recvcost_curr_id;           // int4(4)  
+    public $recv_freight;                    // numeric(-1)  
+    public $recv_freight_curr_id;            // int4(4)  
+    public $recv_date;                       // timestamptz(8)  
+    public $recv_value;                      // numeric(-1)  
+    public $recv_posted;                     // bool(1)  not_null default_false
+    public $recv_invoiced;                   // bool(1)  not_null default_false
+    public $recv_vohead_id;                  // int4(4)  
+    public $recv_voitem_id;                  // int4(4)  
+    public $recv_trans_usr_name;             // text(-1)  not_null default_%22current_user%22%28%29
+    public $recv_notes;                      // text(-1)  
+    public $recv_gldistdate;                 // date(4)  
+    public $recv_splitfrom_id;               // int4(4)  
+    public $recv_rlsd_duedate;               // date(4)  
+    public $recv_recvgrp_id;               // date(4)  
+    
+   /**
+    * Getter / Setter for $recv_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freight_curr() {
+        return func_num_args() ? $this->link('recv_freight_curr_id', func_get_arg(0)) : $this->link('recv_freight_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('recv_itemsite_id', func_get_arg(0)) : $this->link('recv_itemsite_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_purchcost_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function purchcost_curr() {
+        return func_num_args() ? $this->link('recv_purchcost_curr_id', func_get_arg(0)) : $this->link('recv_purchcost_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_recvcost_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function recvcost_curr() {
+        return func_num_args() ? $this->link('recv_recvcost_curr_id', func_get_arg(0)) : $this->link('recv_recvcost_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_splitfrom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function splitfrom() {
+        return func_num_args() ? $this->link('recv_splitfrom_id', func_get_arg(0)) : $this->link('recv_splitfrom_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_vend_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vend() {
+        return func_num_args() ? $this->link('recv_vend_id', func_get_arg(0)) : $this->link('recv_vend_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_vohead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vohead() {
+        return func_num_args() ? $this->link('recv_vohead_id', func_get_arg(0)) : $this->link('recv_vohead_id');
+    }
+
+   /**
+    * Getter / Setter for $recv_voitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function voitem() {
+        return func_num_args() ? $this->link('recv_voitem_id', func_get_arg(0)) : $this->link('recv_voitem_id');
+    }
+    /**
+    * Getter / Setter for $recv_recvgrp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function recvgrp() {
+        return func_num_args() ? $this->link('recv_vrecvgrp_id', func_get_arg(0)) : $this->link('recv_recvgrp_id');
+    }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (isset($q['recv_orderitem_id_poitem_pohead_id'])) {
+            $this->joinAddPoitem();
+            $this->joinAdditem();
+            $this->whereAdd('join_recv_orderitem_id_poitem_id.poitem_pohead_id = ' .
+                            (int)$q['recv_orderitem_id_poitem_pohead_id']);
+            
+        }
+        
+        
+    }
+    function joinAdditem()
+    {
+        $this->_join .= "
+            LEFT JOIN item AS join_recv_item
+                    ON (join_recv_item.item_id =join_recv_itemsite_id_itemsite_id.itemsite_item_id)
+        ";
+        $t = DB_DataObject::Factory('item');
+        $this->selectAs($t, '%s', 'join_recv_item');
+        
+    }
+    function joinAddPoitem()
+    {
+        $this->_join .= "
+            LEFT JOIN poitem AS join_recv_orderitem_id_poitem_id
+                    ON (join_recv_orderitem_id_poitem_id.poitem_id=recv.recv_orderitem_id)
+        ";
+        $t = DB_DataObject::Factory('poitem');
+        $this->selectAs($t, 'recv_orderitem_id_%s', 'join_recv_orderitem_id_poitem_id');
+       // $this->
+        
+        
+        
+    }
+    
+    function orderitem() {
+        $poitem = DB_DataObject::factory('poitem');
+        $poitem->get($this->recv_orderitem_id);
+        return $poitem;
+    }
+    
+    function createFromShipItem($roo,   $shipitem, $poitem)
+    {
+        $po = $poitem->pohead();
+        
+        $poid = $po->pid();
+        
+        $shiphead = $shipitem->shiphead();
+        
+        $coitem = $shipitem->orderitem();
+        $loc = $coitem->coitem_location_src;
+        
+        // see if we have a recvgrp for it..
+        $rg = DB_DataObject::Factory('recvgrp');
+        if (!$rg->get('recvgrp_number', 'XF-' . $shiphead->shiphead_number)) {
+            $rg->recvgrp_number =  'XF-' .$shiphead->shiphead_number;
+            $rg->insert();
+        }
+        
+        
+        
+        
+        // where are we going to locate it from..
+        
+        //DB_DataObject::debugLevel(1);
+        
+      
+        
+        // see if it's already been entered...
+        $d = DB_DataObject::factory('recv');
+        $d->setFrom(array(
+            'recv_order_type' => 'PO',
+            'recv_orderitem_id' =>  $poitem->pid(),
+           // 'recv_qty' =>           $shipitem->shipitem_qty,
+            'recv_purchcost_curr_id' => $po->pohead_curr_id,
+            'recv_recvgrp_id' =>  $rg->pid()
+        ));
+        
+        // has it already been created???
+       
+        if ($d->count()) {
+            $d->find(true);
+            
+            $d->updateQuantity($roo, $shipitem->shipitem_qty);
+            
+            return $d->recv_id;
+        }
+         
+          
+          
+        return  $this->enterReceipt($roo,
+                        $rg,
+                        $poitem->pid(),
+                        $shipitem->shipitem_qty,
+                        'auto recv for shipitem ' . $shipitem->pid(),
+                        $po->pohead_curr_id,
+                        $poitem->poitem_duedate,
+                        $loc);
+          
+         
+    }
+    
+    
+    
+    
+    function enterReceipt($roo, $rg, $poitem_id, $qty, $notes, $curr_id, $date, $loc )
+    {
+        $notes = $this->escape($notes);
+        //DB_DataObject::DebugLevel(1);
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT enterReceipt('PO',
+                        {$poitem_id},
+                        {$qty}, 0,
+                        '$notes', {$curr_id},
+                        '{$date}'
+                    ) AS result");
+        $d->fetch();
+        
+        $recvid = empty($d->result) ? 0 : $d->result;
+        if (empty($recvid) || $recvid < 1) {
+            $roo->jerr("enterReceipt returned {$recvid}");
+        }
+        // ensure we can identify it later..
+        $d = DB_DataObject::factory('recv');
+        $d->get($recvid);
+        $dd = clone($d);
+        
+        if (!$dd->itemsite()->itemsite_loccntrl) {
+            $roo->jerr("Item ".$dd->itemsite()->item()->item_number .
+                       " Is not flagged for Multiple Location Control - under Item .. Inventory .. Location" );
+        }
+        
+        $d->recv_recvgrp_id =  $rg->pid();
+        $d->update($dd);
+        
+         
+        
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT postReceipt(recv_id, 0) AS result FROM recv WHERE (recv_id={$recvid}) ");
+        $d->fetch();
+        
+        if (empty( $d->result) ||  $d->result < 1) {
+            $roo->jerr("enterReceipt returned { $d->result}");
+        }
+        
+        $itemlocdist_series = $d->result;
+        
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT itemlocdist_id,
+                  itemlocdist_reqlotserial,
+                  itemlocdist_distlotserial,
+                  itemlocdist_qty,
+                  itemsite_loccntrl,
+                  itemsite_controlmethod,
+                itemsite_perishable,
+                itemsite_warrpurc,
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                FROM itemlocdist, itemsite
+                WHERE ( (itemlocdist_itemsite_id=itemsite_id) AND (itemlocdist_series={$itemlocdist_series }) ) ORDER BY itemlocdist_id
+                ");
+        $d->fetch();
+        
+        if (empty( $d->itemlocdist_id) ||  $d->itemlocdist_id < 1) {
+            $roo->jerr("SEARCHING FOR itemlocdist_id  returned " . ( empty($d->itemlocdist_id) ? 'NOTHING' : $d->itemlocdist_id) . " FOR ".
+                      $dd->itemsite()->item()->item_number 
+                       );
+        }
+        
+        
+        $itemlocdist_id = $d->itemlocdist_id;
+           
+        $d = DB_DataObject::factory('recv');
+        $d->query("INSERT INTO itemlocdist (
+                itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                itemlocdist_source_id,  itemlocdist_qty,
+                itemlocdist_ls_id, itemlocdist_expiration
+            ) SELECT
+                itemlocdist_id,'L',
+                {$loc},       {$qty},
+                itemlocdist_ls_id, endOfTime()
+                FROM itemlocdist WHERE
+                (itemlocdist_id={$itemlocdist_id }) ");
+        
+        // this generates an additional itemlocdist record..
+        // they throw exceptions if things fail.
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+        $d->fetch();
+        if (empty($d->result) || $d->result < 0) {
+            $roo->jerr("distribute to locations failed:" . (int)@$d->result);
+        }
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT postItemlocseries({$itemlocdist_series}) AS result");
+        $d->fetch();
+        if (empty($d->result) || $d->result < 0) {
+            $roo->jerr("post to locations failed:" . (int)@$d->result);
+        }
+     
+        return $recvid;
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    function revertFromShipItem($roo, $po, $shipitem )
+    {
+        
+        $coitem = $shipitem->orderitem();
+        //$roo->jerr(print_R($coitem,true));
+        $shiphead = $shipitem->shiphead();
+        
+        $rg = DB_DataObject::Factory('recvgrp');
+        if (!$rg->get('recvgrp_number', 'XF-' . $shiphead->shiphead_number)) {
+            $roo->jerr("Could not find original ItemReciept group {$shiphead->shiphead_number}");
+        }
+        
+        $recv = DB_DataObject::factory('recv');
+        $note = 'auto recv for shipitem ' . $shipitem->pid();
+        $recv->setFrom(array(
+            'recv_order_type' => 'PO',
+        //    'recv_orderitem_id' =>  $poitem->pid(),
+           // 'recv_qty' =>           $shipitem->shipitem_qty,
+            'recv_purchcost_curr_id' => $po->pohead_curr_id,
+            'recv_notes' =>  $note,
+            'recv_recvgrp_id' => $rg->recvgrp_id, 
+           // 'recv_duedate' =>       $poitem->poitem_duedate,
+        ));
+        // has it already been created???
+       
+        if (!$recv->count()) {
+            
+            
+            $roo->jerr("could not find shipitem as recieved.");
+
+            
+        }
+        $recv->find(true);
+        
+        $recv->updateQuantity($roo, 0);
+        // got it.. 
+  
+    }
+    
+    
+    function invdetail($roo)
+    {
+        
+        $poitem = $this->orderitem();
+        
+        $po = $poitem->pohead();
+        $number  = $po->pohead_number;
+        
+        $rg = DB_DataObject::Factory('recvgrp');
+        if ($this->recv_recvgrp_id &&  $rg->get($this->recv_recvgrp_id)) {
+            $number =  $rg->recvgrp_number;
+            
+        //    $roo->jerr("Could not find original ItemReciept group");
+        }
+        
+        
+        
+        $invhist = DB_DAtaObject::Factory('invhist');
+        $invhist->setFrom(array( 
+            'invhist_ordnumber' => $number . '-' . $poitem->poitem_linenumber,
+            'invhist_ordtype' => 'PO',
+            'invhist_itemsite_id' => $poitem->poitem_itemsite_id,
+        ));
+        
+        $invhist->orderBy('invhist_id DESC'); // last entry..
+        $invhist->limit(1);
+        if (!$invhist->find(true)) {
+            $roo->jerr("Could not find invhist previous transaction {$rg->recvgrp_number} / {$poitem->poitem_itemsite_id}");
+        }
+        
+        $ivd = DB_DataObject::Factory('invdetail');
+        $ivd->invdetail_invhist_id = $invhist->pid();
+        $ivd->whereAdd('invdetail_location_id IS NOT NULL AND invdetail_location_id > 0');
+        $ivd->limit(1);
+        if (!$ivd->count()) {
+            $roo->jerr("Could not find location of previous item reciept");
+        }
+        $ivd->find(true);
+        return $ivd;
+        
+        
+        
+    }
+    
+    
+    
+    function updateQuantity($roo, $newqty)
+    {
+        if ($newqty == $this->recv_qty) {
+            // no change in quantity
+            return true;
+        }
+        
+        //correctReceipt(previous_recv_id, pQty, pFreight, _itemlocseries, curr_id, pEffective
+        // this actually modfies the recv...
+        // calls postinvtrans
+        $poitem = $this->orderitem();
+        $pohead = $poitem->pohead();
+        
+        
+        // finding invhist data for this...
+        // which should provide the location.
+        $ivd = $this->invdetail($roo);
+        
+       
+         
+         
+        
+        // $roo->jerr(print_R($details,true));
+        
+        $loc = $ivd->invdetail_location_id;
+        
+        $change = $newqty - $this->recv_qty;
+        
+        $cor =  DB_DataObject::factory('recv');
+        
+        $cor->query("  SELECT correctReceipt(
+                    {$this->pid()} , {$newqty}, 0, 0, $pohead->pohead_curr_id,  '{$this->recv_duedate}') AS result
+                ");
+        $cor->fetch();
+        if (empty($cor->result) || $cor->result < 1)  {
+            $roo->jerr("correctReciept returned {$cor->result}");
+        }
+        
+        $itemlocdist_series = $cor->result;
+         
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT itemlocdist_id,
+                  itemlocdist_reqlotserial,
+                  itemlocdist_distlotserial,
+                  itemlocdist_qty,
+                  itemsite_loccntrl,
+                  itemsite_controlmethod,
+                  itemsite_perishable,
+                   itemsite_warrpurc,
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                FROM itemlocdist, itemsite
+                WHERE ( (itemlocdist_itemsite_id=itemsite_id) AND (itemlocdist_series={$itemlocdist_series }) ) ORDER BY itemlocdist_id
+                ");
+        $d->fetch();
+        
+        if (empty( $d->itemlocdist_id) ||  $d->itemlocdist_id < 1) {
+            $roo->jerr("SEARCHING FOR itemlocdist_id  returned { $d->itemlocdist_id}");
+        }
+        
+        
+        $itemlocdist_id = $d->itemlocdist_id;
+         
+        $d = DB_DataObject::factory('recv');
+        $d->query("INSERT INTO itemlocdist (
+                itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                itemlocdist_source_id,  itemlocdist_qty,
+                itemlocdist_ls_id, itemlocdist_expiration
+            ) SELECT
+                itemlocdist_id,'L',
+                {$loc},       {$change},
+                itemlocdist_ls_id, endOfTime()
+                FROM itemlocdist WHERE
+                (itemlocdist_id={$itemlocdist_id }) ");
+        
+        // this generates an additional itemlocdist record..
+        // they throw exceptions if things fail.
+        
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+        $d = DB_DataObject::factory('recv');
+        $d->query("SELECT postItemlocseries({$itemlocdist_series}) AS result");
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Recvgrp.php b/DataObjects/Recvgrp.php
new file mode 100644 (file)
index 0000000..e800c1c
--- /dev/null
@@ -0,0 +1,705 @@
+<?php
+/**
+ * Table Definition for recv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Recvgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'recvgrp';                // table name
+    public $recvgrp_id;                         // int4(4)  not_null default_nextval%28recv_recv_id_seq%29 primary_key
+    public $recvgrp_number;               // text(-1)  not_null
+    public $recvgrp_pohead_id;               // text(-1)  not_null
+    public $recvgrp_date;               // text(-1)  not_null
+    public $recvgrp_landed_cost;               // text(-1)  not_null
+    public $recvgrp_landed_method;               // text(-1)  not_null
+    public $recvgrp_void;               // text(-1)  not_null
+    public $recvgrp_location_id;
+    public $recvgrp_receipt_number;     // TEXT
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (!empty($q['_landed_vohead'])) {
+            // fill in the assigned values for
+            $vo = (int)$q['_landed_vohead'];
+            
+            $vohead = DB_DataObject::factory('vohead');
+            $vohead->get($q['_landed_vohead']);
+            $cost = $vohead->costofshipping();
+            $assigned =  $vohead->assignedcost();
+            
+            
+            if ( ($cost - $assigned) < 1.0) {
+                $this->whereAdd("
+                 recvgrp_id IN (SELECT   recvgrpland_recvgrp_id FROM
+                    recvgrpland  WHERE
+                        recvgrpland_vohead_id = $vo
+                        )
+                ");
+                
+            }
+            
+            if (empty($q['_search'])) {
+            
+                $this->whereAdd("
+                                
+                       recvgrp_date < ('{$vohead->vohead_gldistdate}'::date + INTERVAL '1 MONTH')::date
+                       AND
+                       recvgrp_date > ('{$vohead->vohead_gldistdate}'::date - INTERVAL '4 MONTH')::date
+                       
+                ");
+            }            
+            $this->whereAdd("
+                    (SELECT count(recv_qty) FROM recv  WHERE recv_recvgrp_id = recvgrp_id AND recv_posted) > 0
+                    AND
+                    (recvgrp_void = 0 OR recvgrp_void IS NULL)
+            ");
+            
+            $this->autoJoinVendor();
+            
+            $this->selectAdd("
+                             
+                COALESCE((SELECT sum(currtobase(recvgrpland_curr_id, recvgrpland_cost, vohead_gldistdate))
+                    FROM
+                        recvgrpland
+                    LEFT JOIN
+                        vohead
+                    ON
+                        recvgrpland_vohead_id = vohead_id
+                    WHERE
+                        recvgrpland_vohead_id = $vo
+                    AND
+                        recvgrpland_recvgrp_id = recvgrp_id 
+                ), 0) as assigned_landed,
+                
+                
+                (SELECT sum(recv_qty) FROM recv  WHERE recv_recvgrp_id = recvgrp_id AND recv_posted)  as recv_qty
+                
+                             
+            ");
+            
+            $this->orderBy("
+                             
+                COALESCE((SELECT sum(recvgrpland_cost) FROM   recvgrpland
+                    WHERE
+                        recvgrpland_vohead_id = $vo
+                    AND
+                        recvgrpland_recvgrp_id = recvgrp_id 
+                ), 0) DESC,
+                
+                join_vendinfo.vend_name ASC
+                             
+            ");
+            
+            
+            
+            
+            
+            
+        }
+        $this->selectAdd("
+            (SELECT curr_symbol from curr_symbol where curr_base LIMIT 1)  base_curr_symbol,
+            
+            ROUND ((SELECT
+                    sum(
+                        CASE WHEN recvgrpland_glseries = 0 THEN 0 ELSE
+                            currtobase(recvgrpland_curr_id,  recvgrpland_cost,   gltrans_date)
+                        END 
+                    )
+                FROM
+                    recvgrpland
+                LEFT JOIN
+                    gltrans
+                ON
+                    gltrans_sequence = recvgrpland_glseries
+                    AND
+                    gltrans_amount > 0
+                
+                WHERE
+                     recvgrpland_recvgrp_id = recvgrp_id
+
+                    
+            ),2) as total_landed_cost
+        ");
+        
+        
+        
+        if (!empty($q['_search'])) {
+            $v = $this->escape($q['_search']);
+            $this->whereAdd("
+                      join_vendinfo.vend_name ilike '%{$v}%'
+                      OR
+                      recvgrp_number like '%{$v}%'
+                      OR
+                      
+                       join_recvgrp_pohead_id_pohead_id.pohead_number ilike '%{$v}%'
+                          
+                    ");
+        
+            
+            
+            
+        }
+        $this->autoJoinPoheadcurr();
+        
+    }
+    function autoJoinPoheadcurr()
+    {
+        
+        $v = DB_DataObject::Factory('curr_symbol');
+        $this->_join .= '
+            LEFT JOIN curr_symbol join_pohead_curr_symbol ON
+                join_recvgrp_pohead_id_pohead_id.pohead_curr_id = join_pohead_curr_symbol.curr_id
+            
+        ';
+        $this->selectAs($v, 'pohead_curr_id_%s', 'join_pohead_curr_symbol');
+        
+        
+    }
+    
+    function autoJoinVendor()
+    {
+        
+        $v = DB_DataObject::Factory('vendinfo');
+        $this->_join .= '
+            LEFT JOIN vendinfo join_vendinfo ON join_recvgrp_pohead_id_pohead_id.pohead_vend_id = vend_id
+            
+        ';
+        $this->selectAs($v, '%s', 'join_vendinfo');
+        
+        
+    }
+    
+    function beforeInsert($q, $roo) 
+    {
+        if (!isset($q['recv_qtys'])) {
+            $roo->jerr("no qtys'");
+        }
+        // no more session stuff now...
+        $roo->sessionState(0);
+        $this->factory('cohead')->lockTables();
+        $this->processReceipt($roo,$q);
+        
+        $this->jerr("should not get here");
+        
+        
+    }
+    function beforeUpdate($old, $q ,$roo)
+    {
+        if (!empty($q['_void'])) {
+            $this->factory('cohead')->lockTables();
+            $this->void($roo);
+        }
+        
+        // only allow modification of landed stuff..
+        foreach($this->table() as $k => $v) {
+            if (!preg_match('/landed/', $k)) {
+                $this->$k = $old->$k;
+            }
+        }
+        
+        
+        
+    }
+    
+    function nextNumber($po) {
+        $seq =1;
+        while (true) {
+            $rg = DB_DataObject::Factory('recvgrp');
+            if (!$rg->get('recvgrp_number',  $po->pohead_number . '-' . $seq)) {
+                return  $po->pohead_number . '-' . $seq;
+                
+            }
+            $seq++;
+        }
+        // no return... 
+    }
+    
+    
+    function createFromPO($roo, $po, $loc)
+    {
+       
+        
+        $items = $po->items();
+        $dt = date('Y-m-d', strtotime($po->pohead_orderdate));
+        
+        
+        $seq = 1;
+        
+        $rg = DB_DataObject::Factory('recvgrp');
+        
+        $rg->setFrom(array(
+            'recvgrp_number' =>    $this->nextNumber($po),
+            'recvgrp_pohead_id' =>  $po->pohead_id,
+            'recvgrp_date' => $dt,
+            'recvgrp_landed_cost' => 0,
+            //'recvgrp_landed_method;               // text(-1)  not_null
+            //$recvgrp_void;               // text(-1)  not_null
+            'recvgrp_location_id' => $loc->pid()
+        ));
+        $rg->insert();
+        $pid = $rg->pid();
+        
+        $num = $rg->recvgrp_number;
+        $rrg = clone($rg);
+        
+        $rg->recvgrp_number = $num; // make sure it's not overwritten..
+        
+        $rg->update($rrg);
+        
+        
+        //$notes = $this->escape($q['recv_notes']);
+        
+        foreach($items as $i) {
+            $recv = DB_DataObject::factory('recv');
+            
+            $recv->enterReceipt(
+                    $roo,
+                    $rg,
+                    $i->poitem_id,
+                    $i->poitem_qty_ordered,
+                    'Auto created from Transfer',
+                    $po->pohead_curr_id,
+                    $dt,
+                    $loc->pid()
+            );
+                
+             
+        }
+        $rg = DB_DataObject::Factory('recvgrp');
+        $rg->get($pid);
+        return $rg;
+        
+    }
+    
+    
+    function pohead()
+    {
+        $d = DB_DataObjecT::factory('pohead');
+        $d->get($this->recvgrp_pohead_id);
+        return $d;
+    }
+    // update can not modify reciept...
+    
+    
+    function processReceipt($roo, $q)
+    {
+        
+        $po = DB_DataObject::Factory('pohead');
+        if (!$po->get($q['recvgrp_pohead_id'])) {
+            $roo->jerr("invalid pohead");
+        }
+        $items = json_decode($q['recv_qtys']);
+        $dt = date('Y-m-d', strtotime($q['recvgrp_date']));
+        
+        $rg = DB_DataObject::Factory('recvgrp');
+        
+        $rg->recvgrp_number =  $this->nextNumber($po);
+        $rg->recvgrp_pohead_id =  $po->pohead_id;
+        $rg->insert();
+         
+        $num = $rg->recvgrp_number;
+        $rrg = clone($rg);
+        
+        $rg->setFrom($q);
+        
+        $rg->recvgrp_number = $num; // make sure it's not overwritten..
+        
+        $rg->update($rrg);
+        
+        $notes = $this->escape($q['recv_notes']);
+        
+        foreach($items as $i) {
+            $recv = DB_DataObject::factory('recv');
+            
+            $recv->enterReceipt(
+                    $roo,
+                    $rg,
+                    $i->recv_orderitem_id,
+                    $i->recv_qty,
+                    $notes,
+                    $po->pohead_curr_id,
+                    $dt,
+                    $q['recvgrp_location_id']
+            );
+                
+             
+        }
+        $roo->jok("posted");
+         
+          
+    }
+    function items()
+    {
+        $d = DB_DataObject::Factory('recv');
+        $d->recv_recvgrp_id = $this->pid();
+        $d->joinAddPoitem();
+        return $d->fetchAll();
+        
+        
+    }
+    
+    function void($roo)
+    {
+        if (!in_array('recvgrp_void', array_keys($this->table()))) {
+            $roo->jerr("system has not been updated with recvgrp_void");
+        }
+        
+        if ($this->recvgrp_void) {
+            $roo->jerr("Already void");
+        }
+        
+        //-- are there any transfers for this order??
+        $it = DB_DataObject::Factory('invhist_transfer_item');
+        $it->autoJoin();
+        $it->selectAdd();
+        $it->selectAdd('SUM(invhist_transfer_item_qty) as in_transit');
+        $it->whereAdd("
+                join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_recvgrp_id = {$this->pid()}
+            AND
+                join_invhist_transfer_item_invhist_transfer_id_invhist_transfer_id.invhist_transfer_id IS NOT NULL
+            AND
+               invhist_transfer_item_invhist_transfer_id IS NOT NULL
+             
+    
+        ");
+        $it->find(true);
+        if (!empty($it->in_transit)) {
+            $roo->jerr("there is an open transfer relating to this order - please void it first");
+        }
+         
+        // check if landed cost assigned to it..
+        $lc = DB_DataObject::Factory('recvgrpland');
+        $lc->recvgrpland_recvgrp_id = $this->recvgrp_id;
+        
+        $olc = clone($lc);
+        
+        $landed_count = $lc->count();
+        
+        $olc->whereAdd('recvgrpland_glseries > 0 OR recvgrpland_cost > 0.0');
+        $posted_landed_count = $olc->count();
+        
+        if ($posted_landed_count ) {
+            
+            $head_ids = $olc->fetchAll('recvgrpland_vohead_id');
+            
+            $vohead = DB_DataObject::factory('vohead');
+            $vohead->whereAddIn('vohead_id', $head_ids, 'int');
+            $vonums = $vohead->fetchAll('vohead_number');
+            
+            $roo->jerr("reciept has landed costs assigned to it - void them first "  . $landed_count  . ' (Vouchers: ' . implode(', ', $vonums) .')');
+        }
+        
+        if ($landed_count) {
+            $olc_ids = $lc->fetchAll('recvgrpland_id');
+            
+            foreach($olc_ids as $olc_id) {
+                $lc = DB_DataObject::Factory('recvgrpland');
+                $lc->get($olc_id);
+                $lc->delete();
+            }
+             
+        }
+        
+        
+        $poid = $this->recvgrp_pohead_id;
+        
+        $rj = DB_DataObject::Factory('rjctcode');
+        if (!$rj->get('rjctcode_code', 'WRONG')) {
+            $roo->jerr('can not find reject code');
+        }
+         
+        //DB_DataObject::debugLevel(1);
+
+        //SELECT enterPoReturn(599, 30, 18) AS result;
+        //poitem_id  qty, rejectcode
+        $loc = $this->recvgrp_location_id;
+        
+        $items = $this->items();
+        if (empty($items)) {
+            $roo->jerr("No items where delivered");
+        }
+        
+        $this->checkLocationStock($roo);
+        
+        foreach($items as $i) {
+            
+            if (!$loc) {
+                $ivd = $i->invdetail($roo);
+                $loc =  $ivd->invdetail_location_id;
+            }
+                
+                
+            $q = DB_DataObject::Factory($this->tableName());
+            $q->query("SELECT enterPoReturn({$i->recv_orderitem_id}, {$i->recv_qty}, {$rj->pid()}, '{$this->recvgrp_date}'::date ) as result");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 1) {
+                $roo->jerr("enterPoReturn failed - returned " . $q->result);
+            }
+        }
+        $q = DB_DataObject::Factory($this->tableName());
+        $q->query("SELECT postPoReturns({$poid},false) AS result");
+        $q->fetch();
+        if (empty($q->result) || $q->result < 1) {
+            $roo->jerr("postPoReturns failed - returned " . $q->result);
+        }
+        $ild = $q->result;
+        
+        $ld = DB_DataObject::Factory('itemlocdist');
+        $ld->itemlocdist_series = $ild;
+        $rev = $ld->fetchAll();
+        
+         
+        
+        foreach($rev as $r)
+        {
+            $ld = DB_DataObject::Factory('itemlocdist');
+            
+            $ld->setFrom( array(
+                    'itemlocdist_itemlocdist_id' => $r->itemlocdist_id,
+                    'itemlocdist_source_type' => 'L',
+                    'itemlocdist_source_id' => $loc , // location.
+                    'itemlocdist_qty' =>   $r->itemlocdist_qty,
+                    'itemlocdist_ls_id' => empty($r->itemlocdist_ls_id) ? $this->sqlValue('NULL') : $r->itemlocdist_ls_id,
+                   // 'itemlocdist_series' =>  $ild,
+            ));
+            $ld->itemlocdist_expiration = $ld->sqlValue('endOfTime()');
+            $ld->insert();
+            
+            
+            $q = DB_DataObject::Factory($this->tableName());
+            $q->query("SELECT distributeToLocations({$r->itemlocdist_id}) AS result");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 1) {
+                $roo->jerr("distributeToLocations failed - returned " . $q->result);
+            }
+        }
+        //$ld = DB_DataObject::Factory('itemlocdist');
+        //$ld 
+        
+        
+   
+        
+        
+        $q = DB_DataObject::Factory($this->tableName());
+        $q->query("SELECT postItemlocseries($ild) AS result");
+        $q->fetch();
+        if (empty($q->result) || $q->result < 1) {
+            $roo->jerr("postItemlocseries failed - returned " . $q->result);
+        }
+        
+        $old = clone($this);
+        $this->recvgrp_void = true;
+        
+        $this->update($old);
+        $roo->jok("voided");
+        
+        
+    } 
+    
+    
+    function checkLocationStock($roo)
+    {
+        if(empty($roo->bootLoader->Xtuple['prevent_negative'])){
+            return;
+        }
+        
+        $items = $this->items();
+        
+        $loc = $this->recvgrp_location_id;
+        
+        $stock = array();
+        
+        foreach ($items as $item){
+            if(empty($item->recv_qty)){
+                continue;
+            }
+            
+            if (!$loc) {
+                $ivd = $item->invdetail($roo);
+                $loc =  $ivd->invdetail_location_id;
+            }
+            
+            $balance = $item->itemsite()->checkLocationStock($loc);
+
+            if(empty($balance) || $balance < $item->recv_qty){
+                $stock[] = $item->itemsite()->item()->item_number;
+            }
+        }
+
+        if(count($stock)){
+            $roo->jerr("These items have negative stock " . implode(', ', $stock));
+        }
+    }
+    
+    
+    
+    
+    // IS THIS NEEDED? - CAN WE VOID AND RE-CREATE...?
+    
+    function voidUntransfered($roo)
+    {
+        
+         
+        $poid = $this->recvgrp_pohead_id;
+        
+        $rj = DB_DataObject::Factory('rjctcode');
+        if (!$rj->get('rjctcode_code', 'WRONG')) {
+            $roo->jerr('can not find reject code');
+        }
+        
+        
+        //DB_DataObject::debugLevel(1);
+
+        //SELECT enterPoReturn(599, 30, 18) AS result;
+        //poitem_id  qty, rejectcode
+        $loc = $this->recvgrp_location_id;
+        
+        $items = $this->items();
+        if (empty($items)) {
+            $roo->jerr("No items where delivered");
+        }
+        
+        foreach($items as $i) {
+            
+            if (!$loc) {
+                $ivd = $i->invdetail($roo);
+                $loc =  $ivd->invdetail_location_id;
+            }
+                
+                
+            $q = DB_DataObject::Factory($this->tableName());
+            $q->query("SELECT enterPoReturn({$i->recv_orderitem_id}, {$i->recv_qty}, {$rj->pid()}, '{$this->recvgrp_date}'::date ) as result");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 1) {
+                $roo->jerr("enterPoReturn failed - returned " . $q->result);
+            }
+        }
+        $q = DB_DataObject::Factory($this->tableName());
+        $q->query("SELECT postPoReturns({$poid},false) AS result");
+        $q->fetch();
+        if (empty($q->result) || $q->result < 1) {
+            $roo->jerr("postPoReturns failed - returned " . $q->result);
+        }
+        $ild = $q->result;
+        
+        $ld = DB_DataObject::Factory('itemlocdist');
+        $ld->itemlocdist_series = $ild;
+        $rev = $ld->fetchAll();
+        
+         
+        
+        foreach($rev as $r)
+        {
+            $ld = DB_DataObject::Factory('itemlocdist');
+            
+            $ld->setFrom( array(
+                    'itemlocdist_itemlocdist_id' => $r->itemlocdist_id,
+                    'itemlocdist_source_type' => 'L',
+                    'itemlocdist_source_id' => $loc , // location.
+                    'itemlocdist_qty' =>   $r->itemlocdist_qty,
+                    'itemlocdist_ls_id' => empty($r->itemlocdist_ls_id) ? $this->sqlValue('NULL') : $r->itemlocdist_ls_id,
+                   // 'itemlocdist_series' =>  $ild,
+            ));
+            $ld->itemlocdist_expiration = $ld->sqlValue('endOfTime()');
+            $ld->insert();
+            
+            
+            $q = DB_DataObject::Factory($this->tableName());
+            $q->query("SELECT distributeToLocations({$r->itemlocdist_id}) AS result");
+            $q->fetch();
+            if (empty($q->result) || $q->result < 1) {
+                $roo->jerr("distributeToLocations failed - returned " . $q->result);
+            }
+        }
+        //$ld = DB_DataObject::Factory('itemlocdist');
+        //$ld 
+        
+        
+   
+        
+        
+        $q = DB_DataObject::Factory($this->tableName());
+        $q->query("SELECT postItemlocseries($ild) AS result");
+        $q->fetch();
+        if (empty($q->result) || $q->result < 1) {
+            $roo->jerr("postItemlocseries failed - returned " . $q->result);
+        }
+        
+        $old = clone($this);
+        $this->recvgrp_void = true;
+        
+        $this->update($old);
+        $roo->jok("voided");
+        
+        
+    }   
+    
+    
+}
+
+/*
+ FIX recvgrps
+    UPDATE recv
+        SET recv_recvgrp_id  =
+            CASE WHEN (SELECT count(recvgrp_id) FROM recvgrp WHERE recvgrp_pohead_id = (SELECT poitem_pohead_id FROM poitem where poitem_id = recv_orderitem_id) AND recvgrp_date = recv_date ) = 1 THEN
+                (SELECT recvgrp_id  FROM recvgrp WHERE recvgrp_pohead_id = (SELECT poitem_pohead_id FROM poitem where poitem_id = recv_orderitem_id ) AND recvgrp_date = recv_date)
+            ELSE
+                NULL
+            END
+    WHERE
+        recv_recvgrp_id IS NULL;
+        
+        
+    UPDATE recv
+        SET recv_recvgrp_id  =
+        
+            
+        
+            CASE WHEN
+                (SELECT
+                   count(recvgrp_id)
+                FROM
+                    recvgrp
+                WHERE
+                    recvgrp_number = (SELECT tranid from   netsuite_itemreceipt WHERE id =   (SELECT itemreceipt_id FROM netsuite_itemreceiptitem WHERE  id::text = recv_oldid ))
+                    AND
+                    recvgrp_pohead_id = (SELECT poitem_pohead_id FROM poitem where poitem_id = recv_orderitem_id) AND recvgrp_date = recv_date
+               )  = 1
+            THEN
+                (SELECT
+                    recvgrp_id
+                FROM
+                    recvgrp
+                WHERE
+                    recvgrp_number = (SELECT tranid from   netsuite_itemreceipt WHERE id =   (SELECT itemreceipt_id FROM netsuite_itemreceiptitem WHERE  id::text = recv_oldid ))
+                    AND
+                    recvgrp_pohead_id = (SELECT poitem_pohead_id FROM poitem where poitem_id = recv_orderitem_id) AND recvgrp_date = recv_date
+               )
+            ELSE
+                NULL
+            END
+    WHERE
+        recv_recvgrp_id IS NULL;
+            
+        
+   
+    select recv_id, recv_orderitem_id, (SELECT count(recvgrp_id) FROM recvgrp WHERE recvgrp_pohead_id = (SELECT poitem_pohead_id FROM poitem where poitem_id = recv_orderitem_id) AND recvgrp_date = recv_date ) from recv where recv_recvgrp_id  IS NULL;
+
+    
+    // the remaining ones are our fake vendor bills... 
+ */
diff --git a/DataObjects/Recvgrpland.php b/DataObjects/Recvgrpland.php
new file mode 100644 (file)
index 0000000..dc3c482
--- /dev/null
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Table Definition for recv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Recvgrpland extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'recvgrpland';                // table name
+    public $recvgrpland_id;                         // int4(4)  not_null default_nextval%28recv_recv_id_seq%29 primary_key
+    public $recvgrpland_vohead_id;               // text(-1)  not_null
+    public $recvgrpland_recvgrp_id;               // text(-1)  not_null
+    public $recvgrpland_date;               // text(-1)  not_null
+    public $recvgrpland_cost;               // text(-1)  not_null
+    public $recvgrpland_curr_id;               // text(-1)  not_null
+
+    public $recvgrpland_method;               // text(-1)  not_null
+    public $recvgrpland_glseries;
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function vohead()
+    {
+        $vo = DB_DataObject::Factory('vohead');
+        $vo->get($this->recvgrpland_vohead_id);
+        return $vo;
+    }
+    function recvgrp()
+    {
+        $vo = DB_DataObject::Factory('recvgrp');
+        $vo->get($this->recvgrpland_recvgrp_id);
+        return $vo;
+    }
+    
+    function applyFilters($q, $au, $roo)
+    {
+         
+            
+         
+        
+        
+    }
+    
+    function onInsert($q, $roo)
+    {
+        
+        if (!empty($q['_void'])) {
+            
+            $t = DB_DataObject::Factory($this->tableName());
+            $t->recvgrpland_recvgrp_id = $q['recvgrpland_recvgrp_id'];
+            $t->recvgrpland_vohead_id = $q['recvgrpland_vohead_id'];
+            $t->whereAdd('recvgrpland_glseries != 0');
+            
+            if (!$t->find(true)) {
+                $roo->jerr("could not find existing transaction");
+            }
+            if (empty($t->recvgrpland_glseries)) {
+                $roo->jerr("recvgrpland_glseries was not set?");
+            }
+            //DB_DataObject::debugLevel(1);
+            $gl = DB_DataObject::factory('gltrans');
+            $gl->gltrans_sequence= $t->recvgrpland_glseries;
+            $gl->limit(1);
+            if (!$gl->find(true)) {
+                $roo->jerr("no transaction found");
+            }
+            //print_R($gl);exit;
+            
+            $gl->void($roo, true, 'landed cost reversed');
+            $t->delete();
+            $roo->jok("DELETED");
+            
+        }
+        
+        // post...
+        
+        $vo = $this->vohead();
+        
+        $cos_accnt_id = $vo->costofshippingaccnt();
+        
+        // inventory..
+        $costcat = DB_DataObject::Factory('costcat');
+        $costcat->limit(1);
+        $costcat->find(true);
+        $asset_accnt_id = $costcat->costcat_asset_accnt_id;
+        
+        
+        $rg = $this->recvgrp();
+        $gl = DB_DataObject::factory('gltrans');
+        $series = $gl->newJournalEntry($roo,
+                    array(
+                        'memo' => 'COS-'. $this->pid(),
+                        'notes' => 'Cost of freight application - VO#' . $vo->vohead_number .' to IR#' . $rg->recvgrp_number,
+                        'date' => $vo->vohead_distdate,
+                        'lines' => array(
+                            array(
+                                'accnt_id' => $cos_accnt_id,
+                                'amount' => " currtobase({$this->recvgrpland_curr_id}, {$this->recvgrpland_cost}, '{$vo->vohead_gldistdate}' ) ",
+                                
+                            ),
+                            
+                            array(
+                                'accnt_id' => $asset_accnt_id,
+                                'amount' => "-1 * currtobase({$this->recvgrpland_curr_id}, {$this->recvgrpland_cost}, '{$vo->vohead_gldistdate}' ) ",
+                            ),
+                        )
+                    )
+        );
+        $xx = clone($this);
+        $this->recvgrpland_glseries = $series;
+        $this->update($xx);
+        
+         
+        
+    }
+    
+    function beforeDelete($deps, $roo)
+    {
+        $roo->jerr("access denied");
+      
+        
+    }
+     
+    
+    
+    
+    
+} 
+
diff --git a/DataObjects/Remitto.php b/DataObjects/Remitto.php
new file mode 100644 (file)
index 0000000..9a71e26
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for remitto
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Remitto extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'remitto';             // table name
+    public $remitto_name;                    // text(-1)  
+    public $remitto_address1;                // text(-1)  
+    public $remitto_address2;                // text(-1)  
+    public $remitto_address3;                // text(-1)  
+    public $remitto_citystatezip;            // text(-1)  
+    public $remitto_country;                 // text(-1)  
+    public $remitto_phone;                   // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Report.php b/DataObjects/Report.php
new file mode 100644 (file)
index 0000000..06a289e
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for report
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Report extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'report';              // table name
+    public $report_id;                       // int4(4)  not_null default_nextval%28%28report_report_id_seq%29%3A%3Aregclass%29 primary_key
+    public $report_name;                     // text(-1)  unique_key multiple_key
+    public $report_sys;                      // bool(1)  
+    public $report_source;                   // text(-1)  
+    public $report_descrip;                  // text(-1)  
+    public $report_grade;                    // int4(4)  not_null unique_key multiple_key
+    public $report_loaddate;                 // timestamp(8)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Rjctcode.php b/DataObjects/Rjctcode.php
new file mode 100644 (file)
index 0000000..81989e3
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for rjctcode
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Rjctcode extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'rjctcode';            // table name
+    public $rjctcode_id;                     // int4(4)  not_null default_nextval%28%28%22rjctcode_rjctcode_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $rjctcode_code;                   // text(-1)  unique_key
+    public $rjctcode_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Rsncode.php b/DataObjects/Rsncode.php
new file mode 100644 (file)
index 0000000..8a0a598
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for rsncode
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Rsncode extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'rsncode';             // table name
+    public $rsncode_id;                      // int4(4)  not_null default_nextval%28rsncode_rsncode_id_seq%29 primary_key
+    public $rsncode_code;                    // text(-1)  not_null
+    public $rsncode_descrip;                 // text(-1)  
+    public $rsncode_doctype;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Sale.php b/DataObjects/Sale.php
new file mode 100644 (file)
index 0000000..8a4ddc0
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for sale
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Sale extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'sale';                // table name
+    public $sale_id;                         // int4(4)  not_null default_nextval%28%28%22sale_sale_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $sale_name;                       // text(-1)  
+    public $sale_descrip;                    // text(-1)  
+    public $sale_ipshead_id;                 // int4(4)  
+    public $sale_startdate;                  // date(4)  
+    public $sale_enddate;                    // date(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Salesaccnt.php b/DataObjects/Salesaccnt.php
new file mode 100644 (file)
index 0000000..13168c7
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for salesaccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Salesaccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'salesaccnt';          // table name
+    public $salesaccnt_id;                   // int4(4)  not_null default_nextval%28%28%22salesaccnt_salesaccnt_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $salesaccnt_custtype_id;          // int4(4)  
+    public $salesaccnt_prodcat_id;           // int4(4)  
+    public $salesaccnt_warehous_id;          // int4(4)  
+    public $salesaccnt_sales_accnt_id;       // int4(4)  
+    public $salesaccnt_credit_accnt_id;      // int4(4)  
+    public $salesaccnt_cos_accnt_id;         // int4(4)  
+    public $salesaccnt_custtype;             // text(-1)  
+    public $salesaccnt_prodcat;              // text(-1)  
+    public $salesaccnt_returns_accnt_id;     // int4(4)  
+    public $salesaccnt_cor_accnt_id;         // int4(4)  
+    public $salesaccnt_cow_accnt_id;         // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $salesaccnt_cor_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cor_accnt() {
+        return func_num_args() ? $this->link('salesaccnt_cor_accnt_id', func_get_arg(0)) : $this->link('salesaccnt_cor_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $salesaccnt_cow_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cow_accnt() {
+        return func_num_args() ? $this->link('salesaccnt_cow_accnt_id', func_get_arg(0)) : $this->link('salesaccnt_cow_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $salesaccnt_returns_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function returns_accnt() {
+        return func_num_args() ? $this->link('salesaccnt_returns_accnt_id', func_get_arg(0)) : $this->link('salesaccnt_returns_accnt_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults()
+    {
+        $defaults = array(
+            'salesaccnt_custtype_id' => -1,
+            'salesaccnt_prodcat_id' => -1,
+            'salesaccnt_warehous_id' => -1,
+            'salesaccnt_custtype' => '.*',
+            'salesaccnt_prodcat' => '.*'
+        );  
+        
+        return $defaults;
+    }
+}
diff --git a/DataObjects/Salescat.php b/DataObjects/Salescat.php
new file mode 100644 (file)
index 0000000..71f7127
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for salescat
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Salescat extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'salescat';            // table name
+    public $salescat_id;                     // int4(4)  not_null default_nextval%28salescat_salescat_id_seq%29 primary_key
+    public $salescat_active;                 // bool(1)  
+    public $salescat_name;                   // text(-1)  
+    public $salescat_descrip;                // text(-1)  
+    public $salescat_sales_accnt_id;         // int4(4)  
+    public $salescat_prepaid_accnt_id;       // int4(4)  
+    public $salescat_ar_accnt_id;            // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Salesforecast.php b/DataObjects/Salesforecast.php
new file mode 100644 (file)
index 0000000..e6d6ffe
--- /dev/null
@@ -0,0 +1,1028 @@
+<?php
+/**
+ * Table Definition for salesforecast
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Salesforecast extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'salesforecast';          // table name
+    public $salesforecast_id;                   // integer
+    public $salesforecast_itemsite_id;          // integer 
+    public $salesforecast_period_id;            // integer
+    public $salesforecast_qty;                  // integer
+    public $salesforecast_updated_by;           // integer 
+    public $salesforecast_cust_id;              // integer 
+    public $salesforecast_requests;             //integer
+
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au, $roo)
+    {
+        if(isset($q['_download'])){ // for download
+            $this->download($q, $roo);
+        }
+        
+        if(!empty($q['_detailView'])){
+            $this->_join .= "
+                LEFT JOIN
+                    itemsrc AS join_itemsrc
+                ON
+                    join_itemsrc.itemsrc_item_id = join_salesforecast_itemsite_id_itemsite_id.itemsite_item_id
+            ";
+            $this->salesforecast_cust_id = $q['_in_cust_id'];
+            $this->salesforecast_is_all_buyers = $q['_is_all_buyers'];
+            $this->whereAdd("
+                join_itemsrc.itemsrc_active = TRUE
+                AND
+                join_salesforecast_itemsite_id_itemsite_id.itemsite_stocked = TRUE
+                AND
+                join_salesforecast_itemsite_id_itemsite_id.itemsite_item_id = {$this->escape($q['_item_id'])} 
+                AND
+                (
+                    extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW())
+                    OR
+                    extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW() + INTERVAL '1 YEAR')
+                )
+            ");
+            $this->selectAdd();
+            $this->selectAdd("
+                salesforecast_id,
+                extract(year from join_salesforecast_period_id_period_id.period_start) as year,
+                extract(month from join_salesforecast_period_id_period_id.period_start) as month,
+                salesforecast_sum,
+                salesforecast_qty,
+                salesforecast_requests
+            ");
+            
+            return;
+        }
+    }
+    
+
+    function postListFilter($ar, $au, $q)
+    {   
+        if(!empty($q['_detailView'])){
+            $q['_item_id'] = (int) $q['_item_id'];
+            $q['_in_cust_id'] = (int) $q['_in_cust_id'];
+           
+            $cust_str = "invchead_cust_id = {$q['_in_cust_id']}";
+           
+            if($q['_in_cust_id'] == 0){
+                $cust_str = "";
+                if($q['_is_all_buyers'] == 0){
+                    $ci = DB_DataObject::factory('custinfo');
+                    $ids = $ci->topCustomerIdsBySalesQty();
+
+                    $list_ids = implode(',', $ids);
+                    $cust_str = "invchead_cust_id NOT IN ({$list_ids})";
+                }
+            }
+           
+            $ii = DB_DataObject::factory('invcitem');
+            $ii->_join .= "
+                LEFT JOIN 
+                    invchead 
+                ON 
+                    invcitem_invchead_id = invchead_id
+                LEFT JOIN
+                    itemsite
+                ON
+                    invcitem_item_id = itemsite_item_id
+            ";
+            $ii->selectAdd();
+            $ii->selectAdd("
+                extract(year from invchead.invchead_invcdate) as year,
+                extract(month from invchead.invchead_invcdate) as month,
+                ROUND(COALESCE(SUM(invcitem.invcitem_billed),0)) AS total
+            ");
+            $ii->whereAdd("
+                itemsite_stocked = TRUE
+                AND
+                invcitem_item_id = {$this->escape($q['_item_id'])}
+                AND
+                extract(year from invchead.invchead_invcdate) >= extract(year from NOW() - INTERVAL '2 YEAR')
+                AND
+                extract(year from invchead.invchead_invcdate) <= extract(year from NOW() + INTERVAL '1 YEAR')
+            ");
+
+            if(!empty($cust_str)){
+                $ii->whereAdd("{$cust_str}");
+            }
+            
+            
+            $ii->groupBy("year,month");            
+            
+            $billed = $ii->fetchAll(); // this is the actual qty!
+            
+            $year = date('Y');
+            $month = date('m');
+            
+            // define how many years will be show...
+            $years = ($month > 6) ? array($year-2, $year-1, $year, $year+1) : array($year-2, $year-1, $year);
+
+            $r = array(); 
+            
+            $actual = array();
+            
+            foreach ($billed as $b){
+                if($month < 7 && $b->year == $year + 1){ // if current month is not after Jun, we won't show next year
+                    continue;
+                }
+                if(!isset($actual[$b->year])){
+                    $actual[$b->year]['year_text'] = 'Actual ' . $b->year;
+                    $actual[$b->year]['year'] = $b->year;
+                    $actual[$b->year]['type'] = 'actual';
+                }
+                $actual[$b->year]["total_{$b->month}"] = $b->total;
+                
+                if(isset($actual[$b->year]["total_year"])){
+                    $actual[$b->year]["total_year"] += $b->total;
+                    continue;
+                }
+                $actual[$b->year]["total_year"] = $b->total;
+            }
+            
+            foreach ($years as $y){
+                if(isset($actual[$y])){
+                    for($i = 1;$i<=12;$i++){
+                        if(!isset($actual[$y]['total_' . $i])){
+                            $value = '';
+                            if($y < $year){
+                                $value = 0;
+                            }
+                            if($y == $year  && $i > $month){
+                                $value = '';
+                            }
+                            $actual[$y]['total_' . $i] = ($y < $year) ? 0 : (($y == $year && $i > $month) ? '' : (($y > $year) ? '' : 0));
+                        }
+                    }
+                    $r['actual'.$y] = $actual[$y];
+                    continue;
+                }
+                $actual[$y]['year_text'] = 'Actual ' . $y;
+                $actual[$y]['year'] = $y;
+                $actual[$y]['type'] = 'actual';
+                $actual[$y]['total_year'] = ($y > $year) ? '' : 0;
+                for($i = 1;$i<=12;$i++){
+                    $actual[$y]['total_' . $i] = ($y < $year) ? 0 : (($y == $year && $i > $month) ? '' : (($y > $year) ? '' : 0));
+                }
+                $r['actual'.$y] = $actual[$y];
+            }
+            ksort($r); // calc actual
+            
+            $is = DB_DataObject::factory('itemsrc');
+            $is->selectAdd();
+            $is->selectAdd("
+                count(itemsrc_id) as count_itemsrc
+            ");
+            $is->itemsrc_item_id = $q['_item_id'];
+            $is->itemsrc_active = TRUE;
+            
+            if(!$is->count()){
+                return array_values($r);
+            }
+            
+            $nextYearActual = false;
+            
+            if($month > 6){
+                $nextYearActual = array_pop($r);
+            }
+            
+            $currentYearActual = array_pop($r);
+            
+            if($q['_in_cust_id'] > 0){ // company level
+                
+                // push Estimated / Calculated forecast -> $r 
+                
+                
+                $r['estimated'] = array(
+                    'year_text' => 'Estimated / Calculated Forecase ' . $year,
+                    'year' => $year,
+                    'type' => 'estimated',
+                    'total_year' => ($actual[$year-2]['total_year'] + $actual[$year-1]['total_year']) * 1.2
+                );
+                for($i=1;$i<=12;$i++){
+                    $r['estimated']["total_{$i}"] = ($actual[$year-2]["total_{$i}"] + $actual[$year-1]["total_{$i}"]) * 1.2;
+                }
+                
+                // push Regular / Confirmed Forecast -> $r
+                
+                $confirm = array();
+
+                foreach ($ar as $a){
+                    if($month < 7 && $a['year'] == $year + 1){ // if current month is not after Jun, we won't show next year
+                        continue;
+                    }
+                    
+                    if(!isset($confirm[$a['year']])){
+                        $confirm[$a['year']]['year_text'] = 'Regular / Confirmed Forecast ' . $a['year'];
+                        $confirm[$a['year']]['year'] = $a['year'];
+                        $confirm[$a['year']]['type'] = 'confirm';
+                    }
+                    $confirm[$a['year']]["total_{$a['month']}"] = $a['salesforecast_qty'];
+                    $confirm[$a['year']]["total_{$a['month']}_salesforecast_id"] = $a['salesforecast_id'];
+                    if(isset($confirm[$a['year']]["total_year"])){
+                        $confirm[$a['year']]["total_year"] += $a['salesforecast_qty'];
+                        continue;
+                    }
+                    $confirm[$a['year']]["total_year"] = $a['salesforecast_qty'];
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($confirm[$y])){
+                        $confirm[$y]['year_text'] = 'Regular / Confirmed Forecast ' . $y;
+                        $confirm[$y]['year'] = $y;
+                        $confirm[$y]['type'] = 'confirm';
+                        $confirm[$y]["total_year"] = '';
+                    }
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($confirm[$y]["total_{$i}"])){
+                            $confirm[$y]["total_{$i}"] = '';
+                            $confirm[$y]["total_{$i}_salesforecast_id"] = 0;
+                        }
+                    }
+                }
+                
+                // push Special Requests -> $r
+                
+                $request = array();
+
+                foreach ($ar as $a){
+                    if($month < 7 && $a['year'] == $year + 1){ // if current month is not after Jun, we won't show next year
+                        continue;
+                    }
+                    if(!isset($request[$a['year']])){
+                        $request[$a['year']]['year_text'] = 'Special Requests ' . $a['year'];
+                        $request[$a['year']]['year'] = $a['year'];
+                        $request[$a['year']]['type'] = 'request';
+                    }
+                    $request[$a['year']]["total_{$a['month']}"] = $a['salesforecast_requests'];
+                    $request[$a['year']]["total_{$a['month']}_salesforecast_id"] = $a['salesforecast_id'];
+                    if(isset($request[$a['year']]["total_year"])){
+                        $request[$a['year']]["total_year"] += $a['salesforecast_requests'];
+                        continue;
+                    }
+                    $request[$a['year']]["total_year"] = $a['salesforecast_requests'];
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($request[$y])){
+                        $request[$y]['year_text'] = 'Special Requests ' . $y;
+                        $request[$y]['year'] = $y;
+                        $request[$y]['type'] = 'confirm';
+                        $request[$y]["total_year"] = '';
+                    }
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($request[$y]["total_{$i}"])){
+                            $request[$y]["total_{$i}"] = '';
+                            $request[$y]["total_{$i}_salesforecast_id"] = 0;
+                        }
+                    }
+                }
+                
+                
+                // push Total forecast (Regular/Confirmed forecast + Special Request) -> $r
+                
+                $forecast = array();
+                
+                foreach (array_slice($years, 2) as $y){
+                   $forecast[$y] = array(
+                       'year_text' => 'Total forecast ' . $y,
+                       'year' => $y,
+                       'type' => 'forecast',
+                       'total_year' => $confirm[$y]['total_year'] + $request[$y]['total_year']
+                   );
+                   for($i=1;$i<=12;$i++){
+                       $forecast[$y]["total_{$i}"] = $confirm[$y]["total_{$i}"] + $request[$y]["total_{$i}"];
+                   }
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                   $r['confirm' . $y] = $confirm[$y];
+                   $r['request' . $y] = $request[$y];
+                   $r['forecast' . $y] = $forecast[$y];
+                   if($y == $year){
+                       array_push($r, $currentYearActual);
+                       continue;
+                   }
+                   if($nextYearActual){
+                        array_push($r, $nextYearActual);
+                    }
+                }
+                
+                return array_values($r);
+                
+            }
+            
+            // item level
+            
+            $salesforecast = DB_DataObject::factory($this->tableName());
+            $salesforecast->autoJoin();
+            $salesforecast->whereAdd("
+                salesforecast_cust_id != 0
+                AND
+                salesforecast_is_all_buyers = FALSE
+                AND
+                join_salesforecast_itemsite_id_itemsite_id.itemsite_stocked = TRUE
+                AND
+                join_salesforecast_itemsite_id_itemsite_id.itemsite_item_id = {$this->escape($q['_item_id'])} 
+                AND
+                (
+                    extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW())
+                    OR
+                    extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW() + INTERVAL '1 YEAR')
+                )
+            ");
+            $salesforecast->selectAdd();
+            $salesforecast->selectAdd("
+                extract(year from join_salesforecast_period_id_period_id.period_start) as year,
+                extract(month from join_salesforecast_period_id_period_id.period_start) as month,
+                SUM(COALESCE(salesforecast.salesforecast_qty,0)) AS total_qty,
+                SUM(COALESCE(salesforecast.salesforecast_requests,0)) AS total_request
+            ");
+            $salesforecast->groupBy("year,month");
+            
+            $results = $salesforecast->fetchAll();
+            
+            $calc = array();
+            
+            foreach ($results as $result){
+                
+                $calc[$result->year][$result->month]['confirm'] = $result->total_qty;
+                $calc[$result->year][$result->month]['request'] = $result->total_request;
+                
+                if(!isset($calc[$result->year]['total_qty']) || !isset($calc[$result->year]['total_request'])){
+                    $calc[$result->year]['total_qty'] = $result->total_qty;
+                    $calc[$result->year]['total_request'] = $result->total_request;
+                    continue;
+                }
+                
+                $calc[$result->year]['total_qty'] += $result->total_qty;
+                $calc[$result->year]['total_request'] += $result->total_request;
+                
+            }
+            
+            // push Total Estimated / Calculated forecast -> $r
+            
+            $estimated = array();
+            
+            foreach ($ar as $a){
+                if($month < 7 && $a['year'] == $year + 1){ // if current month is not after Jun, we won't show next year
+                    continue;
+                }
+                if(!isset($estimated[$a['year']])){
+                    $estimated[$a['year']]['year_text'] = 'Total Estimated / Calculated forecast ' . $a['year'];
+                    $estimated[$a['year']]['year'] = $a['year'];
+                    $estimated[$a['year']]['type'] = 'estimated';
+                }
+                $estimated[$a['year']]["total_{$a['month']}"] = $a['salesforecast_qty'];
+                $estimated[$a['year']]["total_{$a['month']}_salesforecast_id"] = $a['salesforecast_id'];
+                if(isset($estimated[$a['year']]["total_year"])){
+                    $estimated[$a['year']]["total_year"] += $a['salesforecast_qty'];
+                    continue;
+                }
+                $estimated[$a['year']]["total_year"] = $a['salesforecast_qty'];
+            }
+
+            foreach (array_slice($years, 2) as $y){
+                if(!isset($estimated[$y])){
+                    $estimated[$y]['year_text'] = 'Total Estimated / Calculated forecast ' . $y;
+                    $estimated[$y]['year'] = $y;
+                    $estimated[$y]['type'] = 'estimated';
+                    $estimated[$y]["total_year"] = '';
+                }
+                for($i=1;$i<=12;$i++){
+                    if(!isset($estimated[$y]["total_{$i}"])){
+                        $estimated[$y]["total_{$i}"] = '';
+                        $estimated[$y]["total_{$i}_salesforecast_id"] = 0;
+                    }
+                }
+            }
+            
+            if($au->hasPerm('Xtuple.SalesPlanner', 'S')){ // planning staff
+                
+                $invcitem = DB_DataObject::factory('invcitem');
+                $invcitem->_join .= "
+                    LEFT JOIN 
+                        invchead 
+                    ON 
+                        invcitem_invchead_id = invchead_id
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        invcitem_item_id = itemsite_item_id
+                ";
+                $invcitem->selectAdd();
+                $invcitem->selectAdd("
+                    DISTINCT(invchead_cust_id),
+                    extract(year from invchead.invchead_invcdate) as year,
+                    extract(month from invchead.invchead_invcdate) as month
+                ");
+                $invcitem->whereAdd("
+                    itemsite_stocked = TRUE
+                    AND
+                    invcitem_item_id = {$this->escape($q['_item_id'])}
+                    AND
+                    extract(year from invchead.invchead_invcdate) >= extract(year from NOW() - INTERVAL '1 YEAR')
+                    AND
+                    extract(year from invchead.invchead_invcdate) <= extract(year from NOW())
+                    AND
+                    invcitem.invcitem_billed > 0
+                ");
+                    
+                if(!empty($cust_str)){
+                    $invcitem->whereAdd("{$cust_str}");
+                }
+                
+                $invcitem->groupBy("year,month,invchead_cust_id");
+                
+                $actualFilled = array();
+                
+                foreach ($invcitem->fetchAll() as $invc){
+                    if($month < 7 && $invc->year == $year){ // if current month is not after Jun, we won't show next year
+                        continue;
+                    }
+                    $actualFilled[$invc->year][$invc->month][] = $invc->invchead_cust_id;
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($actualFilled[$y-1])){
+                        $actualFilled[$y-1] = array();
+                    }
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($actualFilled[$y-1][$i])){
+                            $actualFilled[$y-1][$i] = array();
+                        }
+                    }
+                }
+                
+                
+                $salesforecast = DB_DataObject::factory($this->tableName());
+                $salesforecast->autoJoin();
+                $salesforecast->whereAdd("
+                    salesforecast_cust_id != 0
+                    AND
+                    salesforecast_is_all_buyers = FALSE
+                    AND
+                    join_salesforecast_itemsite_id_itemsite_id.itemsite_stocked = TRUE
+                    AND
+                    join_salesforecast_itemsite_id_itemsite_id.itemsite_item_id = {$this->escape($q['_item_id'])} 
+                    AND
+                    (
+                        extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW())
+                        OR
+                        extract(year from join_salesforecast_period_id_period_id.period_start) = extract(year from NOW() + INTERVAL '1 YEAR')
+                    )
+                ");
+                $salesforecast->selectAdd();
+                $salesforecast->selectAdd("
+                    DISTINCT(salesforecast_cust_id),
+                    extract(year from join_salesforecast_period_id_period_id.period_start) as year,
+                    extract(month from join_salesforecast_period_id_period_id.period_start) as month
+                ");
+                $salesforecast->groupBy("year,month,salesforecast_cust_id");
+                
+                $forecastFilled = array();
+                
+                foreach ($salesforecast->fetchAll() as $s){
+                    if($month < 7 && $s->year == $year + 1){ // if current month is not after Jun, we won't show next year
+                        continue;
+                    }
+                    if(in_array($s->salesforecast_cust_id, $actualFilled[$s->year-1][$s->month])){
+                        $forecastFilled[$s->year][$s->month][] = $s->salesforecast_cust_id;
+                    }
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($forecastFilled[$y])){
+                        $forecastFilled[$y] = array();
+                    }
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($forecastFilled[$y][$i])){
+                            $forecastFilled[$y][$i] = array();
+                        }
+                    }
+                }
+                
+                
+                // push Percentage filled in (aggragated) -> $r
+
+                $percentage = array();
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($percentage[$y])){
+                        $percentage[$y]['year_text'] = 'Percentage filled in ' . $y;
+                        $percentage[$y]['year'] = $y;
+                        $percentage[$y]['type'] = 'percentage';
+                        $percentage[$y]["total_year"] = '';
+                    }
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($percentage[$y]["total_{$i}"])){
+                            $percentage[$y]["total_{$i}"] = ((count($actualFilled[$y-1][$i]) > 0) ? count($forecastFilled[$y][$i]) / count($actualFilled[$y-1][$i]) : 0) * 100;
+                        }
+                    }
+                }
+                
+                
+                // push Predicted Forecasts Total -> $r
+                
+                $predicted = array();
+                
+                foreach ($ar as $a){
+                    if($month < 7 && $a['year'] == $year + 1){ // if current month is not after Jun, we won't show next year
+                        continue;
+                    }
+                    if(!isset($predicted[$a['year']])){
+                        $predicted[$a['year']]['year_text'] = 'Predicted Forecasts Total ' . $a['year'];
+                        $predicted[$a['year']]['year'] = $y;
+                        $predicted[$a['year']]['type'] = 'predicted';
+                        $predicted[$a['year']]["total_year"] = '';
+                    }
+                    $value = '';
+                    
+                    if($actual[$a['year']-1]["total_{$a['month']}"] > 0){
+                        $value = (($a['salesforecast_sum'] / $actual[$a['year']-1]["total_{$a['month']}"]) < 0.2) ? -1 : $a['salesforecast_sum'];
+                    }
+                    
+                    $predicted[$a['year']]["total_{$a['month']}"] = $value;
+                }
+                
+                foreach (array_slice($years, 2) as $y){
+                    if(!isset($predicted[$y])){
+                        $predicted[$y]['year_text'] = 'Predicted Forecasts Total ' . $y;
+                        $predicted[$y]['year'] = $y;
+                        $predicted[$y]['type'] = 'predicted';
+                        $predicted[$y]["total_year"] = '';
+                    }
+
+                    for($i=1;$i<=12;$i++){
+                        if(!isset($predicted[$y]["total_{$i}"])){
+                            $predicted[$y]["total_{$i}"] = ($actual[$y-1]["total_{$i}"] > 0) ? -1 : '';
+                        }
+                    }
+                }
+                
+            }
+            
+            // push Total Regular / Confirmed Forecast -> $r
+                
+            $confirm = array();
+
+            foreach (array_slice($years, 2) as $y){
+                $confirm[$y]['year_text'] = 'Total Regular / Confirmed Forecast ' . $y;
+                $confirm[$y]['year'] = $y;
+                $confirm[$y]['type'] = 'confirm';
+                $confirm[$y]["total_year"] = (isset($calc[$y]['total_qty'])) ? $calc[$y]['total_qty'] : '';
+                
+                for($i=1;$i<=12;$i++){
+                    if(!isset($confirm[$y]["total_{$i}"])){
+                        $confirm[$y]["total_{$i}"] = (isset($calc[$y][$i]['confirm'])) ? $calc[$y][$i]['confirm'] : '';
+                    }
+                }
+            }
+            
+            // push Total Special Requests -> $r
+                
+            $request = array();
+
+            foreach (array_slice($years, 2) as $y){
+                $request[$y]['year_text'] = 'Total Special Requests ' . $y;
+                $request[$y]['year'] = $y;
+                $request[$y]['type'] = 'request';
+                $request[$y]["total_year"] = (isset($calc[$y]['total_request'])) ? $calc[$y]['total_request'] : '';
+                
+                for($i=1;$i<=12;$i++){
+                    if(!isset($request[$y]["total_{$i}"])){
+                        $request[$y]["total_{$i}"] = (isset($calc[$y][$i]['request'])) ? $calc[$y][$i]['request'] : '';
+                    }
+                }
+            }
+            
+            // push Total forecast -> $r
+            
+            $forecast = array();
+            
+            foreach ($ar as $a){
+                if($month < 7 && $a['year'] == $year + 1){ // if current month is not after Jun, we won't show next year
+                    continue;
+                }
+                if(!isset($forecast[$a['year']])){
+                    $forecast[$a['year']]['year_text'] = 'Total forecast ' . $a['year'];
+                    $forecast[$a['year']]['year'] = $a['year'];
+                    $forecast[$a['year']]['type'] = 'forecast';
+                }
+                $forecast[$a['year']]["total_{$a['month']}"] = $a['salesforecast_sum'];
+                $forecast[$a['year']]["total_{$a['month']}_salesforecast_id"] = $a['salesforecast_id'];
+                if(isset($forecast[$a['year']]["total_year"])){
+                    $forecast[$a['year']]["total_year"] += $a['salesforecast_sum'];
+                    continue;
+                }
+                $forecast[$a['year']]["total_year"] = $a['salesforecast_sum'];
+            }
+
+            foreach (array_slice($years, 2) as $y){
+                if(!isset($forecast[$y])){
+                    $forecast[$y]['year_text'] = 'Total forecast ' . $y;
+                    $forecast[$y]['year'] = $y;
+                    $forecast[$y]['type'] = 'forecast';
+                    $forecast[$y]["total_year"] = '';
+                }
+                
+                for($i=1;$i<=12;$i++){
+                    if(!isset($forecast[$y]["total_{$i}"])){
+                        $forecast[$y]["total_{$i}"] = '';
+                        $forecast[$y]["total_{$i}_salesforecast_id"] = 0;
+                    }
+                }
+            }
+            
+            foreach (array_slice($years, 2) as $y){
+                $r['estimated' . $y] = $estimated[$y];
+                if($au->hasPerm('Xtuple.SalesPlanner', 'S')){
+                    $r['percentage' . $y] = $percentage[$y];
+                    $r['predicted' . $y] = $predicted[$y];
+                }
+                $r['confirm' . $y] = $confirm[$y];
+                $r['request' . $y] = $request[$y];
+                $r['forecast' . $y] = $forecast[$y];
+                if($y == $year){
+                    array_push($r, $currentYearActual);
+                    continue;
+                }
+                if($nextYearActual){
+                     array_push($r, $nextYearActual);
+                 }
+             }
+            
+            return array_values($r);
+            
+           
+        }
+        return $ar;
+    }
+    
+    
+    function beforeInsert($q,$roo)
+    {
+        if(isset($q['_group_data'])){
+            $groups = json_decode($q['_group_data'],true);
+            
+            foreach ($groups as $g){
+                $forecast = DB_DataObject::factory('salesforecast');
+                if(isset($g['salesforecast_id']) && $g['salesforecast_id'] != 0){ // update
+                    $forecast->get($g['salesforecast_id']);
+                    $ff = clone($forecast);
+                    $forecast->salesforecast_qty = $g['salesforecast_qty'];
+                    $forecast->salesforecast_is_all_buyers = $g['salesforecast_is_all_buyers'];
+                    $forecast->update($ff);
+                    continue;
+                }
+                // insert
+                $forecast->setFrom($g);
+                $this->fillFromPost($g, $forecast, $roo);
+                $forecast->insert();
+            }
+            $roo->jok('SUCCESS'); // all done, jok to leave then
+        }
+        
+        $this->fillFromPost($q, $this, $roo);
+    }
+    
+    function fillFromPost($q,$o,$roo)
+    {
+        $is = DB_DataObject::factory('itemsite');
+        $is->itemsite_item_id = $q['_item_id'];
+        $is->find(true);
+
+        $o->salesforecast_itemsite_id = $is->itemsite_id;
+
+        $p = DB_DataObject::factory('period');
+        $p->whereAdd("
+            extract(year from period_start) = {$q['year']}
+            AND
+            extract(month from period_start) = {$q['month']}
+        ");
+        $p->find(true);
+
+        $o->salesforecast_period_id = $p->period_id;
+        
+        
+        $au = $roo->authUser;
+        if($au->id){
+            $o->salesforecast_updated_by = $au->id;
+        }
+    }
+    
+    
+    function download($q, $roo)
+    {
+        static $cache = array();
+        
+        $system = $roo->uiConfig['xtuple_offices']; // define in Pman.php
+        
+        $data = array();
+        
+        $year = date('Y');
+        
+        $years = array($year-2, $year-1, $year);
+        
+        foreach ($system as $s){
+            
+            // get the cust id which in top list!
+            $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Custinfo?_filterTop=1&limit=9999";
+            $ret = json_decode(file_get_contents($url),true);
+            
+            if(!$ret['success']){
+                $roo->jerr("Error occur on getting customer top list in {$s}, result : " . print_r($ret,true));
+            }
+            
+            $top = $ret['data'];
+            
+            $brand = (!empty($q['brand'])) ? "&brand:text=" . urlencode($q['brand']) : '';
+            $group = (!empty($q['group'])) ? "&group:text=" . urlencode($q['group']) : '';
+            
+            $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Metasql?_group=salesPlanning&_name=summary&limit=9999" . $brand . $group;
+            
+            $ret = json_decode(file_get_contents($url),true);
+            
+            if(!$ret['success']){
+                $roo->jerr("Error occur on getting Metasql data in {$s}, result : " . print_r($ret,true));
+            }
+            
+            foreach ($ret['data'] as $r){
+                
+                $actuals = array();
+                $confirm = array();
+                $request = array();
+                $forecast = array();
+
+                if(!isset($cache[$s]['items'][$r['invcitem_item_id']])){
+                    $cache[$s]['items'][$r['invcitem_item_id']] = $this->fetchItemDetail($s, $r['invcitem_item_id'], $roo);
+                }
+                if(!isset($cache[$s]['cust'][$r['invchead_cust_id']])){
+                    $cache[$s]['cust'][$r['invchead_cust_id']] = $this->fetchCustDetail($s, $r['invchead_cust_id'], $roo);
+                }
+                
+                $d = array_merge($cache[$s]['items'][$r['invcitem_item_id']], $cache[$s]['cust'][$r['invchead_cust_id']]);
+                
+                $results = $this->fetchActualSpecific($s, $r['invcitem_item_id'], $r['invchead_cust_id'], $roo);
+                
+                $d['ytd'] = 0;
+                
+                foreach ($results as $result){
+                    // actual by month
+                    if(!isset($actuals[$result['year']][$result['month']])){
+                        $actuals[$result['year']][$result['month']] = 0;
+                    }
+                    
+                    $actuals[$result['year']][$result['month']] += $result['billed'];
+                    
+                    // actual by year
+                    if(!isset($actuals[$result['year']]['total'])){
+                        $actuals[$result['year']]['total'] = 0;
+                    }
+                    
+                    $actuals[$result['year']]['total'] += $result['billed'];
+                    
+                    // YTD qty
+                    if(strtotime($result['invchead_invcdate']) >= strtotime(date("Y-m-d", mktime(0,0,0,1,1,$year))) && strtotime($result['invchead_invcdate']) <= strtotime(date('Y-m-d'))){
+                        $d['ytd'] += $result['billed'];
+                    }
+                    
+                    
+                    
+                }
+                
+                foreach ($years as $y){
+                    $d['total_' . $y] = isset($actuals[$y]['total']) ? $actuals[$y]['total'] : 0;
+                    
+                    for ($i = 1; $i <= 12; $i++){
+                        $d['qty_' . $y . '_' . $i] = isset($actuals[$y][$i]) ? $actuals[$y][$i] : 0;
+                    }
+                }
+                
+                $d['system_country'] = $s;
+                $d['itemsrc_active'] = $cache[$s]['items'][$r['invcitem_item_id']]['itemsrc_active'] ? 'Yes' : 'No';
+                $d['cust_group'] = (in_array($r['invchead_cust_id'], $top)) ? $cache[$s]['cust'][$r['invchead_cust_id']]['cust_name'] : 'Other';
+                
+                $results = $this->fetchForecastSpecific($s, $r['invcitem_item_id'], $r['invchead_cust_id'], $roo);
+                
+                foreach ($results as $result){
+                    
+                    if(!isset($confirm[$result['month']])){
+                        $confirm[$result['month']] = 0;
+                    }
+                    
+                    $confirm[$result['month']] += $result['salesforecast_qty'];
+                    
+                    if(!isset($request[$result['month']])){
+                        $request[$result['month']] = 0;
+                    }
+                    
+                    $request[$result['month']] += $result['salesforecast_requests'];
+                    
+                    if(!isset($request[$result['month']])){
+                        $request[$result['month']] = 0;
+                    }
+                    
+                    $request[$result['month']] += $result['salesforecast_requests'];
+                    
+                    if(!isset($forecast[$result['month']])){
+                        $forecast[$result['month']] = 0;
+                    }
+                    
+                    $forecast[$result['month']] += $result['forecast'];
+                    
+                }
+                
+                for ($i = 1; $i <= 12; $i++){
+                    $d['confirm_'. $i] = isset($confirm[$i]) ? $confirm[$i] : 0;
+                    $d['request_'. $i] = isset($request[$i]) ? $request[$i] : 0;
+                    $d['forecast_'. $i] = isset($forecast[$i]) ? $forecast[$i] : 0;
+                }
+                
+                $data[] = $d;
+            }
+            
+        }
+        
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        // item and customer informations
+        $cols = array(
+            array( 
+                'dataIndex' => 'system_country',
+                'header'  => 'Dragon System Country',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'item_number',
+                'header'  => 'SKU Item Code',
+                'dataFormat' => 'string',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'item_descrip1',
+                'header'  => 'Item Description',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'item_char_brand',
+                'header'  => 'Brand',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'item_char_productgroup',
+                'header'  => 'Product Group',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'itemsrc_active',
+                'header'  => 'Active',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'cust_name',
+                'header'  => 'Customer Name',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'cust_country',
+                'header'  => 'Country',
+                'width'  => 75,
+            ),
+            array( 
+                'dataIndex' => 'cust_group',
+                'header'  => 'Customer Group',
+                'width'  => 75,
+            )
+        );
+        
+        // actual by year
+        foreach ($years as $y){
+            $cols[] = array( 
+                'dataIndex' => 'total_' . $y,
+                'header'  => 'Total Actual Sales ' . $y . ' (qty)',
+                'width'  => 75,
+            );
+        }
+        // YTD
+        $cols[] = array( 
+                'dataIndex' => 'ytd',
+                'header'  => 'YTD Total Actual Sales ' . $year . ' (qty)',
+                'width'  => 75,
+        );
+        
+        // Calculated Forecast
+        for ($i = 1; $i <= 12; $i++){
+            $cols[] = array( 
+                'dataIndex' => 'forecast_' . $i,
+                'header'  => 'Calculated Forecast Sales ' . date("M", mktime(0, 0, 0, $i, 1)) . ' ' . $year . ' (qty)',
+                'width'  => 75,
+            );
+        }
+        
+        // Special Requests
+        for ($i = 1; $i <= 12; $i++){
+            $cols[] = array( 
+                'dataIndex' => 'request_' . $i,
+                'header'  => 'Special Requests Sales ' . date("M", mktime(0, 0, 0, $i, 1)) . ' ' . $year . ' (qty)',
+                'width'  => 75,
+            );
+        }
+        
+        // Confirmed Forecast
+        for ($i = 1; $i <= 12; $i++){
+            $cols[] = array( 
+                'dataIndex' => 'confirm_' . $i,
+                'header'  => 'Confirmed Forecast Sales ' . date("M", mktime(0, 0, 0, $i, 1)) . ' ' . $year . ' (qty)',
+                'width'  => 75,
+            );
+        }
+        
+        
+        //  actual by month of each year
+        krsort($years);
+        
+        foreach ($years as $y){
+            for ($i = 1; $i <= 12; $i++){
+                $cols[] = array( 
+                    'dataIndex' => 'qty_' . $y . '_' . $i,
+                    'header'  => 'Actual Sales ' . date("M", mktime(0, 0, 0, $i, 1)) . ' ' . $y . ' (qty)',
+                    'width'  => 75,
+                );
+            }
+        }
+        
+        $cfg = array(
+            'workbook' => 'SalesForecase',
+            'cols' => $cols
+        );
+        $x = new Pman_Core_SimpleExcel($data, $cfg);
+        $x->send('SalesForecase.xls');
+        exit;
+    }
+    
+    function fetchItemDetail($s, $item_id, $roo)
+    {
+        $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Item?_id={$item_id}&_with_itemsite=1&_with_itemsrc_active=1&_with_char=1";
+        
+        $ret = json_decode(file_get_contents($url),true);
+        
+        if(!$ret['success'] || !count($ret['data'])){
+            $roo->jerr("Error occur on getting item detail in {$s}, item_id : {$item_id}, result : " . print_r($ret,true));
+        }
+        
+        return $ret['data'];
+        
+    }
+    
+    function fetchCustDetail($s, $cust_id, $roo)
+    {
+        $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Custinfo?_id={$cust_id}&search[with_address]=1";
+        
+        $ret = json_decode(file_get_contents($url),true);
+        
+        if(!$ret['success'] || !count($ret['data'])){
+            $roo->jerr("Error occur on getting customer detail in {$s}, cust_id : {$cust_id}, result : " . print_r($ret,true));
+        }
+        
+        return $ret['data'];
+        
+    }
+    
+    function fetchActualSpecific($s, $item_id, $cust_id, $roo)
+    {
+        $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Metasql?_group=salesPlanning&_name=specific&item_id:number={$item_id}&cust_id:number={$cust_id}&limit=9999";
+        
+        $ret = json_decode(file_get_contents($url),true);
+        
+        if(!$ret['success']){
+            $roo->jerr("Error occur on getting actual specific in {$s}, item_id : {$item_id}, cust_id : {$cust_id}, result : " . print_r($ret,true));
+        }
+        
+        return $ret['data'];
+        
+    }
+    
+    function fetchForecastSpecific($s, $item_id, $cust_id, $roo)
+    {
+        $url = "http://localhost{$roo->rootURL}/{$s}.php/Roo/Metasql?_group=salesPlanning&_name=forecast&item_id:number={$item_id}&cust_id:number={$cust_id}&limit=9999";
+        
+        $ret = json_decode(file_get_contents($url),true);
+        
+        if(!$ret['success']){
+            $roo->jerr("Error occur on getting forecast specific in {$s}, item_id : {$item_id}, cust_id : {$cust_id}, result : " . print_r($ret,true));
+        }
+        
+        return $ret['data'];
+        
+    }
+}
diff --git a/DataObjects/Saleshistory.php b/DataObjects/Saleshistory.php
new file mode 100644 (file)
index 0000000..afa1a5f
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Table Definition for saleshistory
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Saleshistory extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'saleshistory';        // table name
+    public $cohist_id;                       // int4(4)  
+    public $cohist_cust_id;                  // int4(4)  
+    public $cohist_itemsite_id;              // int4(4)  
+    public $cohist_shipdate;                 // date(4)  
+    public $cohist_shipvia;                  // text(-1)  
+    public $cohist_ordernumber;              // text(-1)  
+    public $cohist_orderdate;                // date(4)  
+    public $cohist_invcnumber;               // text(-1)  
+    public $cohist_invcdate;                 // date(4)  
+    public $cohist_qtyshipped;               // numeric(-1)  
+    public $cohist_unitprice;                // numeric(-1)  
+    public $cohist_shipto_id;                // int4(4)  
+    public $cohist_salesrep_id;              // int4(4)  
+    public $cohist_duedate;                  // date(4)  
+    public $cohist_imported;                 // bool(1)  
+    public $cohist_billtoname;               // text(-1)  
+    public $cohist_billtoaddress1;           // text(-1)  
+    public $cohist_billtoaddress2;           // text(-1)  
+    public $cohist_billtoaddress3;           // text(-1)  
+    public $cohist_billtocity;               // text(-1)  
+    public $cohist_billtostate;              // text(-1)  
+    public $cohist_billtozip;                // text(-1)  
+    public $cohist_shiptoname;               // text(-1)  
+    public $cohist_shiptoaddress1;           // text(-1)  
+    public $cohist_shiptoaddress2;           // text(-1)  
+    public $cohist_shiptoaddress3;           // text(-1)  
+    public $cohist_shiptocity;               // text(-1)  
+    public $cohist_shiptostate;              // text(-1)  
+    public $cohist_shiptozip;                // text(-1)  
+    public $cohist_commission;               // numeric(-1)  
+    public $cohist_commissionpaid;           // bool(1)  
+    public $cohist_unitcost;                 // numeric(-1)  
+    public $cohist_misc_type;                // bpchar(-1)  
+    public $cohist_misc_descrip;             // text(-1)  
+    public $cohist_misc_id;                  // int4(4)  
+    public $cohist_doctype;                  // text(-1)  
+    public $cohist_promisedate;              // date(4)  
+    public $cohist_ponumber;                 // text(-1)  
+    public $cohist_curr_id;                  // int4(4)  
+    public $cohist_sequence;                 // int4(4)  
+    public $cohist_taxtype_id;               // int4(4)  
+    public $cohist_taxzone_id;               // int4(4)  
+    public $invoicenumber;                   // text(-1)  
+    public $cust_id;                         // int4(4)  
+    public $cust_number;                     // text(-1)  
+    public $cust_name;                       // text(-1)  
+    public $cust_curr_id;                    // int4(4)  
+    public $cust_custtype_id;                // int4(4)  
+    public $custtype_code;                   // text(-1)  
+    public $custtype_descrip;                // text(-1)  
+    public $salesrep_number;                 // text(-1)  
+    public $salesrep_name;                   // text(-1)  
+    public $shipzone_id;                     // int4(4)  
+    public $shipzone_name;                   // text(-1)  
+    public $shipzone_descrip;                // text(-1)  
+    public $itemsite_warehous_id;            // int4(4)  
+    public $itemsite_item_id;                // int4(4)  
+    public $item_id;                         // int4(4)  
+    public $item_number;                     // text(-1)  
+    public $item_descrip1;                   // text(-1)  
+    public $itemdescription;                 // text(-1)  
+    public $item_prodcat_id;                 // int4(4)  
+    public $warehous_code;                   // text(-1)  
+    public $warehous_descrip;                // text(-1)  
+    public $prodcat_code;                    // text(-1)  
+    public $basecommission;                  // numeric(-1)  
+    public $baseunitprice;                   // numeric(-1)  
+    public $custunitprice;                   // numeric(-1)  
+    public $extprice;                        // numeric(-1)  
+    public $baseextprice;                    // numeric(-1)  
+    public $custextprice;                    // numeric(-1)  
+    public $extcost;                         // numeric(-1)  
+    public $currabbr;                        // varchar(-1)  
+    public $cohist_invcdate_xtnullrole;      // text(-1)  
+    public $cohist_qtyshipped_xtnumericrole;    // text(-1)  
+    public $cohist_unitprice_xtnumericrole;    // text(-1)  
+    public $baseunitprice_xtnumericrole;     // text(-1)  
+    public $custunitprice_xtnumericrole;     // text(-1)  
+    public $custextprice_xtnumericrole;      // text(-1)  
+    public $extprice_xtnumericrole;          // text(-1)  
+    public $baseextprice_xtnumericrole;      // text(-1)  
+    public $cohist_unitcost_xtnumericrole;    // text(-1)  
+    public $extcost_xtnumericrole;           // text(-1)  
+    public $cohist_commission_xtnumericrole;    // text(-1)  
+    public $basecommission_xtnumericrole;    // text(-1)  
+    public $cohist_qtyshipped_xttotalrole;    // int4(4)  
+    public $custextprice_xttotalrole;        // int4(4)  
+    public $baseextprice_xttotalrole;        // int4(4)  
+    public $extcost_xttotalrole;             // int4(4)  
+    public $basecommission_xttotalrole;      // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Saleshistorymisc.php b/DataObjects/Saleshistorymisc.php
new file mode 100644 (file)
index 0000000..0901323
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Table Definition for saleshistorymisc
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Saleshistorymisc extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'saleshistorymisc';    // table name
+    public $cohist_id;                       // int4(4)  
+    public $cohist_cust_id;                  // int4(4)  
+    public $cohist_itemsite_id;              // int4(4)  
+    public $cohist_shipdate;                 // date(4)  
+    public $cohist_shipvia;                  // text(-1)  
+    public $cohist_ordernumber;              // text(-1)  
+    public $cohist_orderdate;                // date(4)  
+    public $cohist_invcnumber;               // text(-1)  
+    public $cohist_invcdate;                 // date(4)  
+    public $cohist_qtyshipped;               // numeric(-1)  
+    public $cohist_unitprice;                // numeric(-1)  
+    public $cohist_shipto_id;                // int4(4)  
+    public $cohist_salesrep_id;              // int4(4)  
+    public $cohist_duedate;                  // date(4)  
+    public $cohist_imported;                 // bool(1)  
+    public $cohist_billtoname;               // text(-1)  
+    public $cohist_billtoaddress1;           // text(-1)  
+    public $cohist_billtoaddress2;           // text(-1)  
+    public $cohist_billtoaddress3;           // text(-1)  
+    public $cohist_billtocity;               // text(-1)  
+    public $cohist_billtostate;              // text(-1)  
+    public $cohist_billtozip;                // text(-1)  
+    public $cohist_shiptoname;               // text(-1)  
+    public $cohist_shiptoaddress1;           // text(-1)  
+    public $cohist_shiptoaddress2;           // text(-1)  
+    public $cohist_shiptoaddress3;           // text(-1)  
+    public $cohist_shiptocity;               // text(-1)  
+    public $cohist_shiptostate;              // text(-1)  
+    public $cohist_shiptozip;                // text(-1)  
+    public $cohist_commission;               // numeric(-1)  
+    public $cohist_commissionpaid;           // bool(1)  
+    public $cohist_unitcost;                 // numeric(-1)  
+    public $cohist_misc_type;                // bpchar(-1)  
+    public $cohist_misc_descrip;             // text(-1)  
+    public $cohist_misc_id;                  // int4(4)  
+    public $cohist_doctype;                  // text(-1)  
+    public $cohist_promisedate;              // date(4)  
+    public $cohist_ponumber;                 // text(-1)  
+    public $cohist_curr_id;                  // int4(4)  
+    public $cohist_sequence;                 // int4(4)  
+    public $cohist_taxtype_id;               // int4(4)  
+    public $cohist_taxzone_id;               // int4(4)  
+    public $invoicenumber;                   // text(-1)  
+    public $cust_id;                         // int4(4)  
+    public $cust_number;                     // text(-1)  
+    public $cust_name;                       // text(-1)  
+    public $cust_curr_id;                    // int4(4)  
+    public $cust_custtype_id;                // int4(4)  
+    public $custtype_code;                   // text(-1)  
+    public $salesrep_number;                 // text(-1)  
+    public $salesrep_name;                   // text(-1)  
+    public $shipzone_id;                     // int4(4)  
+    public $shipzone_name;                   // text(-1)  
+    public $itemsite_warehous_id;            // int4(4)  
+    public $itemsite_item_id;                // int4(4)  
+    public $item_number;                     // text(-1)  
+    public $item_descrip1;                   // text(-1)  
+    public $itemdescription;                 // text(-1)  
+    public $item_prodcat_id;                 // int4(4)  
+    public $warehous_code;                   // text(-1)  
+    public $prodcat_code;                    // text(-1)  
+    public $basecommission;                  // numeric(-1)  
+    public $baseunitprice;                   // numeric(-1)  
+    public $custunitprice;                   // numeric(-1)  
+    public $extprice;                        // numeric(-1)  
+    public $baseextprice;                    // numeric(-1)  
+    public $custextprice;                    // numeric(-1)  
+    public $extcost;                         // numeric(-1)  
+    public $currabbr;                        // varchar(-1)  
+    public $cohist_invcdate_xtnullrole;      // text(-1)  
+    public $cohist_qtyshipped_xtnumericrole;    // text(-1)  
+    public $cohist_unitprice_xtnumericrole;    // text(-1)  
+    public $baseunitprice_xtnumericrole;     // text(-1)  
+    public $custunitprice_xtnumericrole;     // text(-1)  
+    public $custextprice_xtnumericrole;      // text(-1)  
+    public $extprice_xtnumericrole;          // text(-1)  
+    public $baseextprice_xtnumericrole;      // text(-1)  
+    public $cohist_unitcost_xtnumericrole;    // text(-1)  
+    public $extcost_xtnumericrole;           // text(-1)  
+    public $cohist_commission_xtnumericrole;    // text(-1)  
+    public $basecommission_xtnumericrole;    // text(-1)  
+    public $cohist_qtyshipped_xttotalrole;    // int4(4)  
+    public $custextprice_xttotalrole;        // int4(4)  
+    public $baseextprice_xttotalrole;        // int4(4)  
+    public $extcost_xttotalrole;             // int4(4)  
+    public $basecommission_xttotalrole;      // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Salesrep.php b/DataObjects/Salesrep.php
new file mode 100644 (file)
index 0000000..267a003
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for salesrep
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Salesrep extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'salesrep';            // table name
+    public $salesrep_id;                     // int4(4)  not_null default_nextval%28%28salesrep_salesrep_id_seq%29%3A%3Aregclass%29 primary_key primary_key
+    public $salesrep_active;                 // bool(1)  
+    public $salesrep_number;                 // text(-1)  unique_key unique_key
+    public $salesrep_name;                   // text(-1)  
+    public $salesrep_commission;             // numeric(-1)  
+    public $salesrep_method;                 // bpchar(-1)  
+    public $salesrep_emp_id;                 // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $salesrep_emp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function emp() {
+        return func_num_args() ? $this->link('salesrep_emp_id', func_get_arg(0)) : $this->link('salesrep_emp_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if(!empty($q['query']['name'])){
+            $this->whereAdd("
+                salesrep_name LIKE '{$this->escape($q['query']['name'])}%'
+            ");
+        }
+    }
+
+}
diff --git a/DataObjects/Script.php b/DataObjects/Script.php
new file mode 100644 (file)
index 0000000..d0f4152
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for script
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Script extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'script';              // table name
+    public $script_id;                       // int4(4)  not_null default_nextval%28script_script_id_seq%29 primary_key
+    public $script_name;                     // text(-1)  not_null
+    public $script_order;                    // int4(4)  not_null
+    public $script_enabled;                  // bool(1)  not_null default_false
+    public $script_source;                   // text(-1)  not_null
+    public $script_notes;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Sequence.php b/DataObjects/Sequence.php
new file mode 100644 (file)
index 0000000..34b6042
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Table Definition for sequence
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Sequence extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'sequence';            // table name
+    public $sequence_value;                  // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shift.php b/DataObjects/Shift.php
new file mode 100644 (file)
index 0000000..e450fb5
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for shift
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shift extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shift';               // table name
+    public $shift_id;                        // int4(4)  not_null default_nextval%28shift_shift_id_seq%29 primary_key
+    public $shift_number;                    // text(-1)  not_null
+    public $shift_name;                      // text(-1)  not_null
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipchrg.php b/DataObjects/Shipchrg.php
new file mode 100644 (file)
index 0000000..c84f7a8
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for shipchrg
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipchrg extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipchrg';            // table name
+    public $shipchrg_id;                     // int4(4)  not_null default_nextval%28shipchrg_shipchrg_id_seq%29 primary_key
+    public $shipchrg_name;                   // text(-1)  
+    public $shipchrg_descrip;                // text(-1)  
+    public $shipchrg_custfreight;            // bool(1)  
+    public $shipchrg_handling;               // bpchar(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipdata.php b/DataObjects/Shipdata.php
new file mode 100644 (file)
index 0000000..d444ee7
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Table Definition for shipdata
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipdata extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipdata';            // table name
+    public $shipdata_cohead_number;          // text(-1)  not_null primary_key multiple_key
+    public $shipdata_cosmisc_tracknum;       // text(-1)  not_null primary_key multiple_key
+    public $shipdata_cosmisc_packnum_tracknum;    // text(-1)  not_null primary_key multiple_key
+    public $shipdata_weight;                 // numeric(-1)  
+    public $shipdata_base_freight;           // numeric(-1)  
+    public $shipdata_total_freight;          // numeric(-1)  
+    public $shipdata_shipper;                // text(-1)  default_UPS
+    public $shipdata_billing_option;         // text(-1)  
+    public $shipdata_package_type;           // text(-1)  
+    public $shipdata_void_ind;               // bpchar(-1)  not_null primary_key multiple_key
+    public $shipdata_lastupdated;            // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $shipdata_shiphead_number;        // text(-1)  
+    public $shipdata_base_freight_curr_id;    // int4(4)  default_basecurrid%28%29
+    public $shipdata_total_freight_curr_id;    // int4(4)  default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $shipdata_base_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function base_freight_curr() {
+        return func_num_args() ? $this->link('shipdata_base_freight_curr_id', func_get_arg(0)) : $this->link('shipdata_base_freight_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $shipdata_shiphead_number
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shiphead() {
+        return func_num_args() ? $this->link('shipdata_shiphead_number', func_get_arg(0)) : $this->link('shipdata_shiphead_number');
+    }
+
+   /**
+    * Getter / Setter for $shipdata_total_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function total_freight_curr() {
+        return func_num_args() ? $this->link('shipdata_total_freight_curr_id', func_get_arg(0)) : $this->link('shipdata_total_freight_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipdatasum.php b/DataObjects/Shipdatasum.php
new file mode 100644 (file)
index 0000000..34473d7
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Table Definition for shipdatasum
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipdatasum extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipdatasum';         // table name
+    public $shipdatasum_cohead_number;       // text(-1)  not_null primary_key multiple_key
+    public $shipdatasum_cosmisc_tracknum;    // text(-1)  not_null primary_key multiple_key
+    public $shipdatasum_cosmisc_packnum_tracknum;    // text(-1)  not_null primary_key multiple_key
+    public $shipdatasum_weight;              // numeric(-1)  
+    public $shipdatasum_base_freight;        // numeric(-1)  
+    public $shipdatasum_total_freight;       // numeric(-1)  
+    public $shipdatasum_shipper;             // text(-1)  default_UPS
+    public $shipdatasum_billing_option;      // text(-1)  
+    public $shipdatasum_package_type;        // text(-1)  
+    public $shipdatasum_lastupdated;         // timestamp(8)  not_null default_%28now%29%3A%3Atimestamp%286%29%20with%20time%20zone
+    public $shipdatasum_shipped;             // bool(1)  default_false
+    public $shipdatasum_shiphead_number;     // text(-1)  
+    public $shipdatasum_base_freight_curr_id;    // int4(4)  default_basecurrid%28%29
+    public $shipdatasum_total_freight_curr_id;    // int4(4)  default_basecurrid%28%29
+
+    
+   /**
+    * Getter / Setter for $shipdatasum_base_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function base_freight_curr() {
+        return func_num_args() ? $this->link('shipdatasum_base_freight_curr_id', func_get_arg(0)) : $this->link('shipdatasum_base_freight_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $shipdatasum_shiphead_number
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shiphead() {
+        return func_num_args() ? $this->link('shipdatasum_shiphead_number', func_get_arg(0)) : $this->link('shipdatasum_shiphead_number');
+    }
+
+   /**
+    * Getter / Setter for $shipdatasum_total_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function total_freight_curr() {
+        return func_num_args() ? $this->link('shipdatasum_total_freight_curr_id', func_get_arg(0)) : $this->link('shipdatasum_total_freight_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipform.php b/DataObjects/Shipform.php
new file mode 100644 (file)
index 0000000..099d761
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for shipform
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipform extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipform';            // table name
+    public $shipform_id;                     // int4(4)  not_null default_nextval%28%28%22shipform_shipform_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $shipform_name;                   // text(-1)  not_null unique_key
+    public $shipform_report_id;              // int4(4)  
+    public $shipform_report_name;            // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shiphead.php b/DataObjects/Shiphead.php
new file mode 100644 (file)
index 0000000..7a4a130
--- /dev/null
@@ -0,0 +1,1495 @@
+<?php
+/**
+ * Table Definition for shiphead
+ *
+ * States:
+ *    draft:
+ *      shipdate = filled in..
+ *      shipped: false
+ *    confirmed
+ *      shipdate : filled in
+ *      shipped : true
+ *    unconfirmed :
+ *      shipdate : filled in
+ *      shipped : false
+ *    void :
+ *      shipdate NULL
+ *      shipped : false
+ *
+ *
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shiphead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shiphead';            // table name
+    public $shiphead_id;                     // int4(4)  not_null default_nextval%28shiphead_shiphead_id_seq%29 primary_key
+    public $shiphead_order_id;               // int4(4)  not_null
+    public $shiphead_order_type;             // text(-1)  not_null
+    public $shiphead_number;                 // text(-1)  not_null unique_key
+    public $shiphead_shipvia;                // text(-1)  
+    public $shiphead_freight;                // numeric(-1)  not_null default_0.0
+    public $shiphead_freight_curr_id;        // int4(4)  not_null default_basecurrid%28%29
+    public $shiphead_notes;                  // text(-1)  
+    public $shiphead_shipped;                // bool(1)  not_null default_false
+    public $shiphead_shipdate;               // date(4)  
+    public $shiphead_shipchrg_id;            // int4(4)  
+    public $shiphead_shipform_id;            // int4(4)  
+    public $shiphead_sfstatus;               // bpchar(-1)  not_null
+    public $shiphead_tracknum;               // text(-1)  
+    public $shiphead_location_id;               // text(-1)  
+    public $shiphead_shipto_id;               // text(-1)  
+    public $shiphead_delivery_note;          // TEXT
+
+    
+   /**
+    * Getter / Setter for $shiphead_freight_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freight_curr() {
+        return func_num_args() ? $this->link('shiphead_freight_curr_id', func_get_arg(0)) : $this->link('shiphead_freight_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $shiphead_shipchrg_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipchrg() {
+        return func_num_args() ? $this->link('shiphead_shipchrg_id', func_get_arg(0)) : $this->link('shiphead_shipchrg_id');
+    }
+
+   /**
+    * Getter / Setter for $shiphead_shipform_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipform() {
+        return func_num_args() ? $this->link('shiphead_shipform_id', func_get_arg(0)) : $this->link('shiphead_shipform_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    
+    public function location() {
+        if (func_num_args()) {
+            $obj = func_get_args(0);
+            $this->shiphead_location_id = is_object($obj) ? $obj->pid() : $obj;
+            return true;
+        }
+        //echo '<PRE>';print_r($this);exit;
+        $l = DB_DataObject::Factory('location');
+        $l->get($this->shiphead_location_id);
+        return $l;
+        
+        
+    }
+     public function shipto() {
+        if (func_num_args()) {
+            $obj = func_get_args(0);
+            $this->shiphead_shipto_id = is_object($obj) ? $obj->pid() : $obj;
+            return true;
+        }
+        $l = DB_DataObject::Factory('shiptoinfo');
+        $l->get($this->shiphead_shipto_id);
+        return $l;
+        
+        
+    }
+    
+    function order()
+    {
+        if (func_num_args()) {
+            $ar = func_get_arg(0);
+            $this->shiphead_order_id = is_object($ar) ? $ar->pid() : $ar;
+            return $this->shiphead_order_id;
+        }
+        // no arguemnts - fetch..
+        static $cache = array();
+        if (isset($cache[$this->shiphead_order_id])) {
+            return $cache[$this->shiphead_order_id];
+        }
+            // technically check --- shiphead_order_type
+        $d = $this->factory('cohead');
+        if (!$d->get($this->shiphead_order_id)) {
+            $d = $this->factory('cohead');
+            $cache[$this->shiphead_order_id] = $d;
+            return $d;
+        }
+        $cache[$this->shiphead_order_id] = $d;
+        return $d;
+    
+    }
+    // returns a map of orderitemid-> shipitem.
+    // it assumes that a order item does not have multiple lines referenced..
+    function items()
+    {
+        $o = $this->order();
+        $ids = $o->items('coitem_id');
+        $i = $this->factory('shipitem');
+        $i->shipitem_shiphead_id = $this->shiphead_id;
+        $i->whereAddIn('shipitem_orderitem_id', $ids, 'int');
+        
+        $ret = array();
+        $i->find();
+        while($i->fetch()) {
+            $ret[$i->shipitem_orderitem_id] = clone($i);
+        }
+        return $ret;
+        
+        
+    }
+     
+    
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        
+        if (!empty($q['_download'])) {
+            if (!$this->get($q['_download'])) {
+                $roo->jerr("invalid id");
+            }
+            return $this->download($roo);
+        }
+        if (!empty($q['_stash'])) {
+            return $this->stashList($q['_stash'],$roo);
+        }
+        
+        $this->selectAdd("
+            (SELECT count(shipitem_qty) FROM shipitem WHERE shipitem_shiphead_id = shiphead_id)  AS shipqty
+        ");
+        //DB_DataObject::debugLevel(1);
+        /// generally...
+        $cohead = $this->factory('cohead');
+        $cohead->joinAdd($this->factory('custinfo'), 'LEFT');
+        
+        $this->joinAdd(array('shiphead_order_id', $cohead, 'cohead_id'), 'LEFT');
+       
+        
+        $this->selectAs($this->factory('cohead'), 'shiphead_order_id_%s');
+        $this->selectAs($this->factory('custinfo'), 'shiphead_custinfo_%s');
+        
+        
+        
+    }
+    
+    
+  
+    
+    function beforeInsert($q, $roo)
+    {
+        
+        //check to see if there are any other 'draft' shipments...
+        
+        $sh = DB_DataObject::Factory('shiphead');
+        $sh->shiphead_order_id = $this->shiphead_order_id;
+        $sh->shiphead_shipped  = false;
+        $sh->whereAdd('shiphead_shipdate IS NOT NULL');
+        if ($sh->count()) {
+            $roo->jerr("Order already contains a draft shipment");
+        }
+        
+        /*
+         *  check to see if the delivery notes is allow blank
+         *  if the shiphead location id is same as the default_location, then all blank, otherwise, MUST fill it in...
+         */
+        if(empty($this->shiphead_delivery_note)){
+            $l = DB_DataObject::factory('location');
+            $l = $l->defaultConfigLocation();
+            
+            if($this->shiphead_location_id != $l->pid()){
+                $roo->jerr("You must fill in the delivery notes!");
+            }
+            
+        }
+        
+        
+        
+        if (empty($q['shiphead_number'] ) || $q['shiphead_number'] == 'Automatic') {
+            $o = $this->order();
+            //DB_DataObject::DebugLevel(1);
+            $sh = DB_DataObject::factory('shiphead');
+            $sh->shiphead_order_id = $this->shiphead_order_id;
+            
+            $sh->whereAdd("shiphead_number like '" . $this->escape($o->cohead_number) . "-%'");
+            $sh->selectAdd('substr(shiphead_number, ' . strlen($o->cohead_number.'--') .')::numeric as shiphead_number_seq');
+            $sh->orderBy('shiphead_number_seq DESC');
+            if (!$sh->count()) {
+                
+                $this->shiphead_number = $o->cohead_number .'-1';
+            } else {
+                
+                $sh->limit(1);
+                $sh->find(true);
+                $n = array_pop(explode('-',$sh->shiphead_number)) * 1;
+                $this->shiphead_number = $o->cohead_number .'-' . ($n+1);
+                
+            }
+            
+        }
+        if (empty($this->shiphead_order_type)) {
+            $this->shiphead_order_type = 'SO';
+        }
+        
+        
+        
+    }
+    
+    function beforeUpdate($old,$q,$roo)
+    {
+        
+//        print_R($this);exit;
+    
+         
+        if (!empty($q['_void'])) {
+            
+            $this->factory('cohead')->lockTables();
+            if ($this->shiphead_shipped) {
+                
+                $res = $this->unconfirm($roo);
+                if ($res !== true) {
+                    if ($res == -4) {
+                        $roo->jerr("You need to unpost the invoice for this sales order");
+                    }
+                    $roo->jerr("recall returned ". serialize($res));
+                }
+                
+                $roo->jok("unconfirmed");
+            }
+            // result?
+            
+             
+            
+            $ret = $this->void($roo);
+            $ret === true ? $roo->jok("Voided") : $roo->jerr($ret);
+        }
+        
+        /*
+         *  check to see if the delivery notes is allow blank
+         *  if the shiphead location id is same as the default_location, then all blank, otherwise, MUST fill it in...
+         */
+        if(empty($this->shiphead_delivery_note)){
+            $l = DB_DataObject::factory('location');
+            $l = $l->defaultConfigLocation();
+            
+            if($this->shiphead_location_id != $l->pid()){
+                $roo->jerr("You must fill in the delivery notes!");
+            }
+            
+        }
+        
+        if ($this->shiphead_shipped) {
+            $roo->jerr("You can not modified confirmed shipments - void it");
+        }
+        
+    }
+    
+    
+    function unconfirm($roo)
+    {
+        
+        
+        $s = $this->factory('shiphead');
+        if (empty($roo->transObj)) {
+            $s->query("BEGIN");
+        }
+        //DB_DataObject::debugLevel(1);
+        
+        $items = $this->items();
+        if (!$items) {
+            // increase our revision.
+            $this->query("UPDATE shiphead
+                    SET
+                        shiphead_rev = shiphead_rev +1,
+                        shiphead_shipped=FALSE
+                    WHERE
+                        shiphead_id = {$this->shiphead_id}
+            ");
+            return true;
+        
+        }
+        
+        $gl= DB_DataObject::Factory('gltrans');
+        $gl->selectAdd();
+        $gl->selectAdd('max(gltrans_id) as gltrans_id');
+        $gl->find(true);
+        $glbefore = $gl->gltrans_id;
+        // now do the actuall recall..
+        $dt = date('Y-m-d', strtotime( $this->shiphead_shipdate));
+        $s->query("SELECT recallShipment({$this->pid()}, '$dt') as res");
+        $s->fetch();
+        
+        
+        // recall shipment returns null if it's a sales order...
+        if (!empty($s->res) && $s->res < 0) {
+            
+            if (empty($roo->transObj)) {
+               $s->query("ROLLBACK");
+            }   
+            return $s->res;
+            
+        }
+        
+        $gl= DB_DataObject::Factory('gltrans');
+        $gl->selectAdd();
+        $gl->selectAdd('max(gltrans_id) as gltrans_id');
+        $gl->find(true);
+        
+        if ($glbefore == $gl->gltrans_id) {
+            $roo->jerr("no gltrans was commited for recal shipment?");
+        }
+        
+        
+        
+        // hopefully the fact that we have recalled this shipment will not break this..
+        
+        $our_site = substr($this->database(), -2);
+        
+        
+        // where are we transfering to...
+        $loc = DB_DataObject::Factory('location');
+        if (!$this->shiphead_location_id || !$loc->get($this->shiphead_location_id)) {
+            $roo->jerr("no location specified");
+        }
+        $target = $our_site;
+        
+        if ($loc->location_cust_id) {
+            $cust = $loc->customer();
+            if (!$cust) {
+                $roo->jerr("the location specified does not have a customer associated with it. X");
+            }
+            
+            $target = $cust->char('INTERNALCOMPANY');
+            if (empty($target)) {
+                $target = $our_site;
+            }
+        }
+            
+            // who owns the target location
+        
+        
+        
+        // migration process can not transfer.
+        if (HTML_FlexyFramework::get()->cli && $target != $our_site) {
+            $roo->jerr("invalid transfer via cli");
+            
+        }
+        
+        
+        
+        // transfer if necessary..
+        if ($target != $our_site) {
+            $res  = $this->revertStockTransfer($roo);
+            if (true !== $res) {
+                // rollback handled by top level..
+                //$s->query("ROLLBACK");
+                
+                return $res;
+            }
+            
+        }
+        
+        // checck for transfer - it should really look up customers with that remote, and see how many there are..
+        
+      
+        
+        // increase our revision.
+        $this->query("UPDATE shiphead
+                    SET
+                        shiphead_rev = shiphead_rev +1
+                    WHERE
+                        shiphead_id = {$this->shiphead_id}
+        ");
+        
+        if (empty($roo->transObj)) {
+            $s->query("COMMIT");
+        }
+        return true;    
+    }
+    
+    function confirm($roo)
+    {
+        
+        $items = $this->items();
+        if (!$items) {
+            // increase our revision.
+            $roo->jerr("shipment does not have any items");
+            return true;
+        
+        }
+         
+        $s = $this->factory('shiphead');
+         if (empty($roo->transObj)) {
+            $s->query("BEGIN");
+        }
+        $dt = date('Y-m-d', strtotime( $this->shiphead_shipdate));
+        $s->query("SELECT shipShipment({$this->pid()}, '$dt') as res");
+        $s->fetch();
+        
+        if (!is_null($s->res)) {
+            if (empty($roo->transObj)) {
+                $s->query("ROLLBACK");
+            }
+           
+            $roo->jerr("ship returned ". serialize($s->res));
+        }
+        
+        $thisdb = substr($this->database(), -2);
+        
+        // migration process can not transfer.
+        
+        
+        // determine the location.
+        $loc = DB_DataObject::Factory('location');
+        if (!$loc->get($this->shiphead_location_id)) {
+            $roo->jerr("no location specified");
+        }
+        
+        
+        $cust = $loc->customer();
+        
+        if (!$cust) {
+            $roo->jerr("the location specified does not have a customer associated with it. X");
+        }
+        $location_db = $cust->char('INTERNALCOMPANY');
+        $location_db  = empty($location_db ) ? $thisdb : $location_db ;
+        
+        
+        $is_cli = HTML_FlexyFramework::get()->cli;
+        
+        if (HTML_FlexyFramework::get()->cli && ($thisdb != $location_db)) {  
+            $roo->jerr("cli can not do a transfer");
+        }
+        
+        // transfer if necessary..
+        if ($thisdb != $location_db) {
+            
+            //$roo->jerr("Stock transfer disabled at present $thisdb to $location_db");
+            $res  = $this->doStockTransfer($roo);
+            if (true !== $res) {
+                // rollback handled by top level..
+                //$s->query("ROLLBACK");
+                
+                return $res;
+            }
+            
+        }
+        // 
+        
+        
+        
+        // result?
+        if (empty($roo->transObj)) {
+            $s->query("COMMIT");
+        }
+        return true;
+        
+        
+         
+    }
+    
+    
+    function onInsert($q, $roo)
+    {
+        
+        if (isset($q['shipitems'])) {
+            $this->factory('cohead')->lockTables();
+            $this->updateItems(json_decode($q['shipitems']),$roo);
+        }
+        
+        
+    }
+    function onUpdate($old, $q, $roo)
+    {
+        if (isset($q['shipitems'])) {
+            $this->factory('cohead')->lockTables();
+            $this->updateItems(json_decode($q['shipitems']), $roo);
+        }
+        if (isset($q['_confirm'])) {
+            $this->factory('cohead')->lockTables();
+            $res = $this->confirm($roo);
+            if (true !== $res) {
+                $roo->jerr($res);
+            }
+        }
+        
+    }
+    
+    function void($roo)
+    {
+        // if it's void then
+        // shiphead_shipped = true and shipdate is empty..
+        if (!empty($this->shiphead_shipped) && empty($this->shiphead_shipdate) ) {
+            $roo->jerr("the shipment is already void");
+        }
+        $this->stashShipment();
+        
+        $old = $this->items();
+        
+        // always attempt to reverse it..
+        // the reverse code should delete the shipitem line - causing this to
+        // do nothing the next time round..
+        foreach($old as $id => $ol) {
+            $ol->reverse($roo);
+        }
+       
+        
+         if (!$old && empty($this->shiphead_shipdate)) {
+            return "Already void";
+        }
+       
+        $o = clone($this);
+        $this->shiphead_shipdate = $this->sqlValue('NULL');
+        $this->shiphead_shipped = true;
+        $this->update($o);
+        
+        // we have to flag it as shipped..
+        
+        
+        
+        return true;
+        
+        
+    }
+    /**
+     * update Items in a shipment
+     *  array :
+     *     order_item_id => qty
+     *  or
+     *  
+     *     n =>  array(
+     *              shipitem_orderitem_id => order_item_id
+                    shipitem_qty => qty
+     )
+     *
+     *
+     *
+     */
+    
+    
+    function updateItems($ar, $roo)
+    {
+        //print_r($ar);
+        //DB_DataObject::debugLevel(1);
+        // ar is 
+        //$o->shipitem_orderitem_id,
+        //$o->shipitem_qty,
+        
+       
+        $old = $this->items();
+        
+        $bar = array(); //$ar;
+        
+        // check stdcost of item to make sure it's not $0
+        $badItems = array();
+        
+        foreach ($ar as $order_item => $qty){
+            if (is_object($qty)) {
+                $order_item = $qty->shipitem_orderitem_id;
+                $qty = $qty->shipitem_qty;
+            }
+            
+            $oi = DB_DataObject::factory('coitem');
+            $oi->get($order_item);
+            $item = $oi->itemsite()->item();
+            
+            $i = DB_DataObject::factory('item');
+            $i->query("SELECT stdCost({$item->pid()}) AS cost");
+            $i->fetch();
+            if($i->cost == 0){
+                $badItems[] = $item->item_number;
+            }
+        }
+        
+        if(count($badItems)){
+            $roo->jerr("These items have 0 stdCost " . implode(', ', $badItems));
+        }
+        
+        // explode kits..
+        foreach($ar as $order_item=>$qty) {
+            
+            if (is_object($qty)) {
+                $order_item = $qty->shipitem_orderitem_id;
+                $qty = $qty->shipitem_qty;
+            }
+            // in theory what happens to kit parts being updated  to zero quantity
+            // I'm not sure it's even allowed..
+            //if (empty($qty )) {
+            //    $bar[$order_item] = $qty;
+            //    continue;
+            //}
+            
+            $oi = DB_DataObject::factory('coitem');
+            $oi->get($order_item);
+            if ($oi->itemsite()->item()->item_type != 'K') {
+                $bar[$order_item] = $qty;
+                continue;
+            }
+            // got a kit..
+            // find all the child elements..
+            $si = DB_DataObject::factory('coitem');
+            $si->coitem_linenumber =  $oi->coitem_linenumber;
+            $si->coitem_cohead_id   = $oi->coitem_cohead_id;
+            $si->whereAdd('coitem_subnumber != 0 ');
+            $si->find();
+            //echo "CONVERTING kit : {$oi->pid()}\n";
+            while ($si->fetch()) {
+                //echo "ADDING kit : {$si->coitem_id}\n";
+                $bar[$si->coitem_id] = floor($si->coitem_qtyord / $oi->coitem_qtyord) * $qty;
+            }
+            //$roo->jerr("fixing kit of parts at present");
+            
+        }
+        $ar = $bar;
+        
+                
+        // check stock      
+        if(!empty($roo->bootLoader->Xtuple['prevent_negative'])){
+            $stock = array();
+            foreach ($ar as $order_item => $qty){
+                if (is_object($qty)) {
+                    $order_item = $qty->shipitem_orderitem_id;
+                    $qty = $qty->shipitem_qty;
+                }
+                if(empty($qty)){
+                    continue;
+                }
+
+                $coitem = DB_DataObject::factory('coitem');
+                $coitem->get($order_item);
+
+                $balance = $coitem->itemsite()->checkLocationStock($this->shiphead_location_id);
+                
+                if(empty($balance) || $balance < $qty){
+                    $stock[] = $coitem->itemsite()->item()->item_number;
+                }
+            }
+
+            if(count($stock)){
+                $roo->jerr("These items have negative stock " . implode(', ', $stock));
+            }
+        }
+        
+        
+        foreach($ar as $order_item=>$qty) {
+            if (is_object($qty)) {
+                $order_item = $qty->shipitem_orderitem_id;
+                $qty = $qty->shipitem_qty;
+            }
+            
+            if (!isset($old[$order_item])) {
+                if (empty($qty )) {
+                    continue; // skip empty lines..
+                }
+                $this->addShipitem($order_item, $qty );
+                continue;
+            }
+            $ol = $old[$order_item];
+            
+            
+            
+            if ($ol->shipitem_qty == $qty) {
+                unset($old[$order_item]);
+                continue;
+            }
+            //$roo->jerr("REVERSING");
+            $ol->reverse($roo);
+            if (empty($qty )) {
+                unset($old[$order_item]);
+                continue;
+            }
+            
+            $this->addShipItem($order_item, $qty );
+            unset($old[$order_item]);
+        }
+        // $ar - should contain all the order items.. if it does not...
+        // then we should update the quatities.
+        foreach($old as $id => $ol) {
+            $ol->reverse($roo);
+        }
+        
+        
+    }
+    /**
+     * add  a ship item
+     *
+     * - this mimic's issueToshipping
+     * 
+     * @param int|Object $oid the orderitem id or orderitem dataobject
+     * @param number     $qty the quantity to add.. - there should only be one per order..
+     *
+     */
+    function addShipItem($oid, $qty)
+    {
+        $si = $this->factory('shipitem');
+        $o = $this->order();
+        if (is_object($oid)) {
+            $oi = $oid;
+            $oid = $oi->pid();
+        } else { 
+            $oi = $this->factory('coitem');
+            $oi->get($oid);
+        }
+        // it's actually a
+        
+        $itemsite = DB_DataObject::factory('itemsite');
+        $itemsite->get('itemsite_id', $oi->coitem_itemsite_id);
+        if ($itemsite->itemsite_controlmethod !='R') {
+            // it will not get created..
+            return -1;
+            
+        }
+          $roo = HTML_FlexyFramework::get()->page;
+        if (!$itemsite->itemsite_stocked) {
+            $roo->jerr("Item ". $itemsite->item()->item_number . " is not marked as stocked, so can not be fullfilled.");
+            
+        }
+        if (!$itemsite->itemsite_loccntrl) {
+            $roo->jerr("Item ". $itemsite->item()->item_number . " is not marked as location controlled, so can not be fullfilled.");
+        }
+        
+         
+        $d = $this->factory($this->tablename());
+        
+      
+        if (empty($roo->transObj)) { 
+            $d->query("BEGIN");
+        }
+        
+        // verify the product is stocked...
+        
+        
+        
+        
+        
+        
+        /// issue to shipping can not handle multiple shipments for the same
+        // product!!!
+        $ci = $this->factory('coitem');
+        $ci->query("SELECT NEXTVAL('itemloc_series_seq')::integer as itemlocseries ");
+        $ci->fetch();
+        $itemlocSeries = $ci->itemlocseries;
+        
+        
+        $ci = $this->factory('coitem');
+        $q = "SELECT postInvTrans(
+                itemsite_id,
+                'SH'::text,
+                {$qty}::numeric ,
+                'S/R'::text,
+                'SO'::text,
+                formatSoNumber(coitem_id),
+                shiphead_number,
+                ('Issue ' || item_number || ' to Shipping for customer ' || cohead_billtoname),
+                getPrjAccntId(cohead_prj_id, costcat_shipasset_accnt_id), costcat_asset_accnt_id,
+                $itemlocSeries,
+                CAST('{$this->shiphead_shipdate}' AS timestamp with time zone)
+                ) AS invhistid
+            FROM coitem, cohead, itemsite, item, costcat, shiphead
+                WHERE ( (coitem_cohead_id=cohead_id)
+                 AND (coitem_itemsite_id=itemsite_id)
+                 AND (itemsite_item_id=item_id)
+                 AND (itemsite_costcat_id=costcat_id)
+                 AND (coitem_id={$oid})
+                 AND (shiphead_id={$this->shiphead_id}) )";
+        
+              
+        $ci->query($q);
+        $ci->fetch(true);
+        if (empty($ci->invhistid) || $ci->invhistid < 0) {
+            
+            $roo->jerr("post inv trans failed " . @$ci->invhistid );
+            //echo $q; exit;
+        }
+        
+        $si->setFrom(array(
+            
+            'shipitem_orderitem_id' => $oid,
+            'shipitem_shiphead_id' => $this->shiphead_id,
+            'shipitem_qty'=> $qty,
+            'shipitem_shipped' =>false,
+            'shipitem_shipdate' => $this->shiphead_shipdate,
+            'shipitem_transdate' =>  $this->shiphead_shipdate, // $this->sqlValue('NOW()'),
+            //'shipitem_trans_username' text,
+            'shipitem_invoiced' => false,
+            //'shipitem_invcitem_id' => 
+            //'shipitem_value' => $oi->coitem_custprice * $qty,
+            'shipitem_invhist_id' => $ci->invhistid
+            
+            
+        ));
+        
+       // $si->shipitem_value = $si->sqlValue("
+       //         currtobase({$o->cohead_curr_id}, {$oi->coitem_custprice} * {$qty}, '{ $this->shiphead_shipdate}')
+       // ");
+        $si->shipitem_value = $si->sqlValue("
+                (SELECT invhist_value_before - invhist_value_after FROM invhist where invhist_id = {$ci->invhistid} )
+        ");
+        $si->insert();
+         
+        
+        
+         $d = $this->factory($this->tablename());
+        $d->query("
+                  
+                    SELECT
+                            itemlocdist_id,
+                            itemlocdist_reqlotserial,
+                            itemlocdist_distlotserial,
+                            itemlocdist_qty,
+                            itemsite_loccntrl,
+                            itemsite_controlmethod,
+                            itemsite_perishable,
+                            itemsite_warrpurc,
+                            COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                            COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                        FROM
+                            itemlocdist, itemsite
+                        WHERE
+                            ( (itemlocdist_itemsite_id=itemsite_id)
+                            AND
+                            (itemlocdist_series=$itemlocSeries) )
+                        ORDER BY itemlocdist_id;
+
+                  
+                   
+                ");
+        $d->fetch();
+        
+        if (empty($d->itemlocdist_id)) {
+            $ssi = DB_DataObject::factory('shipitem');
+            $ssi->get($si->pid());
+            $roo->jerr("FAILED TO ADD ITEM " . $itemlocSeries. "\n".
+                print_r($ssi->toArray(), true)                      
+                       );
+        }
+        
+        $itemlocdist_id = $d->itemlocdist_id;
+        /*
+        while ($d->fetch()) {
+            print_r($d->toArray('%s', true));
+        }
+       
+        //print_r($ildist->toArray('%s', true));exit;
+             */
+        
+        // why grab from the line item...
+        // it should grab from the shiphead?!?
+        
+        $location = $this->shiphead_location_id; /// where.... from..
+        
+           
+        $d = $this->factory($this->tablename());
+        $d->query("
+                  
+                INSERT INTO
+                    itemlocdist (
+                        itemlocdist_itemlocdist_id, itemlocdist_source_type,
+                        itemlocdist_source_id,  itemlocdist_qty,
+                        itemlocdist_ls_id, itemlocdist_expiration
+                    )
+                    SELECT
+                        itemlocdist_id,       'L',
+                        {$location},        {$qty} * -1,
+                        itemlocdist_ls_id, endOfTime()
+                    FROM
+                        itemlocdist
+                    WHERE (itemlocdist_id= $itemlocdist_id);
+
+            ");
+                  
+                  
+                  
+               
+        
+        // this generates an additional itemlocdist record..
+        
+        $d = $this->factory($this->tablename());
+        $d->query("SELECT distributeToLocations({$itemlocdist_id}) AS result");
+        $d = $this->factory($this->tablename());
+        $d->query("SELECT postItemlocseries({$itemlocSeries}) AS result");
+        
+        $d = $this->factory($this->tablename());
+        
+        if (empty($roo->transObj)) { 
+
+            $d->query("COMMIT");
+        }
+        
+        
+         
+        
+        
+        
+        return $si->pid(); //we could return insert()...
+    }
+    
+    // dumping old versions..
+    function stashItems()
+    {
+        $i = $this->factory('shipitem');
+        $i->selectAdd();
+        $i->shipitem_shiphead_id = $this->pid();
+        $i->selectAdd("
+            (SELECT coitem_itemsite_id FROM coitem where coitem_id = shipitem_orderitem_id) AS itemsite_id,
+            shipitem_qty
+        ");
+        return $i->fetchAll('itemsite_id','shipitem_qty');
+        
+    }
+    
+    
+    function stashShipment()
+    {
+        
+        $old = $this->stashItems();
+        if (empty($old)) {
+            return; // no point in stashing empty..
+        }
+        // we should stash based on id.. - so old ones can be deleted.
+        // group into 100's.. eg.
+        //  /shipstash/{floor(id/100)00/{id}/... versions..
+        $ff = HTML_FlexyFramework::get();
+        
+        if (empty($ff->Xtuple['storedir'])) {
+            $ff->page->jerr("Xtuple['storedir'] is not configured");
+        }
+        
+        $fd = $ff->Xtuple['storedir'] .
+            '/shipstash/' .
+            floor($this->shiphead_order_id /100) .
+            '/' . $this->shiphead_order_id .'/';
+        
+        
+        if (!is_writable( $ff->Xtuple['storedir'])) {
+            $ff->page->jerr("Xtuple['storedir'] is not writable");
+            return;
+        }
+        
+        if (!file_exists($fd)) {
+            mkdir($fd,0700, true);
+        }
+        
+        $d = time();
+        while (true) {
+            $fn = $fd.  $this->shiphead_number . '_' . date('Y-m-d h:i:s',$d). '.json';
+            if (file_exists($fn)) {
+                $d++;
+                continue;
+            }
+            break;
+        }
+        
+       
+        
+        file_put_contents($fn, json_encode( $old ));
+        //$ff->page->jok("wrote stash");
+        
+    }
+    function stashList($id, $roo)
+    {
+        $ff = HTML_FlexyFramework::get();
+        
+        $id = (int) $id;
+        
+           
+        
+        if (empty($ff->Xtuple['storedir'])) {
+            $roo>jerr("Xtuple['storedir'] is not configured");
+        }
+        $fd = $ff->Xtuple['storedir'] .
+            '/shipstash/' .
+            floor($id /100) .
+            '/' . $id;
+            
+        if (!file_exists($fd)) {
+            $roo->jerr("no data available " . $fd);
+            $roo->jdata(array());
+        }
+        
+        
+        
+        $ret = array();
+        foreach(scandir($fd) as $d) {
+            if (!preg_match('/\.json$/', $d)) {
+                continue;
+            }
+            $n = preg_replace('/\.json$/', '', $d);
+            $n = explode('_', $n);
+            $n = $n[0] . ' voided on ' . $n[1];
+            
+            $ret[] = array(
+                
+                'name' => $n,
+                'data' => json_decode(file_get_contents($fd.'/'. $d))
+            );
+        }
+        return $roo->jdata($ret);
+        
+        
+    }
+    /**
+     * return a list of what should be transfered.
+     *
+     * 
+     */
+    function transferItems()
+    {
+        $i = $this->factory('shipitem');
+        $i->selectAdd();
+        $i->shipitem_shiphead_id = $this->pid();
+        $i->selectAdd("
+            (SELECT  item_number
+                FROM coitem
+                LEFT JOIN itemsite ON coitem_itemsite_id = itemsite_id
+                LEFT JOIN item ON itemsite_item_id = item_id
+                WHERE coitem_id = shipitem_orderitem_id
+            ) AS item_number,
+            shipitem_qty
+        ");
+        // only transfer products... ?? should be default... - code should not generate shipments for kits etc..
+        /*$i->whereAdd("
+            'P' = (SELECT   item_type
+                FROM coitem
+                LEFT JOIN itemsite ON coitem_itemsite_id = itemsite_id
+                LEFT JOIN item ON itemsite_item_id = item_id
+                WHERE coitem_id = shipitem_orderitem_id
+            ) 
+            
+             
+        ")*/
+        return $i->fetchAll('item_number','shipitem_qty');
+        
+    }
+    /**
+     * return a list of source locations for this shipment - it should
+     * only return 1 in our system...
+     *
+     */
+     
+     
+    function sourceLocations()
+    {
+        // this is based on the location listed in the coitem
+        $i = $this->factory('shipitem');
+        $i->selectAdd();
+        $i->shipitem_shiphead_id = $this->pid();
+        $i->selectAdd("
+            (SELECT  coitem_location_src
+                FROM coitem
+                WHERE coitem_id = shipitem_orderitem_id
+            ) AS location_src
+                      ");
+        $src = array_unique($i->fetchAll('location_src'));
+        return $src;
+    }
+    
+    function doStockTransfer($roo)
+    {
+        $roo->sessionState(0); // non-locking!?
+        $roo->jerr("stock transfer is disabled at present");
+        
+        
+        // why credit HK?
+        //if ($this->order()->cust()->cust_name == 'Bloom and Grow HK') {
+        //    return $this->creditHK($roo);
+        //}
+       
+       
+        $srcs = $this->sourceLocations();
+        if (count($srcs) != 1) {
+            return "Shipment contains multiple source locations - this should not be allowed";
+        }
+        
+       
+        $loc = DB_DataObject::Factory('location');
+        $loc->get($srcs[0]); 
+        $cust = $loc->customer();
+        
+        $our_db = substr($this->database(),-2);
+        $remote_db = $cust->char('INTERNALCOMPANY');
+        if ($our_db == $remote_db) {
+            $roo->jerr("stock transfer between same company - something is set up wrong.");
+        }
+        
+        
+        
+        
+        
+        // create a purchase order...
+        
+        $po = DB_DataObject::factory('pohead');
+        //Create purchase order + reciept + voucher.
+        //createAllFromShipment($roo, $shiphead, $remote_db, $cust, $loc)
+        $prices = $po->createAllFromShipment($roo, $this, $remote_db, $cust, $loc);
+        
+   
+        
+        // ensure we have a price list???
+        
+        
+        
+        $order = $this->order();
+        $tx_items =  $this->transferItems();
+        $items = array();
+        $line = 0;
+        foreach($tx_items as  $item=>$qty) {
+            $line ++;
+            
+            $items[] = array(
+                    
+                'linenumber' => $line,
+                'qty' => $qty,
+                'unitprice' => $prices[$item],
+                'item_number' => $item,
+            );
+            
+        }
+        
+        
+       
+       
+        
+        
+        // find the location it is comming from...
+        
+        
+        
+        
+        
+        
+        // on hk side..
+        //Needs to know 
+        //  Order number (so it can be voided later..)
+        //  list of items (and the source location)
+        //  Qty
+        //  UnitPrice?? - this should be the FIFO cost..
+        
+        
+        // on the signapore site
+        
+        $rev = $this->shiphead_rev ?   '-rev' . $this->shiphead_rev  : '';
+        //$roo->jerr($this->shiphead_rev);
+        
+         
+        require_once 'HTTP/Request.php';
+        
+        $req = new HTTP_Request( "{http://localhost/$roo->rootURL/{$remote_db}.php/Roo/Invchead" );
+        $req->setMethod(HTTP_REQUEST_METHOD_POST);
+        $req->addPostData( array(
+                '_is_xfer' => $our_db,
+                'invchead_invcnumber' => 'XF-'.$this->shiphead_number . $rev,  // invoice should match number...
+                'invchead_orderdate' => $this->shiphead_shipdate,
+                'invchead_invcdate' => $this->shiphead_shipdate,
+                //'cust_number' => $ff->Xtuple['main_remote_cust_number'] , // $roo->jerr("Old code using remote_customer - disabled");
+                'invchead_posted' => false,
+                'invchead_printed' => false,
+                'invchead_commission' => 0,
+                'invchead_freight' => 0,
+                'invchead_misc_amount' => 0,
+                'invchead_shipchrg_id' => -1,
+                'items' => $items,
+                'src_location' => $loc->location_name
+          
+        ));
+        
+        $res = $req->sendRequest();
+        if (is_a($res,'PEAR_Error')) {
+            return "MAIN REQUEST RETURNED: ". $res->toString();
+        }
+        $res = json_decode($req->getResponseBody());
+        
+        
+        
+        if (!is_object($res)) {
+            return "MAIN REQUEST RETURNED: ". $req->getResponseBody();
+        }
+        
+        if (!$res->success) {
+            return "MAIN REQUEST RETURNED: ". $res->errorMsg;
+        }
+         
+        return true;
+         
+        
+    }
+    // invoicing HK for stock..
+    
+    
+    function creditHK($roo)
+    {
+          
+        $this->jerr("creditHK code - creates a credit memo on remote site? - why?");
+        $ff = HTML_FlexyFramework::get();
+        
+        if (empty($ff->Xtuple['main_url'])) {
+            $roo->jerr("Xtuple['main_url'] is not configured");
+        }
+        if (empty($ff->Xtuple['main_remote_cust_number'])) {
+            //$roo->jerr( "Xtuple['main_remote_cust_number'] is not configured");
+            $roo->jerr("Old code using remote_customer - disabled");
+        }
+        
+        
+        
+         
+        
+        $order = $this->order();
+        $tx_items =  $this->transferItems();
+        $po = DB_DataObject::factory('pohead');
+        $prices = $po->fetchXferPrices($roo, $tx_items);
+            
+        
+        $items = array();
+        $line = 0;
+        foreach($tx_items as  $item=>$qty) {
+            $line ++;
+            $items[] = array(
+                    
+                'linenumber' => $line,
+                'qty' => $qty,
+                'unitprice' => $prices[$item],
+                'item_number' => $item,
+            );
+            
+        }
+        
+        
+        $srcs = $this->sourceLocations();
+        if (count($srcs) != 1) {
+            return "Shipment contains multiple source locations - this should not be allowed";
+            
+        }
+        $loc = DB_DataObject::Factory('location');
+        $loc->get($srcs[0]); 
+        
+        
+        
+        
+        
+        // on hk side..
+        //Needs to know 
+        //  Order number (so it can be voided later..)
+        //  list of items (and the source location)
+        //  Qty
+        //  UnitPrice?? - this should be the FIFO cost..
+        
+        
+        // on the signapore site
+        
+        $full = DB_DataObject::Factory('cmhead');
+        $full->autoJoin();
+        $full->get($this->pid());
+        
+        $roo->jerr("Old code using remote_customer - disabled");
+        
+        require_once 'HTTP/Request.php';
+        
+        $req = new HTTP_Request( $ff->Xtuple['main_url'] . '/Roo/Cmhead' );
+        $req->setMethod(HTTP_REQUEST_METHOD_POST);
+                    
+        $req->addPostData( array(
+                '_is_xfer' => 1,
+                
+                
+                'cmhead_number' => 'XF-INV-' . $this->shiphead_number,
+                'cust_number' => $ff->Xtuple['main_remote_cust_number'], // $roo->jerr("Old code using remote_customer - disabled");
+                'cmhead_docdate' => $this->shiphead_shipdate,
+    
+                
+                'cmhead_freight' => 0 , //$full->cmhead_freight ,
+                'cmhead_misc' => 0, //$full->cmhead_misc,
+            
+                'cmhead_comments' => $full->cmhead_comments,
+                //'cmhead_misc_descrip'=> '', //$full->cmhead_misc_descrip,
+                
+                'location_name' => $loc->location_name,
+                //'cmhead_misc_accnt_id_accnt_number' => $full->cmhead_misc_accnt_id_accnt_number,
+                
+    
+                //'cmhead_curr_id;                  // int4(4)  default_basecurrid%28%29
+                //cmhead_freighttaxtype_id;        // int4(4)  
+                //public $cmhead_salesrep_id;              // int4(4)  
+    
+                //cmhead_taxzone_id;               // int4(4)  
+    
+                 
+                'items' => $items,
+                
+        ));
+        
+        $res = $req->sendRequest();
+        if (is_a($res,'PEAR_Error')) {
+            $roo->jerr( "MAIN REQUEST RETURNED: ". $res->toString());
+        }
+        $res = json_decode($req->getResponseBody());
+        
+        
+        
+        if (!is_object($res)) {
+            $roo->jerr("MAIN REQUEST RETURNED: ". $req->getResponseBody());
+        }
+        
+        if (!$res->success) {
+            $roo->jerr("MAIN REQUEST RETURNED: ". $res->errorMsg);
+        }
+         
+        return true;
+    }
+    
+    
+    
+    function revertStockTransfer($roo)
+    {
+        $roo->jerr("stock transfer is disabled at present");
+        if ($this->order()->cust()->cust_name == 'Bloom and Grow HK') {
+            $roo->jerr("You can not reverse transfers to HK - you need to create
+                       a credit memo for HK - which will move the stock back");
+        }
+        
+        
+        if (preg_match('/-d$/', $this->shiphead_number)) {
+            // it's a migrated record.. no need to track stuff..
+            return true;
+        }
+        
+        $po = DB_DataObject::factory('pohead');
+        //Create purchase order + reciept + voucher.
+        $po->revertAllFromShipment($roo, $this);
+        
+        $ff = HTML_FlexyFramework::get();
+        
+        if (empty($ff->Xtuple['main_url'])) {
+            return "Xtuple['main_url'] is not configured";
+        }
+        //if (empty($ff->Xtuple['main_remote_cust_number'])) {
+        //    return "Xtuple['main_remote_cust_number'] is not configured";
+        //}
+        
+        
+        $order = $this->order();
+         
+        
+        
+        // on hk side..
+        //Needs to know 
+        //  Order number (so it can be voided later..)
+        //  list of items (and the source location)
+        //  Qty
+        //  UnitPrice?? - this should be the FIFO cost..
+        
+        
+        // on the signapore site
+        
+        $rev = $this->shiphead_rev ?  '-rev' . $this->shiphead_rev  : '';
+        
+        require_once 'HTTP/Request.php';
+        
+        $req = new HTTP_Request( $ff->Xtuple['main_url'] . '/Roo/Invchead' );
+        $req->setMethod(HTTP_REQUEST_METHOD_POST);
+        $req->addPostData( array(
+                '_is_xfer_void' => 1,
+                'invchead_invcnumber' => 'XF-'.$this->shiphead_number . $rev
+        ));
+        
+        $res = $req->sendRequest();
+        if (is_a($res,'PEAR_Error')) {
+            return "MAIN REQUEST RETURNED: ". $res->toString();
+        }
+        $res = json_decode($req->getResponseBody());
+        
+        
+        
+        if (!is_object($res)) {
+            return "MAIN REQUEST RETURNED: ". $req->getResponseBody();
+        }
+        
+        if (!$res->success) {
+            return "MAIN REQUEST RETURNED: ". $res->errorMsg;
+        }
+         
+        return true;
+         
+        
+        
+        
+        
+    } 
+    
+    
+    function download($roo)
+    {
+        
+         //DB_DAtaObject::debugLevel(1);
+        
+        $r= DB_DataObject::Factory('shipitem');
+        $r->shiphead($this);
+        $r->autoJoin();
+        $r->joinAddItem();
+        $r->joinAddCoitem();
+        //$r->applyFilters(array(), $roo->authUser, $roo);
+        
+        $r->orderBy('coitem_linenumber ASC, coitem_subnumber ASC');
+        
+        $order = $this->order();
+        $loc = $this->location();
+        $shipto = $this->shipto();
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        $s = new Pman_Core_SimpleExcel(
+            $r->fetchAll(false,false,'toArray'),
+            array(
+                'head' => array( 
+                                
+                        array( "Ship Date:", date('Y-m-d', strtotime($this->shiphead_shipdate))),
+                        array( "Order ID:", $order->cohead_number),
+                        array( "From:", $loc->location_name),
+                        array( "To:", implode("\n", $shipto->address())),
+                ),
+                'cols' => array(
+                    
+                    array(
+                        'header'=> "Item Code",
+                        'dataIndex'=> 'item_number',
+                        'width'=>  100,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Description",
+                        'dataIndex'=> 'item_descrip1',
+                        'width'=>  300,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                    array(
+                        'header'=> "Quantity",
+                        'dataIndex'=> 'shipitem_qty',
+                        'width'=>  50,
+                    //'renderer' => array($this, 'getThumb')
+                    ),
+                ),
+                
+                'workbook' => 'Shipment'
+            
+             )
+        );
+        $s->send($this->shiphead_number.date("-d-M-Y").'.xls');
+        
+         
+        
+    }
+    
+    
+}
+
diff --git a/DataObjects/Shipitem.php b/DataObjects/Shipitem.php
new file mode 100644 (file)
index 0000000..beea556
--- /dev/null
@@ -0,0 +1,225 @@
+<?php
+/**
+ * Table Definition for shipitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipitem';            // table name
+    public $shipitem_id;                     // int4(4)  not_null default_nextval%28shipitem_shipitem_id_seq%29 primary_key
+    public $shipitem_orderitem_id;           // int4(4)  not_null
+    public $shipitem_shiphead_id;            // int4(4)  not_null
+    public $shipitem_qty;                    // numeric(-1)  not_null
+    public $shipitem_shipped;                // bool(1)  not_null default_false
+    public $shipitem_shipdate;               // timestamptz(8)  
+    public $shipitem_transdate;              // timestamptz(8)  
+    public $shipitem_trans_username;         // text(-1)  
+    public $shipitem_invoiced;               // bool(1)  not_null default_false
+    public $shipitem_invcitem_id;            // int4(4)  
+    public $shipitem_value;                  // numeric(-1)  
+    public $shipitem_invhist_id;             // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $shipitem_invcitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invcitem() {
+        return func_num_args() ? $this->link('shipitem_invcitem_id', func_get_arg(0)) : $this->link('shipitem_invcitem_id');
+    }
+
+   /**
+    * Getter / Setter for $shipitem_invhist_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invhist() {
+        return func_num_args() ? $this->link('shipitem_invhist_id', func_get_arg(0)) : $this->link('shipitem_invhist_id');
+    }
+
+   /**
+    * Getter / Setter for $shipitem_shiphead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shiphead() {
+        return func_num_args() ? $this->link('shipitem_shiphead_id', func_get_arg(0)) : $this->link('shipitem_shiphead_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    public function orderitem()
+    {
+        // set..
+        if (func_num_args()) {
+            $arg =  func_get_arg(0);
+            $this->shipitem_orderitem_id = is_object($arg) ? $arg->coitem_id : $arg;
+            return;
+        }
+        //get...
+        $r = DB_DataObject::factory('coitem');
+        $r->get($this->shipitem_orderitem_id);
+        return $r;
+           
+    }
+    
+    function joinAddItem()
+    {
+       
+        $this->_join  .= '
+            LEFT JOIN item ON
+                item_id = (SELECT itemsite_item_id FROM itemsite WHERE itemsite_id = (
+                    SELECT coitem_itemsite_id FROM coitem where coitem_id = shipitem_orderitem_id
+                ))
+            ';
+        $i = DB_DataObject::Factory('item');
+        $this->selectAs($i, '%s');
+        
+    }
+     function joinAddCoitem()
+    {
+       
+        $this->_join  .= '
+            LEFT JOIN coitem ON coitem_id = shipitem_orderitem_id
+            ';
+        $i = DB_DataObject::Factory('coitem');
+        $this->selectAs($i, '%s');
+        
+    }
+    
+    function reverse($roo)
+    {
+        $si = DB_DataObject::factory($this->tablename());
+        if (!$si->get($this->shipitem_id)) {
+            $this->jerr("shipitem does not exist?");
+        }
+        
+        $si = $this;
+        $sh = $this->shiphead();
+        $o = $sh->order();
+        $oi = $this->orderitem();
+        
+        $item = $oi->itemsite()->item();
+        
+        // it's actually a
+        
+        /// issue to shipping can not handle multiple shipments for the same
+        // product!!!
+        
+      
+        
+        
+        
+        // force it to int..
+        $o->cohead_prj_id           = (int) $o->cohead_prj_id;
+        $this->shipitem_value       = (int) $this->shipitem_value;
+        $this->shipitem_invhist_id  = (int) $this->shipitem_invhist_id;
+        
+        $dt = $sh->shiphead_shipdate;
+        if (empty($dt)) {
+            $dt = $o->cohead_orderdate; // hopefully that's set..
+        }
+        
+        // check that this still exists..
+        
+        
+        // doing returnItemShipments.
+        
+        // and returnshipmenttransaction
+        //DB_DataObject::DebugLevel(1);
+        $ci = $this->factory('coitem');
+        $ci->query("SELECT NEXTVAL('itemloc_series_seq')::integer as itemlocseries ");
+        $ci->fetch();
+        $itemlocSeries = $ci->itemlocseries;
+        
+        // creates an invhist entry..
+       // DB_DataObject::debugLevel(1);
+        $ci = $this->factory('coitem');
+        
+        // if ship qty is neg. it was an old bug, and we need to treat it as a shipment.
+        
+      
+        
+      
+        
+         $query = "   SELECT postInvTrans(
+                    itemsite_id,
+                    '"  . ( $this->shipitem_qty > 0 ?  'RS' : 'SH') .  "'::text,
+                    ". abs($this->shipitem_qty) . "::numeric,
+                    'S/R'::text,
+                    'SO'::text,
+                    formatSoNumber({$this->shipitem_orderitem_id}),
+                    shiphead_number,
+                    'Return from Shipping'::text,
+                    costcat_asset_accnt_id,
+                    getPrjAccntId({$o->cohead_prj_id}, costcat_shipasset_accnt_id),
+                    $itemlocSeries,
+                    CAST('{$dt}' AS timestamp with time zone),
+                    {$this->shipitem_value},
+                     {$si->shipitem_invhist_id}
+                ) AS invhistid
+          FROM
+            coitem,
+            itemsite,
+            costcat,
+            shiphead,
+            shipitem
+          WHERE (
+                (coitem_itemsite_id=itemsite_id)
+           AND
+                (itemsite_costcat_id=costcat_id)
+           AND
+                (coitem_id={$this->shipitem_orderitem_id})
+           AND
+                (shiphead_order_type='{$sh->shiphead_order_type}')
+           AND
+                (shiphead_id=shipitem_shiphead_id)
+           AND
+                (shipitem_orderitem_id={$this->shipitem_orderitem_id})
+            AND
+                (shiphead_id={$sh->pid()})
+            )
+        ";
+        
+          $ci->query($query);
+        
+        
+        // needs to move stock back to where it came from..
+        
+         
+        $ci->fetch();
+        if (empty($ci->invhistid) || $ci->invhistid < 0) {
+            $roo->jerr("{$item->item_number} postInvTrans UPDATE FAILED??\n" .
+                       (empty($ci->invhistid)  ? 'empty' : $ci->invhistid ));
+        }
+        
+        $ci = $this->factory('coitem');
+        $ci->query("SELECT postItemlocseries({$itemlocSeries}) as result");
+          $ci->fetch();
+        if (empty($ci->result) || !$ci->result  ) {
+            $roo->jerr(" {$item->item_number}  postItemlocseries ($itemlocSeries) UPDATE FAILED : " .
+                       (empty($ci->result)  ? 'empty' : $ci->result  ).
+                       "\n". $query
+                       
+                       );
+        }
+         
+        $si->delete();
+        
+        
+    }
+    
+    
+     
+}
diff --git a/DataObjects/Shipitemlocrsrv.php b/DataObjects/Shipitemlocrsrv.php
new file mode 100644 (file)
index 0000000..70a2969
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Table Definition for shipitemlocrsrv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipitemlocrsrv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipitemlocrsrv';     // table name
+    public $shipitemlocrsrv_id;              // int4(4)  not_null default_nextval%28shipitemlocrsrv_shipitemlocrsrv_id_seq%29 primary_key
+    public $shipitemlocrsrv_shipitem_id;     // int4(4)  not_null
+    public $shipitemlocrsrv_itemsite_id;     // int4(4)  not_null
+    public $shipitemlocrsrv_location_id;     // int4(4)  not_null
+    public $shipitemlocrsrv_ls_id;           // int4(4)  
+    public $shipitemlocrsrv_expiration;      // date(4)  
+    public $shipitemlocrsrv_warrpurc;        // date(4)  
+    public $shipitemlocrsrv_qty;             // numeric(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $shipitemlocrsrv_itemsite_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function itemsite() {
+        return func_num_args() ? $this->link('shipitemlocrsrv_itemsite_id', func_get_arg(0)) : $this->link('shipitemlocrsrv_itemsite_id');
+    }
+
+   /**
+    * Getter / Setter for $shipitemlocrsrv_location_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function location() {
+        return func_num_args() ? $this->link('shipitemlocrsrv_location_id', func_get_arg(0)) : $this->link('shipitemlocrsrv_location_id');
+    }
+
+   /**
+    * Getter / Setter for $shipitemlocrsrv_shipitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipitem() {
+        return func_num_args() ? $this->link('shipitemlocrsrv_shipitem_id', func_get_arg(0)) : $this->link('shipitemlocrsrv_shipitem_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipto.php b/DataObjects/Shipto.php
new file mode 100644 (file)
index 0000000..6f7cbe4
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Table Definition for shipto
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipto extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipto';              // table name
+    public $shipto_id;                       // int4(4)  
+    public $shipto_cust_id;                  // int4(4)  
+    public $shipto_name;                     // text(-1)  
+    public $shipto_address1;                 // text(-1)  
+    public $shipto_address2;                 // text(-1)  
+    public $shipto_address3;                 // text(-1)  
+    public $shipto_city;                     // text(-1)  
+    public $shipto_state;                    // text(-1)  
+    public $shipto_zipcode;                  // text(-1)  
+    public $shipto_taxzone_id;               // int4(4)  
+    public $shipto_salesrep_id;              // int4(4)  
+    public $shipto_phone;                    // text(-1)  
+    public $shipto_comments;                 // text(-1)  
+    public $shipto_shipcomments;             // text(-1)  
+    public $shipto_contact;                  // text(-1)  
+    public $shipto_fax;                      // text(-1)  
+    public $shipto_email;                    // text(-1)  
+    public $shipto_shipzone_id;              // int4(4)  
+    public $shipto_shipvia;                  // text(-1)  
+    public $shipto_commission;               // numeric(-1)  
+    public $shipto_shipform_id;              // int4(4)  
+    public $shipto_shipchrg_id;              // int4(4)  
+    public $shipto_active;                   // bool(1)  
+    public $shipto_default;                  // bool(1)  
+    public $shipto_num;                      // text(-1)  
+    public $shipto_ediprofile_id;            // int4(4)  
+    public $shipto_country;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+   
+   
+    // use shiptoinfo..
+}
diff --git a/DataObjects/Shiptoinfo.php b/DataObjects/Shiptoinfo.php
new file mode 100644 (file)
index 0000000..1c9b346
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+/**
+ * Table Definition for shiptoinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shiptoinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shiptoinfo';          // table name
+    public $shipto_id;                       // int4(4)  not_null default_nextval%28%28shipto_shipto_id_seq%29%3A%3Aregclass%29 primary_key
+    public $shipto_cust_id;                  // int4(4)  not_null unique_key multiple_key
+    public $shipto_name;                     // text(-1)  
+    public $shipto_salesrep_id;              // int4(4)  
+    public $shipto_comments;                 // text(-1)  
+    public $shipto_shipcomments;             // text(-1)  
+    public $shipto_shipzone_id;              // int4(4)  
+    public $shipto_shipvia;                  // text(-1)  
+    public $shipto_commission;               // numeric(-1)  not_null
+    public $shipto_shipform_id;              // int4(4)  
+    public $shipto_shipchrg_id;              // int4(4)  
+    public $shipto_active;                   // bool(1)  not_null
+    public $shipto_default;                  // bool(1)  
+    public $shipto_num;                      // text(-1)  unique_key multiple_key
+    public $shipto_ediprofile_id;            // int4(4)  
+    public $shipto_cntct_id;                 // int4(4)  
+    public $shipto_addr_id;                  // int4(4)  
+    public $shipto_taxzone_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $shipto_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('shipto_addr_id', func_get_arg(0)) : $this->link('shipto_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('shipto_cntct_id', func_get_arg(0)) : $this->link('shipto_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_cust_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cust() {
+        return func_num_args() ? $this->link('shipto_cust_id', func_get_arg(0)) : $this->link('shipto_cust_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_salesrep_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function salesrep() {
+        return func_num_args() ? $this->link('shipto_salesrep_id', func_get_arg(0)) : $this->link('shipto_salesrep_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_shipform_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipform() {
+        return func_num_args() ? $this->link('shipto_shipform_id', func_get_arg(0)) : $this->link('shipto_shipform_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_shipzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipzone() {
+        return func_num_args() ? $this->link('shipto_shipzone_id', func_get_arg(0)) : $this->link('shipto_shipzone_id');
+    }
+
+   /**
+    * Getter / Setter for $shipto_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('shipto_taxzone_id', func_get_arg(0)) : $this->link('shipto_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function address() {
+        $ret = $this->addr()->addressArray();
+        array_unshift($ret, $this->shipto_name);
+        return $ret;
+    }
+    
+    
+    function applyFilters($q, $au)
+    {
+        
+        
+        if (isset($q['query']['for_cohead_id'])) {
+            $cid = (int)$q['query']['for_cohead_id'];
+            $this->whereAdd("
+                shipto_id IN (SELECT coitem_shipto_id FROM coitem where coitem_cohead_id = $cid )
+                            ");
+        
+        }
+        
+        
+        //DB_DataObject::debugLevel(1);
+        $this->selectAdd(" 
+             CASE WHEN LENGTH( join_shipto_addr_id_addr_id.addr_line1) < 1 THEN 'UNKNOWN'
+                ELSE  join_shipto_addr_id_addr_id.addr_line1
+            END as shipto_addr_id_addr_name
+            
+        ");
+    }
+    
+   
+    function createFromCustomerContact($cust, $cnt, $num = false )
+    {
+        //DB_DataObject::debugLevel(1);
+        if (!$cust) {
+            
+            $cust = $cnt->crmacct()->cust();
+            if (!$cust->pid()) {
+                return false;
+            }
+            
+        }
+        
+        
+        if ($num !== false) { 
+            $sh = DB_DataObject::Factory('shiptoinfo');
+            if ($sh->get('shipto_num', $num)) {
+                return $sh;
+            }
+        
+        }
+        
+        
+        
+        if ( $num === false && !empty($cnt->cntct_number)) {
+            $sh = DB_DataObject::Factory('shiptoinfo');
+            if ($sh->get('shipto_num', $cnt->cntct_number)) {
+                return $sh;
+            }
+            
+        }
+         // verify we do not have one..
+        $sh = DB_DataObject::Factory('shiptoinfo');
+        $sh->cust($cust);
+        
+        $cust= $sh->cust();
+        $sh->cntct($cnt);
+        $cnt = $sh->cntct();
+        
+        if ($sh->count() == 1)  {
+            $sh->find(true);
+            return $sh;
+        }
+        $this->cust($cust);
+        $this->cntct($cnt);
+        $this->salesrep($cust->salesrep());
+        $this->taxzone($cust->taxzone());
+        $this->shipform($cust->shipform());
+
+        $addr = $cnt->addr();
+
+        //$this->shipzone($cust->salesrep());
+        
+        $sz = $this->shipzone();
+        if (!$sz->get('shipzone_name', 'DEFAULT')) {
+            $sz->shipzone_descrip = 'Default';
+            $sz->insert();
+            
+        }
+        if (empty($this->shipto_cntct_id)) {
+            print_r($cnt);
+            throw("invalid shipto contact id ?");
+        }
+
+        $name = empty($addr->line1 ) ? $cnt->cntct_name : $addr->line1 ;
+
+        $this->setFrom(array(
+           // 'shipto_cntct_id' => $cnt->cntct_id, -- not needed??? as we set it earlier..
+            'shipto_shipchrg_id' => $cust->cust_shipchrg_id,
+            'shipto_shipzone_id' => $sz->shipzone_id,
+            'shipto_active' => true,
+            'shipto_name' => $cnt->cntct_name, //unique with customer..
+            'shipto_shipvia' => $cust->cust_shipvia,
+            'shipto_commission' => 0,
+            'shipto_default' => false, /// should we have defaults here..
+            'shipto_num'  => $num !== false ? $num : $cnt->cntct_number,
+            'shipto_ediprofile_id' =>  $cust->cust_ediprofile_id,
+            'shipto_addr_id' => $addr->pid()
+            
+        ));
+        //print_R($this);exit;
+        $this->insert();
+      
+        
+        return $this;
+        
+        
+    }
+    
+    function genNum()
+    {
+        
+         
+        $l = $this->cntct()->cntct_number. '-' . $this->addr()->addr_number;
+        if (empty($l)) {
+            $l = 'Shipto';
+        }
+        
+        $x = DB_DataObject::Factory('shiptoinfo');
+        $suf = 0;
+        while ($x->get('shipto_num', $l . (!$suf ? '' : '-' . $suf))) {
+            $x = DB_DataObject::Factory('shiptoinfo');
+            $suf++;
+            //if ($suf > 10) {die("TO MANYU");}
+        }
+        // got a suf..
+        $this->shipto_num = $l . (!$suf ? '' : '-' . $suf);
+        
+        
+        
+        
+    }
+    
+    function defaultShipZone()
+    {
+        $sz = $this->shipzone();
+        if (!$sz->get('shipzone_name', 'DEFAULT')) {
+            $sz->shipzone_descrip = 'Default';
+            $sz->insert();
+            
+        }
+        return $sz->pid();
+        
+        
+    }
+    
+    
+}
diff --git a/DataObjects/Shipvia.php b/DataObjects/Shipvia.php
new file mode 100644 (file)
index 0000000..c31e674
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for shipvia
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipvia extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipvia';             // table name
+    public $shipvia_id;                      // int4(4)  not_null default_nextval%28%28shipvia_shipvia_id_seq%29%3A%3Aregclass%29 primary_key
+    public $shipvia_code;                    // text(-1)  
+    public $shipvia_descrip;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Shipzone.php b/DataObjects/Shipzone.php
new file mode 100644 (file)
index 0000000..8f83d31
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for shipzone
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Shipzone extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'shipzone';            // table name
+    public $shipzone_id;                     // int4(4)  not_null default_nextval%28%28shipzone_shipzone_id_seq%29%3A%3Aregclass%29 primary_key
+    public $shipzone_name;                   // text(-1)  
+    public $shipzone_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Sitetype.php b/DataObjects/Sitetype.php
new file mode 100644 (file)
index 0000000..510ee06
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for sitetype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Sitetype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'sitetype';            // table name
+    public $sitetype_id;                     // int4(4)  not_null default_nextval%28sitetype_sitetype_id_seq%29 primary_key
+    public $sitetype_name;                   // text(-1)  not_null unique_key
+    public $sitetype_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Sltrans.php b/DataObjects/Sltrans.php
new file mode 100644 (file)
index 0000000..21e522b
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Table Definition for sltrans
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Sltrans extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'sltrans';             // table name
+    public $sltrans_id;                      // int4(4)  not_null default_nextval%28sltrans_sltrans_id_seq%29 primary_key
+    public $sltrans_created;                 // timestamptz(8)  
+    public $sltrans_date;                    // date(4)  not_null
+    public $sltrans_sequence;                // int4(4)  
+    public $sltrans_accnt_id;                // int4(4)  not_null
+    public $sltrans_source;                  // text(-1)  
+    public $sltrans_docnumber;               // text(-1)  
+    public $sltrans_misc_id;                 // int4(4)  
+    public $sltrans_amount;                  // numeric(-1)  not_null
+    public $sltrans_notes;                   // text(-1)  
+    public $sltrans_journalnumber;           // int4(4)  
+    public $sltrans_posted;                  // bool(1)  not_null
+    public $sltrans_doctype;                 // text(-1)  
+    public $sltrans_username;                // text(-1)  not_null default_%22current_user%22%28%29
+    public $sltrans_gltrans_journalnumber;    // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Sopack.php b/DataObjects/Sopack.php
new file mode 100644 (file)
index 0000000..90c5cd8
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for sopack
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Sopack extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'sopack';              // table name
+    public $sopack_id;                       // int4(4)  
+    public $sopack_sohead_id;                // int4(4)  
+    public $sopack_printed;                  // bool(1)  
+    public $sopack_cosmisc_id;               // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Source.php b/DataObjects/Source.php
new file mode 100644 (file)
index 0000000..09941ea
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for source
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Source extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'source';              // table name
+    public $source_id;                       // int4(4)  not_null default_nextval%28source_source_id_seq%29 primary_key
+    public $source_module;                   // text(-1)  
+    public $source_name;                     // text(-1)  unique_key
+    public $source_descrip;                  // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/State.php b/DataObjects/State.php
new file mode 100644 (file)
index 0000000..a972114
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for state
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_State extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'state';               // table name
+    public $state_id;                        // int4(4)  not_null default_nextval%28state_state_id_seq%29 primary_key
+    public $state_name;                      // text(-1)  unique_key multiple_key
+    public $state_abbr;                      // text(-1)  
+    public $state_country_id;                // int4(4)  unique_key multiple_key
+
+    
+   /**
+    * Getter / Setter for $state_country_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function country() {
+        return func_num_args() ? $this->link('state_country_id', func_get_arg(0)) : $this->link('state_country_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function applyFilters($q, $au)
+    {
+       // DB_DataObject::debugLevel(1);
+        if (!empty($q['query']['state_name'])) {
+            $v = $this->escape($q['query']['state_name']);
+            $this->whereAdd("state_name ILIKE '$v%'");
+        }
+        
+        
+    }
+}
diff --git a/DataObjects/Status.php b/DataObjects/Status.php
new file mode 100644 (file)
index 0000000..dd5c917
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for status
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Status extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'status';              // table name
+    public $status_id;                       // int4(4)  not_null default_nextval%28status_status_id_seq%29
+    public $status_type;                     // text(-1)  not_null unique_key multiple_key
+    public $status_code;                     // bpchar(-1)  not_null unique_key multiple_key
+    public $status_name;                     // text(-1)  
+    public $status_seq;                      // int4(4)  
+    public $status_color;                    // text(-1)  default_white
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Stdjrnl.php b/DataObjects/Stdjrnl.php
new file mode 100644 (file)
index 0000000..251ced0
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for stdjrnl
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Stdjrnl extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'stdjrnl';             // table name
+    public $stdjrnl_id;                      // int4(4)  not_null default_nextval%28stdjrnl_stdjrnl_id_seq%29 primary_key
+    public $stdjrnl_name;                    // text(-1)  not_null
+    public $stdjrnl_descrip;                 // text(-1)  
+    public $stdjrnl_notes;                   // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Stdjrnlgrp.php b/DataObjects/Stdjrnlgrp.php
new file mode 100644 (file)
index 0000000..70a36db
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for stdjrnlgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Stdjrnlgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'stdjrnlgrp';          // table name
+    public $stdjrnlgrp_id;                   // int4(4)  not_null default_nextval%28stdjrnlgrp_stdjrnlgrp_id_seq%29 primary_key
+    public $stdjrnlgrp_name;                 // text(-1)  
+    public $stdjrnlgrp_descrip;              // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Stdjrnlgrpitem.php b/DataObjects/Stdjrnlgrpitem.php
new file mode 100644 (file)
index 0000000..fe84366
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Table Definition for stdjrnlgrpitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Stdjrnlgrpitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'stdjrnlgrpitem';      // table name
+    public $stdjrnlgrpitem_id;               // int4(4)  not_null default_nextval%28stdjrnlgrpitem_stdjrnlgrpitem_id_seq%29 primary_key
+    public $stdjrnlgrpitem_stdjrnl_id;       // int4(4)  
+    public $stdjrnlgrpitem_toapply;          // int4(4)  
+    public $stdjrnlgrpitem_applied;          // int4(4)  
+    public $stdjrnlgrpitem_effective;        // date(4)  
+    public $stdjrnlgrpitem_expires;          // date(4)  
+    public $stdjrnlgrpitem_stdjrnlgrp_id;    // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Stdjrnlitem.php b/DataObjects/Stdjrnlitem.php
new file mode 100644 (file)
index 0000000..8666abe
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Table Definition for stdjrnlitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Stdjrnlitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'stdjrnlitem';         // table name
+    public $stdjrnlitem_id;                  // int4(4)  not_null default_nextval%28stdjrnlitem_stdjrnlitem_id_seq%29 primary_key
+    public $stdjrnlitem_stdjrnl_id;          // int4(4)  not_null
+    public $stdjrnlitem_accnt_id;            // int4(4)  not_null
+    public $stdjrnlitem_amount;              // numeric(-1)  not_null
+    public $stdjrnlitem_notes;               // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Subaccnt.php b/DataObjects/Subaccnt.php
new file mode 100644 (file)
index 0000000..7278109
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for subaccnt
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Subaccnt extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'subaccnt';            // table name
+    public $subaccnt_id;                     // int4(4)  not_null default_nextval%28subaccnt_subaccnt_id_seq%29 primary_key
+    public $subaccnt_number;                 // text(-1)  unique_key
+    public $subaccnt_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Subaccnttype.php b/DataObjects/Subaccnttype.php
new file mode 100644 (file)
index 0000000..363420d
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for subaccnttype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Subaccnttype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'subaccnttype';        // table name
+    public $subaccnttype_id;                 // int4(4)  not_null default_nextval%28subaccnttype_subaccnttype_id_seq%29 primary_key
+    public $subaccnttype_accnt_type;         // bpchar(-1)  not_null
+    public $subaccnttype_code;               // text(-1)  not_null unique_key
+    public $subaccnttype_descrip;            // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Tax.php b/DataObjects/Tax.php
new file mode 100644 (file)
index 0000000..80bfeff
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Table Definition for tax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Tax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'tax';                 // table name
+    public $tax_id;                          // int4(4)  not_null default_nextval%28%28%22tax_tax_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $tax_code;                        // text(-1)  
+    public $tax_descrip;                     // text(-1)  
+    public $tax_sales_accnt_id;              // int4(4)  
+    public $tax_taxclass_id;                 // int4(4)  
+    public $tax_taxauth_id;                  // int4(4)  
+    public $tax_basis_tax_id;                // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $tax_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('tax_basis_tax_id', func_get_arg(0)) : $this->link('tax_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $tax_sales_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function sales_accnt() {
+        return func_num_args() ? $this->link('tax_sales_accnt_id', func_get_arg(0)) : $this->link('tax_sales_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $tax_taxauth_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxauth() {
+        return func_num_args() ? $this->link('tax_taxauth_id', func_get_arg(0)) : $this->link('tax_taxauth_id');
+    }
+
+   /**
+    * Getter / Setter for $tax_taxclass_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxclass() {
+        return func_num_args() ? $this->link('tax_taxclass_id', func_get_arg(0)) : $this->link('tax_taxclass_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxass.php b/DataObjects/Taxass.php
new file mode 100644 (file)
index 0000000..df3d200
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Table Definition for taxass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxass';              // table name
+    public $taxass_id;                       // int4(4)  not_null default_nextval%28taxass_taxass_id_seq%29 primary_key
+    public $taxass_taxzone_id;               // int4(4)  unique_key multiple_key
+    public $taxass_taxtype_id;               // int4(4)  unique_key multiple_key
+    public $taxass_tax_id;                   // int4(4)  not_null unique_key multiple_key
+
+    
+   /**
+    * Getter / Setter for $taxass_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxass_tax_id', func_get_arg(0)) : $this->link('taxass_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxass_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxass_taxtype_id', func_get_arg(0)) : $this->link('taxass_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $taxass_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('taxass_taxzone_id', func_get_arg(0)) : $this->link('taxass_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxauth.php b/DataObjects/Taxauth.php
new file mode 100644 (file)
index 0000000..9f81847
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Table Definition for taxauth
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxauth extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxauth';             // table name
+    public $taxauth_id;                      // int4(4)  not_null default_nextval%28taxauth_taxauth_id_seq%29 primary_key
+    public $taxauth_code;                    // text(-1)  not_null unique_key
+    public $taxauth_name;                    // text(-1)  
+    public $taxauth_extref;                  // text(-1)  
+    public $taxauth_addr_id;                 // int4(4)  
+    public $taxauth_curr_id;                 // int4(4)  
+    public $taxauth_county;                  // text(-1)  
+    public $taxauth_accnt_id;                // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxauth_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function accnt() {
+        return func_num_args() ? $this->link('taxauth_accnt_id', func_get_arg(0)) : $this->link('taxauth_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $taxauth_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('taxauth_addr_id', func_get_arg(0)) : $this->link('taxauth_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $taxauth_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('taxauth_curr_id', func_get_arg(0)) : $this->link('taxauth_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxclass.php b/DataObjects/Taxclass.php
new file mode 100644 (file)
index 0000000..fb4ad4b
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for taxclass
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxclass extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxclass';            // table name
+    public $taxclass_id;                     // int4(4)  not_null default_nextval%28taxclass_taxclass_id_seq%29 primary_key
+    public $taxclass_code;                   // text(-1)  
+    public $taxclass_descrip;                // text(-1)  
+    public $taxclass_sequence;               // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxhist.php b/DataObjects/Taxhist.php
new file mode 100644 (file)
index 0000000..b25cac3
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Table Definition for taxhist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxhist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxhist';             // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('taxhist_curr_id', func_get_arg(0)) : $this->link('taxhist_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxrate.php b/DataObjects/Taxrate.php
new file mode 100644 (file)
index 0000000..22189f5
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for taxrate
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxrate extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxrate';             // table name
+    public $taxrate_id;                      // int4(4)  not_null default_nextval%28taxrate_taxrate_id_seq%29 primary_key
+    public $taxrate_tax_id;                  // int4(4)  not_null
+    public $taxrate_percent;                 // numeric(-1)  not_null
+    public $taxrate_curr_id;                 // int4(4)  
+    public $taxrate_amount;                  // numeric(-1)  not_null
+    public $taxrate_effective;               // date(4)  
+    public $taxrate_expires;                 // date(4)  
+
+    
+   /**
+    * Getter / Setter for $taxrate_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('taxrate_curr_id', func_get_arg(0)) : $this->link('taxrate_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $taxrate_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxrate_tax_id', func_get_arg(0)) : $this->link('taxrate_tax_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxreg.php b/DataObjects/Taxreg.php
new file mode 100644 (file)
index 0000000..a5e82ea
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Table Definition for taxreg
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxreg extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxreg';              // table name
+    public $taxreg_id;                       // int4(4)  not_null default_nextval%28taxreg_taxreg_id_seq%29 primary_key
+    public $taxreg_rel_id;                   // int4(4)  not_null
+    public $taxreg_rel_type;                 // bpchar(-1)  
+    public $taxreg_taxauth_id;               // int4(4)  
+    public $taxreg_number;                   // text(-1)  not_null
+    public $taxreg_taxzone_id;               // int4(4)  
+    public $taxreg_effective;                // date(4)  default_startoftime%28%29
+    public $taxreg_expires;                  // date(4)  default_endoftime%28%29
+    public $taxreg_notes;                    // text(-1)  default_
+
+    
+   /**
+    * Getter / Setter for $taxreg_taxauth_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxauth() {
+        return func_num_args() ? $this->link('taxreg_taxauth_id', func_get_arg(0)) : $this->link('taxreg_taxauth_id');
+    }
+
+   /**
+    * Getter / Setter for $taxreg_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('taxreg_taxzone_id', func_get_arg(0)) : $this->link('taxreg_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Taxtype.php b/DataObjects/Taxtype.php
new file mode 100644 (file)
index 0000000..af89dc4
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Table Definition for taxtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxtype';             // table name
+    public $taxtype_id;                      // int4(4)  not_null default_nextval%28taxtype_taxtype_id_seq%29 primary_key
+    public $taxtype_name;                    // text(-1)  not_null unique_key
+    public $taxtype_descrip;                 // text(-1)  
+    public $taxtype_sys;                     // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    function initDatabase()
+    {
+        
+        $ret = array(
+            array(
+                'taxtype_name' => 'Taxfree',
+                'taxtype_descrip' => "Not taxable zone"
+            ),
+            array(
+                'taxtype_name' => 'Taxable',
+                'taxtype_descrip' => "Taxable"
+            ),
+            
+            
+        );
+        
+        foreach($ret as $ar) {
+            $tt = DB_DataObject::factory($this->tableName());
+            if ($tt->get('taxtype_name', $ar['taxtype_name'])) {
+                continue;
+            }
+            $tt = DB_DataObject::factory($this->tableName());
+            $tt->setFrom($ar);
+            $tt->insert();
+            
+        }
+        
+    }
+    
+}
diff --git a/DataObjects/Taxzone.php b/DataObjects/Taxzone.php
new file mode 100644 (file)
index 0000000..310cfee
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Table Definition for taxzone
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Taxzone extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'taxzone';             // table name
+    public $taxzone_id;                      // int4(4)  not_null default_nextval%28taxzone_taxzone_id_seq%29 primary_key
+    public $taxzone_code;                    // text(-1)  
+    public $taxzone_descrip;                 // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function applyFilters($q, $au, $roo)
+    {
+        // we need to provide tax information for our UI..
+        
+        if (isset($q['with_date'])) {
+          //  DB_DataObject::DebugLevel(1);
+            $d = date('Y-m-d', strtotime($q['with_date']));
+            $this->selectAdd("
+                            
+               COALESCE( (SELECT taxrate_percent FROM taxrate WHERE taxrate_tax_id IN 
+                   (SELECT taxass_tax_id FROM taxass WHERE
+                       taxass_taxzone_id = taxzone_id
+                       AND taxrate_effective < '$d' AND taxrate_expires > '$d'
+                   )
+               ), 0) as taxzone_rate
+                         
+            ");
+        }
+        
+        
+    }
+    
+    function initDatabase()
+    {
+        $tx = DB_DataObject::Factory($this->tableName());
+        if ($tx->get('taxzone_code', 'NO TAX')) {
+            return;
+        }
+        $tx = DB_DataObject::Factory($this->tableName());
+        $tx->setFrom(array(
+            'taxzone_code' => 'NO TAX',
+            'taxzone_descrip' => "Not taxable"            
+        ));
+        $tx->insert();
+            
+    }
+    
+}
diff --git a/DataObjects/Terms.php b/DataObjects/Terms.php
new file mode 100644 (file)
index 0000000..92175e5
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Table Definition for terms
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Terms extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'terms';               // table name
+    public $terms_id;                        // int4(4)  not_null default_nextval%28%28terms_terms_id_seq%29%3A%3Aregclass%29 primary_key
+    public $terms_code;                      // text(-1)  unique_key
+    public $terms_descrip;                   // text(-1)  
+    public $terms_type;                      // bpchar(-1)  
+    public $terms_duedays;                   // int4(4)  
+    public $terms_discdays;                  // int4(4)  
+    public $terms_discprcnt;                 // numeric(-1)  
+    public $terms_cutoffday;                 // int4(4)  
+    public $terms_ap;                        // bool(1)  
+    public $terms_ar;                        // bool(1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function importFromArray($roo, $terms)
+    {   
+        foreach ($terms as $term){
+            $t = DB_DataObject::factory('terms');
+            if($t->get('terms_code',$term['terms_code'])){
+                continue;
+            }
+            $t->setFrom($term);
+            $t->insert();
+        }
+        
+    }
+}
diff --git a/DataObjects/Todoitem.php b/DataObjects/Todoitem.php
new file mode 100644 (file)
index 0000000..1011703
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Table Definition for todoitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Todoitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'todoitem';            // table name
+    public $todoitem_id;                     // int4(4)  not_null default_nextval%28todoitem_todoitem_id_seq%29 primary_key
+    public $todoitem_name;                   // text(-1)  not_null
+    public $todoitem_description;            // text(-1)  
+    public $todoitem_incdt_id;               // int4(4)  
+    public $todoitem_creator_username;       // text(-1)  not_null default_%22current_user%22%28%29
+    public $todoitem_status;                 // bpchar(-1)  
+    public $todoitem_active;                 // bool(1)  not_null default_true
+    public $todoitem_start_date;             // date(4)  
+    public $todoitem_due_date;               // date(4)  
+    public $todoitem_assigned_date;          // date(4)  
+    public $todoitem_completed_date;         // date(4)  
+    public $todoitem_seq;                    // int4(4)  not_null default_0
+    public $todoitem_notes;                  // text(-1)  
+    public $todoitem_crmacct_id;             // int4(4)  
+    public $todoitem_ophead_id;              // int4(4)  
+    public $todoitem_owner_username;         // text(-1)  
+    public $todoitem_priority_id;            // int4(4)  
+    public $todoitem_username;               // text(-1)  
+    public $todoitem_recurring_todoitem_id;    // int4(4)  
+    public $todoitem_cntct_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $todoitem_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('todoitem_cntct_id', func_get_arg(0)) : $this->link('todoitem_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $todoitem_crmacct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function crmacct() {
+        return func_num_args() ? $this->link('todoitem_crmacct_id', func_get_arg(0)) : $this->link('todoitem_crmacct_id');
+    }
+
+   /**
+    * Getter / Setter for $todoitem_incdt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function incdt() {
+        return func_num_args() ? $this->link('todoitem_incdt_id', func_get_arg(0)) : $this->link('todoitem_incdt_id');
+    }
+
+   /**
+    * Getter / Setter for $todoitem_ophead_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function ophead() {
+        return func_num_args() ? $this->link('todoitem_ophead_id', func_get_arg(0)) : $this->link('todoitem_ophead_id');
+    }
+
+   /**
+    * Getter / Setter for $todoitem_recurring_todoitem_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function recurring_todoitem() {
+        return func_num_args() ? $this->link('todoitem_recurring_todoitem_id', func_get_arg(0)) : $this->link('todoitem_recurring_todoitem_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Trgthist.php b/DataObjects/Trgthist.php
new file mode 100644 (file)
index 0000000..3481a6f
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Table Definition for trgthist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Trgthist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'trgthist';            // table name
+    public $trgthist_src_cntct_id;           // int4(4)  not_null
+    public $trgthist_trgt_cntct_id;          // int4(4)  not_null
+    public $trgthist_col;                    // text(-1)  not_null
+    public $trgthist_value;                  // text(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $trgthist_src_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function src_cntct() {
+        return func_num_args() ? $this->link('trgthist_src_cntct_id', func_get_arg(0)) : $this->link('trgthist_src_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $trgthist_trgt_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function trgt_cntct() {
+        return func_num_args() ? $this->link('trgthist_trgt_cntct_id', func_get_arg(0)) : $this->link('trgthist_trgt_cntct_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Trialbal.php b/DataObjects/Trialbal.php
new file mode 100644 (file)
index 0000000..61a5ea9
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Table Definition for trialbal
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Trialbal extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'trialbal';            // table name
+    public $trialbal_id;                     // int4(4)  not_null default_nextval%28trialbal_trialbal_id_seq%29 primary_key
+    public $trialbal_period_id;              // int4(4)  unique_key multiple_key
+    public $trialbal_accnt_id;               // int4(4)  unique_key multiple_key
+    public $trialbal_beginning;              // numeric(-1)  
+    public $trialbal_ending;                 // numeric(-1)  
+    public $trialbal_credits;                // numeric(-1)  
+    public $trialbal_debits;                 // numeric(-1)  
+    public $trialbal_dirty;                  // bool(1)  
+    public $trialbal_yearend;                // numeric(-1)  not_null default_0.00
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Trialbalsync.php b/DataObjects/Trialbalsync.php
new file mode 100644 (file)
index 0000000..776f1e6
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Table Definition for trialbalsync
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Trialbalsync extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'trialbalsync';        // table name
+    public $trialbal_id;                     // int4(4)  not_null default_nextval%28trialbal_trialbal_id_seq%29 primary_key
+    public $trialbal_period_id;              // int4(4)  unique_key multiple_key
+    public $trialbal_accnt_id;               // int4(4)  unique_key multiple_key
+    public $trialbal_beginning;              // numeric(-1)  
+    public $trialbal_ending;                 // numeric(-1)  
+    public $trialbal_credits;                // numeric(-1)  
+    public $trialbal_debits;                 // numeric(-1)  
+    public $trialbal_dirty;                  // bool(1)  
+    public $trialbal_yearend;                // numeric(-1)  not_null default_0.00
+    public $trialbalsync_curr_beginning;     // numeric(-1)  not_null default_0
+    public $trialbalsync_curr_ending;        // numeric(-1)  not_null default_0
+    public $trialbalsync_curr_credits;       // numeric(-1)  not_null default_0
+    public $trialbalsync_curr_debits;        // numeric(-1)  not_null default_0
+    public $trialbalsync_curr_yearend;       // numeric(-1)  not_null default_0
+    public $trialbalsync_curr_posted;        // bool(1)  not_null default_false
+    public $trialbalsync_curr_id;            // int4(4)  not_null
+    public $trialbalsync_curr_rate;          // numeric(-1)  
+
+    
+   /**
+    * Getter / Setter for $trialbalsync_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('trialbalsync_curr_id', func_get_arg(0)) : $this->link('trialbalsync_curr_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Uiform.php b/DataObjects/Uiform.php
new file mode 100644 (file)
index 0000000..724a9cf
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for uiform
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Uiform extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'uiform';              // table name
+    public $uiform_id;                       // int4(4)  not_null default_nextval%28uiform_uiform_id_seq%29 primary_key
+    public $uiform_name;                     // text(-1)  not_null
+    public $uiform_order;                    // int4(4)  not_null
+    public $uiform_enabled;                  // bool(1)  not_null default_false
+    public $uiform_source;                   // text(-1)  not_null
+    public $uiform_notes;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Uom.php b/DataObjects/Uom.php
new file mode 100644 (file)
index 0000000..a810a53
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for uom
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Uom extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'uom';                 // table name
+    public $uom_id;                          // int4(4)  not_null default_nextval%28uom_uom_id_seq%29 primary_key
+    public $uom_name;                        // text(-1)  unique_key
+    public $uom_descrip;                     // text(-1)  
+    public $uom_item_weight;                 // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Uomconv.php b/DataObjects/Uomconv.php
new file mode 100644 (file)
index 0000000..6ce072b
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Table Definition for uomconv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Uomconv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'uomconv';             // table name
+    public $uomconv_id;                      // int4(4)  not_null default_nextval%28uomconv_uomconv_id_seq%29 primary_key
+    public $uomconv_from_uom_id;             // int4(4)  not_null
+    public $uomconv_from_value;              // numeric(-1)  not_null
+    public $uomconv_to_uom_id;               // int4(4)  not_null
+    public $uomconv_to_value;                // numeric(-1)  not_null
+    public $uomconv_fractional;              // bool(1)  not_null default_false
+
+    
+   /**
+    * Getter / Setter for $uomconv_from_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function from_uom() {
+        return func_num_args() ? $this->link('uomconv_from_uom_id', func_get_arg(0)) : $this->link('uomconv_from_uom_id');
+    }
+
+   /**
+    * Getter / Setter for $uomconv_to_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function to_uom() {
+        return func_num_args() ? $this->link('uomconv_to_uom_id', func_get_arg(0)) : $this->link('uomconv_to_uom_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Uomtype.php b/DataObjects/Uomtype.php
new file mode 100644 (file)
index 0000000..ad039d0
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for uomtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Uomtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'uomtype';             // table name
+    public $uomtype_id;                      // int4(4)  not_null default_nextval%28uomtype_uomtype_id_seq%29 primary_key
+    public $uomtype_name;                    // text(-1)  not_null unique_key
+    public $uomtype_descrip;                 // text(-1)  
+    public $uomtype_multiple;                // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Url.php b/DataObjects/Url.php
new file mode 100644 (file)
index 0000000..2c35c97
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for url
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Url extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'url';                 // table name
+    public $url_id;                          // int4(4)  not_null default_nextval%28url_url_id_seq%29 primary_key
+    public $url_source_id;                   // int4(4)  not_null
+    public $url_source;                      // text(-1)  not_null
+    public $url_title;                       // text(-1)  not_null
+    public $url_url;                         // text(-1)  not_null
+    public $url_stream;                      // bytea(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Usr.php b/DataObjects/Usr.php
new file mode 100644 (file)
index 0000000..bde28a0
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Table Definition for usr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Usr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'usr';                 // table name
+    public $usr_id;                          // int4(4)  
+    public $usr_username;                    // text(-1)  
+    public $usr_propername;                  // text(-1)  
+    public $usr_passwd;                      // text(-1)  
+    public $usr_locale_id;                   // int4(4)  
+    public $usr_initials;                    // text(-1)  
+    public $usr_agent;                       // bool(1)  
+    public $usr_active;                      // bool(1)  
+    public $usr_email;                       // text(-1)  
+    public $usr_window;                      // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Usr_bak.php b/DataObjects/Usr_bak.php
new file mode 100644 (file)
index 0000000..3b00362
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Table Definition for usr_bak
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Usr_bak extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'usr_bak';             // table name
+    public $usr_id;                          // int4(4)  not_null default_nextval%28%28usr_usr_id_seq%29%3A%3Aregclass%29 primary_key
+    public $usr_username;                    // text(-1)  not_null unique_key
+    public $usr_propername;                  // text(-1)  
+    public $usr_passwd;                      // text(-1)  
+    public $usr_locale_id;                   // int4(4)  not_null
+    public $usr_initials;                    // text(-1)  
+    public $usr_agent;                       // bool(1)  not_null
+    public $usr_active;                      // bool(1)  not_null
+    public $usr_email;                       // text(-1)  
+    public $usr_window;                      // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Usrgrp.php b/DataObjects/Usrgrp.php
new file mode 100644 (file)
index 0000000..c8ad1f2
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Table Definition for usrgrp
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Usrgrp extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'usrgrp';              // table name
+    public $usrgrp_id;                       // int4(4)  not_null default_nextval%28usrgrp_usrgrp_id_seq%29 primary_key
+    public $usrgrp_grp_id;                   // int4(4)  not_null
+    public $usrgrp_username;                 // text(-1)  not_null
+
+    
+   /**
+    * Getter / Setter for $usrgrp_grp_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function grp() {
+        return func_num_args() ? $this->link('usrgrp_grp_id', func_get_arg(0)) : $this->link('usrgrp_grp_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function syncGroups($person)
+    {
+        $name = $person->pgname();
+        
+        $gm = DB_DataObject::Factory('group_members');
+        $new = $gm->listGroupMembership($person, 'name');
+        
+        
+        $g = DB_DataObject::Factory('grp');
+        $grps  = $g->fetchAll('grp_id', 'grp_name');
+        $gmap = array_flip($grps);
+        
+        
+        $cur = DB_DataObject::Factory('usrgrp');
+        $cur->usrgrp_username = $name;
+        $oldids = $cur->fetchAll('usrgrp_grp_id');
+        $old = array();
+        foreach($oldids as $id) {
+            $old[$grps[$id]] = true;
+        }
+        
+        foreach($new as $i=> $n) {
+            if ($n == 'Administrators') {
+                $n = 'ADMIN';
+            }
+            
+            if (isset($old[$n])) {
+                unset($old[$n]);
+                continue;
+            }
+            // skip groups we do not know about..
+            if (!isset($gmap[$n])) {
+                unset($new[$i]);
+                continue;
+            }
+            $ug = DB_DataObject::Factory('usrgrp');
+            $ug->usrgrp_grp_id = $gmap[$n];
+            $ug->usrgrp_username = $name;
+            $ug->insert();
+            unset($new[$i]);
+                
+        }
+        // finally remove from group..
+        
+        foreach($old as $n => $tr) {
+            $ug = DB_DataObject::Factory('usrgrp');
+            $ug->usrgrp_grp_id = $gmap[$n];
+            $ug->usrgrp_username = $name;
+            if ($ug->find(true)) {
+                $ug->delete();
+            }
+            
+        }
+    }
+         
+}
diff --git a/DataObjects/Usrpref.php b/DataObjects/Usrpref.php
new file mode 100644 (file)
index 0000000..7bbf6bc
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for usrpref
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Usrpref extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'usrpref';             // table name
+    public $usrpref_id;                      // int4(4)  not_null default_nextval%28%28usrpref_usrpref_id_seq%29%3A%3Aregclass%29 primary_key
+    public $usrpref_name;                    // text(-1)  
+    public $usrpref_value;                   // text(-1)  
+    public $usrpref_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Usrpriv.php b/DataObjects/Usrpriv.php
new file mode 100644 (file)
index 0000000..9581baf
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for usrpriv
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Usrpriv extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'usrpriv';             // table name
+    public $usrpriv_id;                      // int4(4)  not_null default_nextval%28%28usrpriv_usrpriv_id_seq%29%3A%3Aregclass%29 primary_key
+    public $usrpriv_priv_id;                 // int4(4)  
+    public $usrpriv_username;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Vend.php b/DataObjects/Vend.php
new file mode 100644 (file)
index 0000000..84de30f
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Table Definition for vend
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vend extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vend';                // table name
+    public $vend_id;                         // int4(4)  
+    public $vend_name;                       // text(-1)  
+    public $vend_address1;                   // text(-1)  
+    public $vend_address2;                   // text(-1)  
+    public $vend_address3;                   // text(-1)  
+    public $vend_city;                       // text(-1)  
+    public $vend_state;                      // text(-1)  
+    public $vend_zip;                        // text(-1)  
+    public $vend_contact1;                   // text(-1)  
+    public $vend_phone1;                     // text(-1)  
+    public $vend_contact2;                   // text(-1)  
+    public $vend_phone2;                     // text(-1)  
+    public $vend_lastpurchdate;              // date(4)  
+    public $vend_active;                     // bool(1)  
+    public $vend_po;                         // bool(1)  
+    public $vend_comments;                   // text(-1)  
+    public $vend_pocomments;                 // text(-1)  
+    public $vend_number;                     // text(-1)  
+    public $vend_fax1;                       // text(-1)  
+    public $vend_fax2;                       // text(-1)  
+    public $vend_email1;                     // text(-1)  
+    public $vend_email2;                     // text(-1)  
+    public $vend_1099;                       // bool(1)  
+    public $vend_exported;                   // bool(1)  
+    public $vend_fobsource;                  // bpchar(-1)  
+    public $vend_fob;                        // text(-1)  
+    public $vend_terms_id;                   // int4(4)  
+    public $vend_shipvia;                    // text(-1)  
+    public $vend_vendtype_id;                // int4(4)  
+    public $vend_qualified;                  // bool(1)  
+    public $vend_ediemail;                   // text(-1)  
+    public $vend_ediemailbody;               // text(-1)  
+    public $vend_edisubject;                 // text(-1)  
+    public $vend_edifilename;                // text(-1)  
+    public $vend_accntnum;                   // text(-1)  
+    public $vend_emailpodelivery;            // bool(1)  
+    public $vend_restrictpurch;              // bool(1)  
+    public $vend_edicc;                      // text(-1)  
+    public $vend_country;                    // text(-1)  
+    public $vend_curr_id;                    // int4(4)  
+    public $vend_taxzone_id;                 // int4(4)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Vendaddr.php b/DataObjects/Vendaddr.php
new file mode 100644 (file)
index 0000000..00928bb
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for vendaddr
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vendaddr extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vendaddr';            // table name
+    public $vendaddr_id;                     // int4(4)  
+    public $vendaddr_vend_id;                // int4(4)  
+    public $vendaddr_code;                   // text(-1)  
+    public $vendaddr_name;                   // text(-1)  
+    public $vendaddr_address1;               // text(-1)  
+    public $vendaddr_address2;               // text(-1)  
+    public $vendaddr_address3;               // text(-1)  
+    public $vendaddr_contact1;               // text(-1)  
+    public $vendaddr_phone1;                 // text(-1)  
+    public $vendaddr_fax1;                   // text(-1)  
+    public $vendaddr_city;                   // text(-1)  
+    public $vendaddr_state;                  // text(-1)  
+    public $vendaddr_zipcode;                // text(-1)  
+    public $vendaddr_country;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Vendaddrinfo.php b/DataObjects/Vendaddrinfo.php
new file mode 100644 (file)
index 0000000..1f23e77
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Table Definition for vendaddrinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vendaddrinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vendaddrinfo';        // table name
+    public $vendaddr_id;                     // int4(4)  not_null default_nextval%28%28vendaddr_vendaddr_id_seq%29%3A%3Aregclass%29 primary_key
+    public $vendaddr_vend_id;                // int4(4)  
+    public $vendaddr_code;                   // text(-1)  
+    public $vendaddr_name;                   // text(-1)  
+    public $vendaddr_comments;               // text(-1)  
+    public $vendaddr_cntct_id;               // int4(4)  
+    public $vendaddr_addr_id;                // int4(4)  
+    public $vendaddr_taxzone_id;             // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $vendaddr_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('vendaddr_addr_id', func_get_arg(0)) : $this->link('vendaddr_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $vendaddr_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('vendaddr_cntct_id', func_get_arg(0)) : $this->link('vendaddr_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $vendaddr_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('vendaddr_taxzone_id', func_get_arg(0)) : $this->link('vendaddr_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Vendinfo.php b/DataObjects/Vendinfo.php
new file mode 100644 (file)
index 0000000..f5b298a
--- /dev/null
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Table Definition for vendinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vendinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vendinfo';            // table name
+    public $vend_id;                         // int4(4)  not_null default_nextval%28%28vend_vend_id_seq%29%3A%3Aregclass%29 primary_key
+    public $vend_name;                       // text(-1)  
+    public $vend_lastpurchdate;              // date(4)  
+    public $vend_active;                     // bool(1)  
+    public $vend_po;                         // bool(1)  
+    public $vend_comments;                   // text(-1)  
+    public $vend_pocomments;                 // text(-1)  
+    public $vend_number;                     // text(-1)  unique_key unique_key
+    public $vend_1099;                       // bool(1)  
+    public $vend_exported;                   // bool(1)  
+    public $vend_fobsource;                  // bpchar(-1)  
+    public $vend_fob;                        // text(-1)  
+    public $vend_terms_id;                   // int4(4)  
+    public $vend_shipvia;                    // text(-1)  
+    public $vend_vendtype_id;                // int4(4)  
+    public $vend_qualified;                  // bool(1)  
+    public $vend_ediemail;                   // text(-1)  
+    public $vend_ediemailbody;               // text(-1)  
+    public $vend_edisubject;                 // text(-1)  
+    public $vend_edifilename;                // text(-1)  
+    public $vend_accntnum;                   // text(-1)  
+    public $vend_emailpodelivery;            // bool(1)  
+    public $vend_restrictpurch;              // bool(1)  
+    public $vend_edicc;                      // text(-1)  
+    public $vend_curr_id;                    // int4(4)  default_basecurrid%28%29
+    public $vend_cntct1_id;                  // int4(4)  
+    public $vend_cntct2_id;                  // int4(4)  
+    public $vend_addr_id;                    // int4(4)  
+    public $vend_match;                      // bool(1)  not_null default_false
+    public $vend_ach_enabled;                // bool(1)  not_null default_false
+    public $vend_ach_accnttype;              // text(-1)  
+    public $vend_ach_use_vendinfo;           // bool(1)  not_null default_true
+    public $vend_ach_indiv_number;           // text(-1)  not_null default_
+    public $vend_ach_indiv_name;             // text(-1)  not_null default_
+    public $vend_ediemailhtml;               // bool(1)  not_null default_false
+    public $vend_ach_routingnumber;          // bytea(-1)  not_null default_%5C%5Cx00
+    public $vend_ach_accntnumber;            // bytea(-1)  not_null default_%5C%5Cx00
+    public $vend_taxzone_id;                 // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $vend_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('vend_curr_id', func_get_arg(0)) : $this->link('vend_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $vend_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('vend_addr_id', func_get_arg(0)) : $this->link('vend_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $vend_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('vend_taxzone_id', func_get_arg(0)) : $this->link('vend_taxzone_id');
+    }
+
+   /**
+    * Getter / Setter for $vend_vendtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function vendtype() {
+        return func_num_args() ? $this->link('vend_vendtype_id', func_get_arg(0)) : $this->link('vend_vendtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function  findInternal($int_name, $cur)
+    {
+        //DB_DataObject::DebugLevel(1);
+        $ve = $this->factory($this->tableName());
+        $ve->vend_curr_id = $cur->pid();
+        // CRMACCT
+        $ve->whereAdd(" charass_getvalue('CRMACCT',
+                        (SELECT crmacct_id FROM crmacct where crmacct_vend_id = vend_id LIMIT 1),
+                        'INTERNALCOMPANY') = '{$this->escape($int_name)}'");
+        // fixme INTERNALCOMPANY must  be added to contacts
+        $matches = $ve->count();
+        if (!$matches || $matches > 1) {
+            return false;
+        }
+        $ve->find(true);
+        
+        return $ve;
+        
+    }
+    
+    
+    function applyFilters($q,$au, $roo)
+    {
+         if (!empty($q['search']['name'])) {
+            $v = $this->escape($q['search']['name']);
+            $this->whereAdd("vend_name ILIKE '%$v%' or vend_number ILIKE '%$v%' ");
+        }
+         if (!empty($q['query']['vend_name'])) {
+            $v = $this->escape($q['query']['vend_name']);
+            $this->whereAdd("vend_name ILIKE '%$v%' or vend_number ILIKE '%$v%' ");
+        }
+        
+        if (!empty($q['_with_char'])) {
+            $ch = DB_DAtaObject::Factory('char');
+            $ch->char_crmaccounts = 1;
+            
+            //if (!$ch->count() < 2) {
+            //    $ch->initDatabase();
+            //}
+            $ch->find();
+            while ($ch->fetch()) {
+                $nm = 'vend_char_' . strtolower(preg_replace('/[^a-z]+/i','_', $ch->char_name));
+             
+            
+                $this->selectAdd("
+                    charass_getvalue('CRMACCT',
+                            (SELECT crmacct_id FROM crmacct where crmacct_vend_id = vend_id LIMIT 1),
+                            '{$this->escape($ch->char_name)}') as $nm
+                ");
+                
+                if (!empty($q['sort']) && $q['sort'] == $nm) {
+                    $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
+                    $this->orderBy("charass_getvalue('CRMACCT',
+                                   (SELECT crmacct_id FROM crmacct where crmacct_vend_id = vend_id LIMIT 1),
+                                   '{$this->escape($ch->char_name)}') $dir");
+                }
+            }
+             
+        }
+    }
+    
+         
+    
+    
+}
diff --git a/DataObjects/Vendtype.php b/DataObjects/Vendtype.php
new file mode 100644 (file)
index 0000000..07dd9c6
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Table Definition for vendtype
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vendtype extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vendtype';            // table name
+    public $vendtype_id;                     // int4(4)  not_null default_nextval%28vendtype_vendtype_id_seq%29 primary_key
+    public $vendtype_code;                   // text(-1)  not_null
+    public $vendtype_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Vodist.php b/DataObjects/Vodist.php
new file mode 100644 (file)
index 0000000..964e4cb
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Table Definition for vodist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vodist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vodist';              // table name
+    public $vodist_id;                       // int4(4)  not_null default_nextval%28%28%22vodist_vodist_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $vodist_poitem_id;                // int4(4)  
+    public $vodist_vohead_id;                // int4(4)  
+    public $vodist_costelem_id;              // int4(4)  
+    public $vodist_accnt_id;                 // int4(4)  
+    public $vodist_amount;                   // numeric(-1)  
+    public $vodist_qty;                      // numeric(-1)  
+    public $vodist_expcat_id;                // int4(4)  default_%28-1%29
+    public $vodist_tax_id;                   // int4(4)  default_%28-1%29
+    public $vodist_discountable;             // bool(1)  not_null default_true
+    public $vodist_notes;                    // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function defaults() {
+        $tt = DB_DAtaObject::Factory('taxtype');
+        $tt->get('taxtype_name','Taxable');
+        return array(
+            'vodist_poitem_id'=> -1,
+            'vodist_costelem_id'=> -1,
+            'vodist_discountable' => true,
+            'vodist_expcat_id' =>  -1,
+            'voitem_taxtype_id' => $tt->pid(),
+            'vodist_tax_id' => -1,
+          
+            
+        );
+         
+        
+    }
+    
+    function createFromExpItem($roo, $vohead, $ei)
+    {
+        $expcat = DB_DataObject::Factory('expcat');
+        if (!$expcat->get($ei->expitem_expcat_id)) {
+            $roo->jerr("expense cat {$ei->expitem_expcat_id} could not be found.");
+        }
+        
+        $this->setFrom($this->defaults());
+       // $roo->jerr(print_r($ei,true));
+        $this->setFrom(array(
+            'vodist_vohead_id'=> $vohead->pid(),
+            'vodist_accnt_id' => $expcat->expcat_exp_accnt_id,
+            'vodist_amount'=> round($ei->expitem_total,2),
+                        //$this->sqlValue("ROUND(currtobase({$ei->expitem_curr_id}, {$ei->expitem_amount_fc} , '{$ei->expitem_date}'),2)"),
+            'vodist_notes' => $ei->expitem_memo
+        ));
+        $this->insert();
+        
+    }
+    function createFromExpTax($roo, $vohead, $total)
+    {
+         
+        $txa = DB_DataObject::factory('taxass');
+        $txa->taxass_taxzone_id = $vohead->vohead_taxzone_id;
+        $txa->limit(1);
+        $txa->find(true);
+        $tax_id = $txa->taxass_tax_id;
+            
+        
+        $this->setFrom($this->defaults());
+        
+        $this->setFrom(array(
+            'vodist_vohead_id'=> $vohead->pid(),
+            'vodist_accnt_id' => -1, // check does this get posted correctly!!!
+            'vodist_amount'=>   $total,
+            'vodist_tax_id' => $tax_id
+        ));
+        $this->insert();
+    }
+}
diff --git a/DataObjects/Vohead.php b/DataObjects/Vohead.php
new file mode 100644 (file)
index 0000000..7bf249d
--- /dev/null
@@ -0,0 +1,407 @@
+<?php
+/**
+ * Table Definition for vohead
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Vohead extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'vohead';              // table name
+    public $vohead_id;                       // int4(4)  not_null default_nextval%28%28vohead_vohead_id_seq%29%3A%3Aregclass%29 primary_key
+    public $vohead_number;                   // text(-1)  unique_key
+    public $vohead_pohead_id;                // int4(4)  
+    public $vohead_posted;                   // bool(1)  
+    public $vohead_duedate;                  // date(4)  
+    public $vohead_invcnumber;               // text(-1)  
+    public $vohead_amount;                   // numeric(-1)  
+    public $vohead_docdate;                  // date(4)  
+    public $vohead_1099;                     // bool(1)  
+    public $vohead_distdate;                 // date(4)  
+    public $vohead_reference;                // text(-1)  
+    public $vohead_terms_id;                 // int4(4)  
+    public $vohead_vend_id;                  // int4(4)  
+    public $vohead_curr_id;                  // int4(4)  default_basecurrid%28%29
+    public $vohead_adjtaxtype_id;            // int4(4)  
+    public $vohead_freighttaxtype_id;        // int4(4)  
+    public $vohead_gldistdate;               // date(4)  
+    public $vohead_misc;                     // bool(1)  
+    public $vohead_taxzone_id;               // int4(4)  
+    public $vohead_taxtype_id;               // int4(4)  
+    public $vohead_notes;                    // text(-1)  
+
+    
+   /**
+    * Getter / Setter for $vohead_curr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function curr() {
+        return func_num_args() ? $this->link('vohead_curr_id', func_get_arg(0)) : $this->link('vohead_curr_id');
+    }
+
+   /**
+    * Getter / Setter for $vohead_adjtaxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function adjtaxtype() {
+        return func_num_args() ? $this->link('vohead_adjtaxtype_id', func_get_arg(0)) : $this->link('vohead_adjtaxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $vohead_freighttaxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function freighttaxtype() {
+        return func_num_args() ? $this->link('vohead_freighttaxtype_id', func_get_arg(0)) : $this->link('vohead_freighttaxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $vohead_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('vohead_taxtype_id', func_get_arg(0)) : $this->link('vohead_taxtype_id');
+    }
+
+   /**
+    * Getter / Setter for $vohead_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('vohead_taxzone_id', func_get_arg(0)) : $this->link('vohead_taxzone_id');
+    }
+
+    
+    
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    
+    
+    function applyFilters($q, $au, $roo)
+    {
+        if (isset($q['_freight'])) {
+            // depricated..
+            $accnt = DB_DataObject::Factory('accnt');
+            $accnt->whereAdd("accnt_descrip like '%Freight%'");
+            $ids = $accnt->fetchAll('accnt_id');
+            
+            $dis = DB_DAtaObject::Factory('vodist');
+            $dis->whereAddIn('vodist_accnt_id', $ids, 'int');
+            $dis->selectAdd();
+            $dis->selectAdd("distinct(vodist_vohead_id)");
+            $voheads = $dis->fetchAll('vodist_vohead_id');
+            
+            $this->whereAddIn("vohead_id", $voheads, 'int');
+            $this->vohead_posted= true;
+             
+            $this->selectAdd("
+                
+                ROUND( (SELECT ABS(SUM(currtocurr(basecurrid(), vohead_curr_id, gltrans_amount, gltrans_date)))
+                    FROM
+                        gltrans
+                    WHERE
+                        gltrans_docnumber=vohead_number
+                    AND
+                        gltrans_doctype = 'VO'
+                    AND
+                        gltrans_accnt_id IN (" . implode(',', $ids) . ")
+                ),2) as  vohead_total  
+                               
+                             ");
+            
+            
+            //$this->joinAddVendor();
+        }
+        if (!empty($q['query']['vohead_invcnumber'])) {
+            $val = $this->escape($q['query']['vohead_invcnumber']);
+            $this->whereAdd("vohead_invcnumber LIKE '$val%'");
+            
+        }
+        
+        
+        if (!empty($q['_search'])) {
+            $val = $this->escape($q['_search']);
+            $this->whereAdd("vohead_number LIKE '%$val%'");
+            
+        }
+        
+        if (!empty($q['_landed'])) {
+            // only list vouchers that have landed costs..
+            $accnt = DB_DataObject::Factory('accnt');
+            // ??? 
+            $accnt->whereAdd("accnt_descrip like '%Cost of Freight%'");
+            $ids = $accnt->fetchAll('accnt_id');
+            
+            $dis = DB_DAtaObject::Factory('vodist');
+            $dis->whereAddIn('vodist_accnt_id', $ids, 'int');
+            $dis->selectAdd();
+            $dis->selectAdd("distinct(vodist_vohead_id)");
+            $voheads = $dis->fetchAll('vodist_vohead_id');
+            
+            $this->whereAddIn("vohead_id", $voheads, 'int');
+            $this->vohead_posted= true;
+            
+            
+            
+            
+            
+             $this->selectAdd("
+                ROUND( (SELECT ABS(SUM(currtocurr(basecurrid(), vohead_curr_id, gltrans_amount, gltrans_date)))
+                    FROM
+                        gltrans
+                    WHERE
+                        gltrans_docnumber=vohead_number
+                    AND
+                        gltrans_doctype = 'VO'
+                    AND
+                        gltrans_accnt_id IN (" . implode(',', $ids) . ")
+                ),2) as  vohead_total  
+                
+                
+                
+                
+                
+                 ");
+            // assigned should always be in vohead currency..
+             $this->selectAdd("
+                COALESCE((SELECT sum(recvgrpland_cost) FROM   recvgrpland
+                    WHERE
+                        recvgrpland_vohead_id = vohead_id
+                ), 0) as assigned
+                
+            ");
+            switch($q['_landed_status']) {
+                
+                case 'NOTASSIGN':
+                    $this->whereAdd("
+                        ROUND((SELECT ABS(SUM(  (currtocurr(basecurrid(), vohead_curr_id,  gltrans_amount, gltrans_date) )))
+                           FROM
+                               gltrans
+                           WHERE
+                               gltrans_docnumber=vohead_number
+                           AND
+                               gltrans_doctype = 'VO'
+                           AND
+                               gltrans_accnt_id IN (" . implode(',', $ids) . ")
+                       ),2)
+                       
+                       - ROUND(COALESCE((SELECT sum(recvgrpland_cost) FROM   recvgrpland
+                           WHERE
+                               recvgrpland_vohead_id = vohead_id
+                       ), 0),2) > 0.0                                    
+                        AND
+                        vohead_number NOT LIKE 'NS%'
+                          AND
+                        vohead_number NOT LIKE 'P%'                         
+                    ");
+                    break;
+                
+                
+                
+                case 'ASSIGNED':
+                    
+                    $this->whereAdd("
+                        ROUND((SELECT ABS(SUM(  (currtocurr(basecurrid(), vohead_curr_id,  gltrans_amount, gltrans_date) )))
+                           FROM
+                               gltrans
+                           WHERE
+                               gltrans_docnumber=vohead_number
+                           AND
+                               gltrans_doctype = 'VO'
+                           AND
+                               gltrans_accnt_id IN (" . implode(',', $ids) . ")
+                       ),2)
+                       - ROUND(COALESCE((SELECT sum(recvgrpland_cost) FROM   recvgrpland
+                           WHERE
+                               recvgrpland_vohead_id = vohead_id
+                       ), 0),2) = 0.0                                    
+                        AND
+                        vohead_number NOT LIKE 'NS%'                   
+                             AND
+                        vohead_number NOT LIKE 'P%'               
+                    ");
+                    break;
+                    
+                    
+            }
+            
+            
+        }
+        
+        
+        
+        
+    }
+    function vend()
+    {
+        $d = DB_DataObject::Factory('vendinfo');
+        $d->get($this->vohead_vend_id);
+        return $d;
+        
+    }
+    
+    function costofshippingaccnt()
+    {
+         $accnt = DB_DataObject::Factory('accnt');
+            // ??? 
+        $accnt->whereAdd("accnt_descrip like '%Cost of Freight%'");
+        $ids = $accnt->fetchAll('accnt_id');
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->gltrans_docnumber= $this->vohead_number;
+        $gl->gltrans_doctype = 'VO';
+        $gl->whereAddIn('gltrans_accnt_id', $ids , 'int');
+        $gl->selectAdd();
+        $gl->selectAdd('DISTINCT(gltrans_accnt_id) as gltrans_accnt_id');
+        $gl->limit(1);
+        $gl->find(true);
+        return $gl->gltrans_accnt_id;
+        
+        
+    }
+    
+    
+    function costofshipping()
+    {
+        
+         $accnt = DB_DataObject::Factory('accnt');
+            // ??? 
+        $accnt->whereAdd("accnt_descrip like '%Cost of Freight%'");
+        $ids = $accnt->fetchAll('accnt_id');
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->gltrans_docnumber= $this->vohead_number;
+        $gl->gltrans_doctype = 'VO';
+        $gl->whereAddIn('gltrans_accnt_id', $ids , 'int');
+        $gl->selectAdd();
+        $gl->selectAdd('ABS(SUM(gltrans_amount)) as gltrans_amount');
+        $gl->find(true);
+        return $gl->gltrans_amount;
+    }
+    function assignedcost() 
+    {
+        
+        $l = DB_DataObject::Factory('recvgrpland');
+        $l->recvgrpland_vohead_id = $this->vohead_id;
+        $l->selectAdd();
+        
+        $l->selectAdd('sum(recvgrpland_cost) as rcost');
+        $l->find(true);
+        return $l->rcost;
+    }
+    
+    
+    
+    /*
+    function joinAddVendor()
+    {
+        
+        $this->_join .= "
+            LEFT JOIN vendinfo AS join_vohead_vend_id_vend_id
+                    ON (join_vohead_vend_id_vend_id.vend_id= vohead.vohead_vend_id)
+        ";
+        $t = DB_DataObject::Factory('vendinfo');
+        $this->selectAs($t, 'vohead_vend_id_%s', 'join_vohead_vend_id_vend_id');
+       
+         
+    }
+    */
+    
+    function defaults()
+    {
+        return array(
+            //'vohead_amount'=> 0,  // this will probably get filled by items..
+            'vohead_invcnumber'=>'',
+            'vohead_posted'=>false,
+            'vohead_misc'=>false, //??? 0 ?
+            
+            'vohead_1099' => false,
+            'vohead_reference' => '',
+            //'vohead_adjtaxtype_id'=>'|NULL', //(SELECT taxtype_id FROM taxtype WHERE taxtype_name='Adjustment' LIMIT 1)",
+            //'vohead_freighttaxtype_id'=>'|NULL', //|(SELECT taxtype_id FROM taxtype WHERE taxtype_name='Freight' LIMIT 1)",
+        );
+    }
+    
+    function createFromPO($roo, $po, $num = false)
+    {
+        $tot = 0.0;
+        $items = $po->items();
+        foreach($items  as $item)
+        {
+            $tot = bcadd( $tot, bcmul($item->poitem_unitprice , $item->poitem_qty_ordered, 2),2);
+        }
+        
+
+        $this->setFrom($this->defaults());
+        
+        $this->setFrom(array(
+            
+            
+            'vohead_number'=>   $num === false ? $po->pohead_number : $num,
+            'vohead_docdate'=>  $po->pohead_orderdate,
+            'vohead_distdate'=> $po->pohead_orderdate,
+            'vohead_duedate'=>  $po->pohead_orderdate,
+            'vohead_invcnumber'=> '',
+            'vohead_amount'=>   $tot,
+            'vohead_terms_id'=> $po->pohead_terms_id,
+            'vohead_notes'=>    'Created from transfer',
+            'vohead_curr_id'=>  $po->pohead_curr_id,
+            'vohead_pohead_id' => $po->pohead_id,
+            'vohead_vend_id' => $po->pohead_vend_id,
+            'vohead_taxtype_id'=> $po->pohead_taxtype_id,
+            'vohead_taxzone_id'=>$po->pohead_taxzone_id,
+            //'vohead_misc'=> 0
+            
+            
+            
+        ));
+        $this->insert();
+        foreach($items as $item) {
+            $vi = DB_DataObject::Factory('voitem');
+            $vi->createFromPoItem($roo, $this, $item);
+        }
+        //$roo->jerr( print_R($this->toArray(), true) .  print_R($this->items(), true)  );
+        
+        
+    }
+    function post($roo) {
+        $vd = DB_DAtaObject::factory('vodist');
+        
+        $vd->query("SELECT postVoucher({$this->pid()},
+                    fetchJournalNumber('AP-VO'), TRUE) AS result");
+        $vd->fetch();
+        if (!$vd->result || $vd->result < 0) {
+            
+            $roo->jerr("posing journal failed.");
+            
+       
+        }
+        return true;
+    }
+    function items()
+    {
+        $vi = DB_DAtaObject::factory('voitem');
+        $vi->voitem_vohead_id = $this->pid();
+        return $vi->fetchAll();
+        
+    }
+      function distitems()
+    {
+        $vi = DB_DAtaObject::factory('vodist');
+        $vi->vodist_vohead_id = $this->pid();
+        return $vi->fetchAll();
+        
+    }
+}
diff --git a/DataObjects/Voheadtax.php b/DataObjects/Voheadtax.php
new file mode 100644 (file)
index 0000000..e7dd148
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for voheadtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Voheadtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'voheadtax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Voitem.php b/DataObjects/Voitem.php
new file mode 100644 (file)
index 0000000..6fe114c
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Table Definition for voitem
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Voitem extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'voitem';              // table name
+    public $voitem_id;                       // int4(4)  not_null default_nextval%28%28%22voitem_voitem_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $voitem_vohead_id;                // int4(4)  
+    public $voitem_poitem_id;                // int4(4)  
+    public $voitem_close;                    // bool(1)  
+    public $voitem_qty;                      // numeric(-1)  
+    public $voitem_freight;                  // numeric(-1)  not_null default_0.0
+    public $voitem_taxtype_id;               // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $voitem_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('voitem_taxtype_id', func_get_arg(0)) : $this->link('voitem_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    function createFromPoItem($roo,$vo, $poitem)
+    {
+       
+        $x = DB_DataObject::factory('vohead');
+        // this may work if done multiple times..???
+        $x->query(" SELECT distributeVoucherLine(
+                        vohead_id,
+                        {$poitem->pid()},
+                        vohead_curr_id
+                    ) as result FROM
+                    vohead where vohead_id = {$vo->pid()}");
+        $x->fetch();
+        if (!isset($x->result)|| $x->result < 1) {
+            $roo->jerr("distributeVoucherLine failed");
+        }
+        return true;
+         /*
+       
+        $this->setFrom(array(
+             
+             'voitem_vohead_id' => $vo->pid(),
+            'voitem_poitem_id' => $poitem->pid(),
+            'voitem_close' => false,
+            'voitem_qty' => $poitem->poitem_qty_ordered,
+            'voitem_freight' => 0,
+            'voitem_taxtype_id'  => $poitem->poitem_taxtype_id,
+            
+        ));
+        $this->insert();
+    */
+    }
+   
+}
diff --git a/DataObjects/Voitemtax.php b/DataObjects/Voitemtax.php
new file mode 100644 (file)
index 0000000..6457d08
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Table Definition for voitemtax
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Voitemtax extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'voitemtax';           // table name
+    public $taxhist_id;                      // int4(4)  not_null default_nextval%28taxhist_taxhist_id_seq%29 primary_key
+    public $taxhist_parent_id;               // int4(4)  not_null
+    public $taxhist_taxtype_id;              // int4(4)  
+    public $taxhist_tax_id;                  // int4(4)  not_null
+    public $taxhist_basis;                   // numeric(-1)  not_null
+    public $taxhist_basis_tax_id;            // int4(4)  
+    public $taxhist_sequence;                // int4(4)  
+    public $taxhist_percent;                 // numeric(-1)  not_null
+    public $taxhist_amount;                  // numeric(-1)  not_null
+    public $taxhist_tax;                     // numeric(-1)  not_null
+    public $taxhist_docdate;                 // date(4)  not_null
+    public $taxhist_distdate;                // date(4)  
+    public $taxhist_curr_id;                 // int4(4)  
+    public $taxhist_curr_rate;               // numeric(-1)  
+    public $taxhist_journalnumber;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $taxhist_basis_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function basis_tax() {
+        return func_num_args() ? $this->link('taxhist_basis_tax_id', func_get_arg(0)) : $this->link('taxhist_basis_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_parent_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function parent() {
+        return func_num_args() ? $this->link('taxhist_parent_id', func_get_arg(0)) : $this->link('taxhist_parent_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_tax_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function tax() {
+        return func_num_args() ? $this->link('taxhist_tax_id', func_get_arg(0)) : $this->link('taxhist_tax_id');
+    }
+
+   /**
+    * Getter / Setter for $taxhist_taxtype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxtype() {
+        return func_num_args() ? $this->link('taxhist_taxtype_id', func_get_arg(0)) : $this->link('taxhist_taxtype_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Voucheringeditlist.php b/DataObjects/Voucheringeditlist.php
new file mode 100644 (file)
index 0000000..9cc3a9c
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Table Definition for voucheringeditlist
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Voucheringeditlist extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'voucheringeditlist';    // table name
+    public $vendid;                          // int4(4)  
+    public $orderid;                         // int4(4)  
+    public $itemid;                          // int4(4)  
+    public $vouchernumber;                   // text(-1)  
+    public $ponumber;                        // text(-1)  
+    public $invoicenumber;                   // text(-1)  
+    public $itemnumber;                      // text(-1)  
+    public $description;                     // text(-1)  
+    public $itemtype;                        // text(-1)  
+    public $iteminvuom;                      // text(-1)  
+    public $f_qty;                           // text(-1)  
+    public $cost;                            // numeric(-1)  
+    public $f_cost;                          // text(-1)  
+    public $account;                         // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Warehous.php b/DataObjects/Warehous.php
new file mode 100644 (file)
index 0000000..3da141a
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Table Definition for warehous
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Warehous extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'warehous';            // table name
+    public $warehous_id;                     // int4(4)  
+    public $warehous_code;                   // text(-1)  
+    public $warehous_descrip;                // text(-1)  
+    public $warehous_addr1;                  // text(-1)  
+    public $warehous_addr2;                  // text(-1)  
+    public $warehous_addr3;                  // text(-1)  
+    public $warehous_addr4;                  // text(-1)  
+    public $warehous_city;                   // text(-1)  
+    public $warehous_state;                  // text(-1)  
+    public $warehous_zip;                    // text(-1)  
+    public $warehous_country;                // text(-1)  
+    public $warehous_fob;                    // text(-1)  
+    public $warehous_active;                 // bool(1)  
+    public $warehous_sitetype_id;            // int4(4)  
+    public $warehous_counttag_prefix;        // text(-1)  
+    public $warehous_counttag_number;        // int4(4)  
+    public $warehous_bol_prefix;             // text(-1)  
+    public $warehous_bol_number;             // int4(4)  
+    public $warehous_shipping;               // bool(1)  
+    public $warehous_useslips;               // bool(1)  
+    public $warehous_usezones;               // bool(1)  
+    public $warehous_aislesize;              // int4(4)  
+    public $warehous_aislealpha;             // bool(1)  
+    public $warehous_racksize;               // int4(4)  
+    public $warehous_rackalpha;              // bool(1)  
+    public $warehous_binsize;                // int4(4)  
+    public $warehous_binalpha;               // bool(1)  
+    public $warehous_locationsize;           // int4(4)  
+    public $warehous_locationalpha;          // bool(1)  
+    public $warehous_enforcearbl;            // bool(1)  
+    public $warehous_default_accnt_id;       // int4(4)  
+    public $warehous_shipping_commission;    // numeric(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Whsezone.php b/DataObjects/Whsezone.php
new file mode 100644 (file)
index 0000000..6bd8a46
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Table Definition for whsezone
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Whsezone extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'whsezone';            // table name
+    public $whsezone_id;                     // int4(4)  not_null default_nextval%28whsezone_whsezone_id_seq%29 primary_key
+    public $whsezone_warehous_id;            // int4(4)  not_null
+    public $whsezone_name;                   // text(-1)  not_null
+    public $whsezone_descrip;                // text(-1)  
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Whsinfo.php b/DataObjects/Whsinfo.php
new file mode 100644 (file)
index 0000000..e1ef082
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Table Definition for whsinfo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Whsinfo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'whsinfo';             // table name
+    public $warehous_id;                     // int4(4)  not_null default_nextval%28%28warehous_warehous_id_seq%29%3A%3Aregclass%29 primary_key
+    public $warehous_code;                   // text(-1)  unique_key
+    public $warehous_descrip;                // text(-1)  
+    public $warehous_fob;                    // text(-1)  
+    public $warehous_active;                 // bool(1)  
+    public $warehous_counttag_prefix;        // text(-1)  
+    public $warehous_counttag_number;        // int4(4)  
+    public $warehous_bol_prefix;             // text(-1)  
+    public $warehous_bol_number;             // int4(4)  
+    public $warehous_shipping;               // bool(1)  
+    public $warehous_useslips;               // bool(1)  
+    public $warehous_usezones;               // bool(1)  
+    public $warehous_aislesize;              // int4(4)  
+    public $warehous_aislealpha;             // bool(1)  
+    public $warehous_racksize;               // int4(4)  
+    public $warehous_rackalpha;              // bool(1)  
+    public $warehous_binsize;                // int4(4)  
+    public $warehous_binalpha;               // bool(1)  
+    public $warehous_locationsize;           // int4(4)  
+    public $warehous_locationalpha;          // bool(1)  
+    public $warehous_enforcearbl;            // bool(1)  
+    public $warehous_default_accnt_id;       // int4(4)  
+    public $warehous_shipping_commission;    // numeric(-1)  default_0.00
+    public $warehous_cntct_id;               // int4(4)  
+    public $warehous_addr_id;                // int4(4)  
+    public $warehous_transit;                // bool(1)  not_null default_false
+    public $warehous_shipform_id;            // int4(4)  
+    public $warehous_shipvia_id;             // int4(4)  
+    public $warehous_shipcomments;           // text(-1)  
+    public $warehous_costcat_id;             // int4(4)  
+    public $warehous_sitetype_id;            // int4(4)  
+    public $warehous_taxzone_id;             // int4(4)  
+    public $warehous_sequence;               // int4(4)  not_null default_0
+
+    
+   /**
+    * Getter / Setter for $warehous_default_accnt_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function default_accnt() {
+        return func_num_args() ? $this->link('warehous_default_accnt_id', func_get_arg(0)) : $this->link('warehous_default_accnt_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_addr_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function addr() {
+        return func_num_args() ? $this->link('warehous_addr_id', func_get_arg(0)) : $this->link('warehous_addr_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_cntct_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function cntct() {
+        return func_num_args() ? $this->link('warehous_cntct_id', func_get_arg(0)) : $this->link('warehous_cntct_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_costcat_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function costcat() {
+        return func_num_args() ? $this->link('warehous_costcat_id', func_get_arg(0)) : $this->link('warehous_costcat_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_shipform_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipform() {
+        return func_num_args() ? $this->link('warehous_shipform_id', func_get_arg(0)) : $this->link('warehous_shipform_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_shipvia_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function shipvia() {
+        return func_num_args() ? $this->link('warehous_shipvia_id', func_get_arg(0)) : $this->link('warehous_shipvia_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_sitetype_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function sitetype() {
+        return func_num_args() ? $this->link('warehous_sitetype_id', func_get_arg(0)) : $this->link('warehous_sitetype_id');
+    }
+
+   /**
+    * Getter / Setter for $warehous_taxzone_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function taxzone() {
+        return func_num_args() ? $this->link('warehous_taxzone_id', func_get_arg(0)) : $this->link('warehous_taxzone_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Wo.php b/DataObjects/Wo.php
new file mode 100644 (file)
index 0000000..f97b7f5
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Table Definition for wo
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Wo extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'wo';                  // table name
+    public $wo_id;                           // int4(4)  not_null default_nextval%28%28wo_wo_id_seq%29%3A%3Aregclass%29 primary_key
+    public $wo_number;                       // int4(4)  
+    public $wo_subnumber;                    // int4(4)  
+    public $wo_status;                       // bpchar(-1)  
+    public $wo_itemsite_id;                  // int4(4)  
+    public $wo_startdate;                    // date(4)  
+    public $wo_duedate;                      // date(4)  
+    public $wo_ordtype;                      // bpchar(-1)  
+    public $wo_ordid;                        // int4(4)  
+    public $wo_qtyord;                       // numeric(-1)  
+    public $wo_qtyrcv;                       // numeric(-1)  
+    public $wo_adhoc;                        // bool(1)  
+    public $wo_itemcfg_series;               // int4(4)  
+    public $wo_imported;                     // bool(1)  
+    public $wo_wipvalue;                     // numeric(-1)  default_0
+    public $wo_postedvalue;                  // numeric(-1)  default_0
+    public $wo_prodnotes;                    // text(-1)  
+    public $wo_prj_id;                       // int4(4)  
+    public $wo_priority;                     // int4(4)  not_null default_1
+    public $wo_brdvalue;                     // numeric(-1)  default_0
+    public $wo_bom_rev_id;                   // int4(4)  default_%28-1%29
+    public $wo_boo_rev_id;                   // int4(4)  default_%28-1%29
+    public $wo_cosmethod;                    // bpchar(-1)  
+    public $wo_womatl_id;                    // int4(4)  
+    public $wo_username;                     // text(-1)  default_%22current_user%22%28%29
+
+    
+   /**
+    * Getter / Setter for $wo_womatl_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function womatl() {
+        return func_num_args() ? $this->link('wo_womatl_id', func_get_arg(0)) : $this->link('wo_womatl_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Womatl.php b/DataObjects/Womatl.php
new file mode 100644 (file)
index 0000000..5b1e660
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Table Definition for womatl
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Womatl extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'womatl';              // table name
+    public $womatl_id;                       // int4(4)  not_null default_nextval%28%28womatl_womatl_id_seq%29%3A%3Aregclass%29 primary_key
+    public $womatl_wo_id;                    // int4(4)  
+    public $womatl_itemsite_id;              // int4(4)  
+    public $womatl_qtyper;                   // numeric(-1)  not_null
+    public $womatl_scrap;                    // numeric(-1)  not_null
+    public $womatl_qtyreq;                   // numeric(-1)  not_null
+    public $womatl_qtyiss;                   // numeric(-1)  not_null
+    public $womatl_qtywipscrap;              // numeric(-1)  not_null
+    public $womatl_lastissue;                // date(4)  
+    public $womatl_lastreturn;               // date(4)  
+    public $womatl_cost;                     // numeric(-1)  
+    public $womatl_picklist;                 // bool(1)  
+    public $womatl_status;                   // bpchar(-1)  
+    public $womatl_imported;                 // bool(1)  default_false
+    public $womatl_createwo;                 // bool(1)  
+    public $womatl_issuemethod;              // bpchar(-1)  
+    public $womatl_wooper_id;                // int4(4)  
+    public $womatl_bomitem_id;               // int4(4)  
+    public $womatl_duedate;                  // date(4)  
+    public $womatl_schedatwooper;            // bool(1)  
+    public $womatl_uom_id;                   // int4(4)  not_null
+    public $womatl_notes;                    // text(-1)  
+    public $womatl_ref;                      // text(-1)  
+    public $womatl_scrapvalue;               // numeric(-1)  default_0
+    public $womatl_qtyfxd;                   // numeric(-1)  not_null default_0
+
+    
+   /**
+    * Getter / Setter for $womatl_uom_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function uom() {
+        return func_num_args() ? $this->link('womatl_uom_id', func_get_arg(0)) : $this->link('womatl_uom_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Womatlpost.php b/DataObjects/Womatlpost.php
new file mode 100644 (file)
index 0000000..e28f64c
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Table Definition for womatlpost
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Womatlpost extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'womatlpost';          // table name
+    public $womatlpost_id;                   // int4(4)  not_null default_nextval%28womatlpost_womatlpost_id_seq%29 primary_key
+    public $womatlpost_womatl_id;            // int4(4)  
+    public $womatlpost_invhist_id;           // int4(4)  
+
+    
+   /**
+    * Getter / Setter for $womatlpost_invhist_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function invhist() {
+        return func_num_args() ? $this->link('womatlpost_invhist_id', func_get_arg(0)) : $this->link('womatlpost_invhist_id');
+    }
+
+   /**
+    * Getter / Setter for $womatlpost_womatl_id
+    *
+    * @param    mixed   (optional) value to assign
+    * @access   public
+    */
+    public function womatl() {
+        return func_num_args() ? $this->link('womatlpost_womatl_id', func_get_arg(0)) : $this->link('womatlpost_womatl_id');
+    }
+
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Womatlvar.php b/DataObjects/Womatlvar.php
new file mode 100644 (file)
index 0000000..2106d20
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Table Definition for womatlvar
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Womatlvar extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'womatlvar';           // table name
+    public $womatlvar_id;                    // int4(4)  not_null default_nextval%28%28%22womatlvar_womatlvar_id_seq%22%29%3A%3Aregclass%29 primary_key
+    public $womatlvar_number;                // int4(4)  
+    public $womatlvar_subnumber;             // int4(4)  
+    public $womatlvar_posted;                // date(4)  
+    public $womatlvar_parent_itemsite_id;    // int4(4)  
+    public $womatlvar_component_itemsite_id;    // int4(4)  
+    public $womatlvar_qtyord;                // numeric(-1)  
+    public $womatlvar_qtyrcv;                // numeric(-1)  
+    public $womatlvar_qtyiss;                // numeric(-1)  
+    public $womatlvar_qtyper;                // numeric(-1)  
+    public $womatlvar_scrap;                 // numeric(-1)  
+    public $womatlvar_wipscrap;              // numeric(-1)  
+    public $womatlvar_bomitem_id;            // int4(4)  
+    public $womatlvar_ref;                   // text(-1)  
+    public $womatlvar_notes;                 // text(-1)  
+    public $womatlvar_qtyfxd;                // numeric(-1)  not_null default_0
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Xsltmap.php b/DataObjects/Xsltmap.php
new file mode 100644 (file)
index 0000000..4e2e1db
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Table Definition for xsltmap
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Xsltmap extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'xsltmap';             // table name
+    public $xsltmap_id;                      // int4(4)  not_null default_nextval%28xsltmap_xsltmap_id_seq%29 primary_key
+    public $xsltmap_name;                    // text(-1)  not_null unique_key
+    public $xsltmap_doctype;                 // text(-1)  not_null
+    public $xsltmap_system;                  // text(-1)  not_null
+    public $xsltmap_import;                  // text(-1)  not_null
+    public $xsltmap_export;                  // text(-1)  not_null default_
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/DataObjects/Yearperiod.php b/DataObjects/Yearperiod.php
new file mode 100644 (file)
index 0000000..9966e7a
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Table Definition for yearperiod
+ */
+require_once 'DB/DataObject.php';
+
+class Pman_Xtuple_DataObjects_Yearperiod extends DB_DataObject 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__table = 'yearperiod';          // table name
+    public $yearperiod_id;                   // int4(4)  not_null default_nextval%28yearperiod_yearperiod_id_seq%29 primary_key
+    public $yearperiod_start;                // date(4)  not_null
+    public $yearperiod_end;                  // date(4)  not_null
+    public $yearperiod_closed;               // bool(1)  not_null default_false
+
+    
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+    
+    function beforeUpdate($old, $q,$roo)
+    {
+        if(isset($q['_close'])){
+            $this->close($roo);
+            $roo->jok("closed");
+        }
+        if(isset($q['_open'])){
+            $this->open($roo);
+            $roo->jok("opened");
+        }
+        
+    }
+    
+    /*
+     * close the period
+     */
+    function close($roo)
+    {
+        $yearperiod = DB_DataObject::factory('yearperiod');
+        $yearperiod->query("SELECT closeAccountingYearPeriod({$this->yearperiod_id}) AS result");
+        $yearperiod->fetch();
+        if($yearperiod->result < 0){
+            switch ($yearperiod->result){
+                case -1 :
+                    $roo->jerr("This year period is already close! result : {$yearperiod->result}");
+                    break;
+                case -4 :
+                    $roo->jerr("Next year period is not found! result : {$yearperiod->result}");
+                    break;
+                case -5 :
+                    $roo->jerr("Prematurely close this year period! result : {$yearperiod->result}");
+                    break;
+                case -6 :
+                    $roo->jerr("Year period is not found! result : {$yearperiod->result}");
+                    break;
+                case -7 :
+                    $roo->jerr("Can not found the default account number for year end closing! result : {$yearperiod->result}");
+                    break;
+                case -8 :
+                    $roo->jerr("Can not found where to stick the end of year data! result : {$yearperiod->result}");
+                    break;
+                case -9 :
+                    $roo->jerr("Can not found trialbal! result : {$yearperiod->result}");
+                    break;
+                case -10 :
+                    $roo->jerr("Not all the period of this year period are closed! result : {$yearperiod->result}");
+                    break;
+                case -11 :
+                    $roo->jerr("Pervious year period is not closed! result : {$yearperiod->result}");
+                    break;
+
+                default :
+                    $roo->jerr("Error occur on close accounting year period! result : {$yearperiod->result}");
+                    break;
+            }
+        }
+        
+    }
+     function open($roo)
+    {
+        $period = DB_DataObject::factory('period');
+        $period->query("SELECT openAccountingYearPeriod({$this->yearperiod_id}) AS result");
+        $period->fetch();
+        if($period->result < 0){
+            switch ($period->result){
+                case -1 :
+                case -2:
+                    $roo->jerr("This period is already open! name : {$this->period_name} result : {$period->result}");
+                    break;
+               
+                default :
+                    $roo->jerr("Error occur on open accounting period! name : {$this->period_name} result : {$period->result}");
+                    break;
+            }
+        }
+    }
+    
+}
diff --git a/DataObjects/invdetailview.php b/DataObjects/invdetailview.php
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Fifo/FillPurchasePrices.php b/Fifo/FillPurchasePrices.php
new file mode 100644 (file)
index 0000000..b0022d6
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+
+/**
+ * fill in products pruchase price
+ * 
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_FillPurchasePrices extends  Pman_Xtuple_Fifo_ProcessBase
+{
+    static $cli_desc = "Fill in products pruchase price";
+   
+    static $permitError = false;
+    
+    function get()
+    {
+        
+       // DB_DataObject::debugLevel(1);
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $i = DB_DataObject::factory('item');
+        $i->_join .= "
+            LEFT JOIN 
+                itemsite 
+            ON 
+                itemsite_item_id = item_id
+            WHERE
+                itemsite_item_id > 0
+        ";
+        $i->selectAdd();
+        $i->selectAdd("item_id,itemsite_id");
+        $i->orderby('item_id');
+        $items = $i->fetchAll('item_id','itemsite_id');
+        foreach ($items as $item_id => $itemsite_id){
+            // now see if we have any itemsrcs..
+            $pi = $this->fetch_poitem($itemsite_id );
+            if (!$pi) {
+                continue;
+            }
+            
+            $is =DB_DataObject::factory('itemsrc');
+            $is->itemsrc_item_id = $item_id;
+            $vender_to_src = $is->fetchAll('itemsrc_vend_id', 'itemsrc_id');
+            
+            $product_has_price = false;
+            
+            foreach($vender_to_src as $vend_id => $itemsrc_id) {
+                if ($pi->pohead_vend_id != $vend_id) {
+                    // give up, the last purchase is not from this vendor..
+                    continue;
+                    
+                }
+                $has_price = false;
+                
+                $ip = DB_DataObject::factory('itemsrcp');
+                $ip->itemsrcp_itemsrc_id = $itemsrc_id;
+                if ($ip->count()) {
+                    // we have some..
+                    foreach($ip->fetchAll() as $ip) {
+                        $has_price =  1;
+                        $product_has_price = 1;
+                        
+                        if($ip->itemsrcp_price != ''){
+                            continue;
+                        }
+                        $ip->itemsrcp_qtybreak = 0;
+                        $ip->itemsrcp_price = $pi->poitem_unitprice;
+                        $ip->itemsrcp_curr_id = $pi->pohead_curr_id;
+
+                        $ip->update();
+                        
+                    }
+                }
+                if ($has_price) {
+                    continue;
+                }
+                
+                $ip->itemsrcp_itemsrc_id = $itemsrc_id;
+                $ip->itemsrcp_qtybreak = 0;
+                $ip->itemsrcp_price = $pi->poitem_unitprice;
+                $ip->itemsrcp_curr_id = $pi->pohead_curr_id;
+                $ip->itemsrcp_updated = date('Y-m-d');
+
+                $ip->insert();
+                $product_has_price = 1;
+            }
+            // now we have looked at all the itemsrc's and not found any pu
+            if ($product_has_price) {
+                // we have already filled in a price..
+                continue;
+            }
+                
+            // at this point we do not have a itemsrc for this product..
+            // create one based on the pi.
+            
+            $is = DB_DataObject::factory('itemsrc');
+            $vend = DB_DataObject::factory('vendinfo');
+            $vend->get($pi->pohead_vend_id);
+            $is->itemsrc_item_id = $item_id;
+            $is->itemsrc_vend_id = $pi->pohead_vend_id;
+            $is->itemsrc_vend_item_number = $vend->vend_number;
+            $is->itemsrc_vend_uom = 1;
+            $is->itemsrc_invvendoruomratio = 1;
+            $is->itemsrc_minordqty = 0;
+            $is->itemsrc_multordqty = 0;
+            $is->itemsrc_leadtime = 0;
+            $is->itemsrc_ranking = 1;
+            $is->itemsrc_active = TRUE;
+            $is->itemsrc_default = TRUE;
+            $is->insert();
+            
+            $ip = DB_DataObject::factory('itemsrcp');
+            $ip->itemsrcp_itemsrc_id = $is->itemsrc_id;
+            $ip->itemsrcp_qtybreak = 0;
+            $ip->itemsrcp_price = $pi->poitem_unitprice;
+            $ip->itemsrcp_curr_id = $pi->pohead_curr_id;
+            $ip->itemsrcp_updated = date('Y-m-d');
+            $ip->insert();
+            // then create an itemsrcp for it as weell..
+            
+        }
+        exit;
+        
+    }
+    
+    function fetch_poitem($itemsite_id){
+        $pi = DB_DataObject::factory('poitem');
+        $pi->_join .= "
+            LEFT JOIN 
+                pohead 
+            ON 
+                poitem_pohead_id = pohead_id
+        ";
+
+        $pi->whereAdd("poitem_itemsite_id = {$itemsite_id}");
+        $pi->orderby("poitem_duedate DESC");
+        $pi->limit(1);
+        return $pi->find(true) ? $pi : '';
+    }
+    
+}
\ No newline at end of file
diff --git a/Fifo/FillValuesWalk2.php b/Fifo/FillValuesWalk2.php
new file mode 100644 (file)
index 0000000..04c8800
--- /dev/null
@@ -0,0 +1,326 @@
+<?php
+
+
+/**
+ *
+ * Idea is to test the walking through of a sequence
+ * to see if we can work out a method of ordering the calculations.
+ *
+ *
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_FillValuesWalk2 extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+  
+    static $cli_desc = "Fill in Fifo dollar values.";
+   
+    static $permitError = false;
+    
+    var $loc_only = false;//187; //false;
+    
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    
+    
+    function get($v)
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        
+      
+        
+        
+        if (!empty($v)) {
+            $this->runSingle($v);
+            die("DONE");
+        }
+        
+        die("single only");
+    }
+    
+    function runSingle($itemsite )
+    {
+        //DB_DataObject::debugLevel(1);
+         
+         
+         
+        $itemsite = (int)$itemsite;
+        $start = time();
+        
+        
+        $id = DB_DataObject::Factory('invdetail');
+         
+        
+        $id->query("SELECT
+       
+                  count(invdetail_id) as nres
+            FROM 
+                    
+                  invdetailview
+          WHERE
+              invhist_itemsite_id = $itemsite
+              AND
+              invfifo_void = 0
+              
+        ");
+        $id->fetch();
+        
+        $total = $id->nres;
+        
+        
+        
+        
+        //exit;
+        $id = DB_DataObject::Factory('invdetail');
+        $id->query("SELECT
+                        *
+                    FROM
+                      
+                invdetailview
+            WHERE
+                invhist_itemsite_id =  {$itemsite}
+                AND
+                invfifo_void = 0
+                AND
+                (
+                    invhist_transtype = 'RP'
+                    OR
+                    invhist_transtype = 'AD'
+                    OR
+                    invhist_transtype = 'RS'
+                ) AND
+                    invdetail_qty >  0
+                    
+            ORDER BY
+         
+                invhist_transdate ASC,
+                invdetail_id ASC
+            
+        ");
+       
+        while ($id->fetch()) {
+            $all[] = clone($id);
+        }
+        
+        
+       
+        foreach($all as $id) {
+            $idr = DB_DataObject::Factory('invdetail');
+            $idr->query("SELECT invfifo_update_from_invdetail({$id->invdetail_id},true)");
+            
+            
+            // fill in all outgoing based on these reciepts..
+            
+            $this->regBuy( $id->invdetail_id, $id->invdetail_location_id, $id->invfifo_qty_before, $id->invfifo_qty_after, 'S');
+           
+             
+        }
+          while (true) {
+            $before = count($this->done);
+            foreach($this->locs as $loc=>$ar) {
+                
+               $this->processOut($loc, $itemsite);
+                
+            }
+            if (count($this->done) == $before) {
+                break;
+            }
+        // process remaining locs...
+        } 
+        echo "DONE : ". count($this->done) . " out of $total \n";
+        //print_R($done);
+    
+        exit;
+          
+        
+   
+    }
+    
+    function processOut($loc, $itemsite)
+    {
+        
+        if (!isset($this->locs[$loc]) || $this->locs[$loc][0] > 0)  {
+            return; // no record or can not start..
+        }
+        
+         
+        $end = $this->locs[$loc][1];
+      
+        $id = DB_DataObject::Factory('invdetail');
+        
+        $q = array();
+        for($i = 0; $i < count($this->locs[$loc]); $i+=2) {
+            
+            $q[] = "
+                
+                (invfifo_qty_before >= {$this->locs[$loc][$i]} AND invfifo_qty_after <= {$this->locs[$loc][$i+1]})
+            ";
+        }
+        
+        
+        $id->query("SELECT
+       
+              *
+                FROM
+                    
+              invdetailview
+          WHERE
+              invhist_itemsite_id =  {$itemsite}
+              AND
+              invfifo_void = 0
+              AND
+              invdetail_qty < 0
+              AND
+              (". implode(' OR ', $q) . ") 
+             AND
+             invdetail_location_id = $loc
+             AND
+             invdetail_id NOT IN (". implode(',', $this->done) . ") 
+          ORDER BY
+       
+              invhist_transdate ASC,
+              invdetail_id ASC
+          
+        ");
+        $all = array();
+        while($id->fetch()) {
+            $all[] = clone($id);
+            
+            $ret[] = $id->invdetail_id;
+            
+        }
+       // $done = array();
+        foreach($all as $id) {
+            //var_dump($id->invdetail_id);
+            if (in_array($id->invdetail_id, $this->done)) {
+                continue;
+            }
+            
+            
+            $idr = DB_DataObject::Factory('invdetail');
+            $idr->query("SELECT invfifo_update_from_invdetail({$id->invdetail_id},true)");
+           
+             
+            // if it's a transfer, then flag the reverse as done as well..
+            if ($id->invhist_transtype == 'RL') {
+                $idr = DB_DataObject::Factory('invdetail');
+                $idr->query("SELECT *
+                                FROM invdetailview WHERE invdetail_invhist_id = {$id->invhist_id} AND invdetail_id != {$id->invdetail_id}
+                            ");
+                $idr->fetch();
+                $this->regBuy(  $idr->invdetail_id,   $idr->invdetail_location_id, $idr->invfifo_qty_before, $idr->invfifo_qty_after, 'R');
+                
+                
+                $invdetail_id =  $idr->invdetail_id;
+                $out_loc = $idr->invdetail_location_id;
+                
+                $idr = DB_DataObject::Factory('invdetail');
+                $idr->query("SELECT invfifo_update_from_invdetail({$invdetail_id},true)");
+                
+               
+                
+               
+                
+            }
+            
+            
+        }
+         
+        
+        
+        
+    }
+    var $done = array( 0 );
+    var $locs = array();
+    function regBuy($invdetail_id, $loc, $start, $end, $type) {
+        
+        if (in_array($invdetail_id, $this->done)) {
+            return;
+        }
+        $this->done[] = $invdetail_id;
+        
+        echo "$loc S:$start, $end  : $type\n";
+        if (!isset($this->locs[$loc])) {
+            $this->locs[$loc] = array($start, $end);
+            return;
+        }
+        
+        // replace the last line..
+        if (count($this->locs[$loc]) == 2 && $this->locs[$loc][1] == $start) {
+            $this->locs[$loc][1] = $end;
+            print_r($this->locs);
+            return;
+        }
+        // got an array, work out how to maniupulate it..
+        $added = false;
+        for ($i = 0; $i < count($this->locs[$loc]); $i +=2) {
+            $ss = $this->locs[$loc][$i];
+            $ee = $this->locs[$loc][$i+1];
+            echo "CHECK $ee == $start?";
+            
+            if ($ee == $start) {
+                echo "fixed?";
+                $this->locs[$loc][$i+1] = $end;
+                $added = true;
+                break;
+            }
+            
+        }
+        if (!$added) {
+            $this->locs[$loc][] = $start;
+            $this->locs[$loc][] = $end;
+        }
+        
+        sort($this->locs[$loc]);
+        $nl = array();
+        
+        for ($i = 0; $i < count($this->locs[$loc]); $i+=2) {
+            $ss = $this->locs[$loc][$i];
+            $ee = $this->locs[$loc][$i+1];
+            if (empty($nl)) {
+                $nl[] = $ss;
+                $nl[] = $ee;
+                continue;
+            }
+            if ($ss == $nl[count($nl)-1]) {
+                $nl[count($nl)-1] = $ee;
+                
+                continue;
+            }
+            $nl[] = $ss;
+            $nl[] = $ee;
+            
+        }
+        // normalize the list..
+        $this->locs[$loc] = $nl;
+        
+        print_r($this->locs);
+        
+        
+        
+    }
+    
+    
+    
+    
+}
+
+
+
+
diff --git a/Fifo/FixVoids.php b/Fifo/FixVoids.php
new file mode 100644 (file)
index 0000000..58336fa
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_FixVoids extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+    static $cli_desc = "Fill some void records - do not normmally run...";
+   
+    static $permitError = false;
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+        $this->cli = true;
+         
+    }
+    
+    function get()
+    {
+        // set up the failure code..
+        
+        die("not needed any more -- done on HK?? - needs testing on SG??");
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        //DB_DataObject::debugLevel(1);
+        $id = DB_DataObject::Factory('invdetail');
+        $id->autoJoin();
+        $id->selectAdd();
+        $id->selectAdd( 'distinct(invhist_ordnumber) as ordernum');
+        $id->whereAdd(" invhist_transtype ='RS' AND invdetail_qty < 0 and invfifo_void =0 ");
+        $ons = $id->fetchAll('ordernum');
+        print_R($ons);
+        $tot = count($ons);
+        foreach($ons as $n => $oid) {
+            
+            
+            // find the last insue and reverse it..
+            $id = DB_DataObject::Factory('invdetail');
+            $id->autoJoin();
+
+            $id->whereAdd("invhist_ordnumber = '$oid'");
+            $id->whereAdd("invhist_transtype = 'SH' AND invdetail_qty < 0");
+            $id->orderBy('invdetail_id DESC');
+            $id->limit(1);
+            if (!$id->find(true)) {
+                die("not found");
+            }
+            $id->reverse($this,array(
+                '_force' => true
+            ));
+            // now find the one I've just create it and reverse it..
+            $id = DB_DataObject::Factory('invdetail');
+            $id->autoJoin();
+            
+            $id->whereAdd("invhist_ordnumber = '$oid'");
+            $id->whereAdd("invhist_transtype = 'RS' AND invdetail_qty > 0");
+            $id->orderBy('invdetail_id DESC');
+            $id->limit(1);
+            if (!$id->find(true)) {
+                die("not found");
+            }
+            $id->reverse($this,array(
+                '_force' => true
+            ));
+            echo "$n / $tot\n";
+            //print_R($id);exit;
+            //die("done");
+            
+            
+            
+        }
+        
+        die("done");
+        
+        
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessAdjVoids.php b/Fifo/ProcessAdjVoids.php
new file mode 100644 (file)
index 0000000..67272bf
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessAdjVoids extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Flag voids for inventory adjustments.";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        $id = DB_DataObject::Factory('invdetail');
+        $id->autoJoin();
+        $id->whereAdd("invhist_transtype='AD'");
+        
+        $locs = $id->fetchAll('invdetail_id');
+        $id->free();
+        
+        $tot = count($locs);
+        foreach($locs as $n=>$invdetail_id) {
+        
+            $id = DB_DataObject::Factory('invdetail');
+            $id->query("SELECT invfifo_invadj_void_flag($invdetail_id)");
+            $id->free();
+            if (!($n % 50)) {
+                echo "$n/$tot\n";
+            }
+            
+        }
+        
+        die("DONE");
+
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessBase.php b/Fifo/ProcessBase.php
new file mode 100644 (file)
index 0000000..60bc984
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'Pman.php';
+class Pman_Xtuple_Fifo_ProcessBase extends Pman
+{
+     static $permitError = false;
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    function get()
+    {
+    
+        
+                die("base class");
+
+         
+   
+    }
+     
+    function onPearError($err)
+    {
+        static $reported = false;
+        if ($reported) {
+            return;
+        }
+        
+        if (self::$permitError) {
+             
+            return;
+            
+        }
+        
+        
+        // prevent looping
+        $reported = true;
+        $out = $err->toString();
+        
+        
+        //print_R($bt); exit;
+        $ret = array();
+        $n = 0;
+        foreach($err->backtrace as $b) {
+            $ret[] = @$b['file'] . '(' . @$b['line'] . ')@' .   @$b['class'] . '::' . @$b['function'];
+            if ($n > 20) {
+                break;
+            }
+            $n++;
+        }
+        //convert the huge backtrace into something that is readable..
+        $out .= "\n" . implode("\n",  $ret);
+     
+     
+        // email result??
+        echo $out ."\n";
+        exit;
+         
+        
+        
+        
+    }
+}
\ No newline at end of file
diff --git a/Fifo/ProcessBasic.php b/Fifo/ProcessBasic.php
new file mode 100644 (file)
index 0000000..c30a36d
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessBasic extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Fill in basic Fifo values.";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        $id = DB_DataObject::Factory('invdetail');
+        $id->autoJoinLocation();
+        $id->selectAdd();
+        $id->selectAdd('distinct(invdetail_location_id) as location_id, join_location.location_name as location_name');
+        
+        $locs = $id->fetchAll('location_id', 'location_name');
+        $id->free();
+        foreach($locs as $loc=>$name) {
+            
+            $id = DB_DataObject::Factory('invdetail');
+            $id->autoJoin();
+            $id->invdetail_location_id = $loc;
+            $id->selectAdd();
+            $id->selectAdd('distinct(invhist_itemsite_id) as itemsite_id');
+            $is = $id->fetchAll('itemsite_id');
+            $id->free();
+            $tot = count($is);
+            $mu = memory_get_usage();
+            echo "Processing $name ({$tot}) - memory $mu\n";
+            
+            foreach($is as $n=>$itemsite) {
+                $id = DB_DataObject::Factory('invdetail');
+                $id->query("SELECT invfifo_fill_all($loc, $itemsite)");
+                $id->free();
+                if (!($n % 50)) {
+                    echo "$n/$tot\n";
+                }
+            }
+        }
+        
+                die("DONE");
+
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessCoheadVoids.php b/Fifo/ProcessCoheadVoids.php
new file mode 100644 (file)
index 0000000..0a15352
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessCoheadVoids extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Flag voids for coheads.";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        $co = DB_DataObject::Factory('invfifo');
+        
+        $co->selecTAdd();
+        $co->selecTAdd('distinct(invfifo_cohead_id) as cohead_id');
+        $co->whereAdd('
+                        invfifo_void = -1
+                    AND
+                        invfifo_cohead_id > 0
+                       ');
+        $locs = $co->fetchAll('cohead_id');
+        print_R($locs);
+        if (!$locs) {
+            return;
+        }
+            $co = DB_DataObject::Factory('invfifo');
+            
+            $co->query('
+                update
+                    invfifo
+                set
+                    invfifo_void = 0
+                WHERE
+                    invfifo_cohead_id IN (
+                        ' . implode(',', $locs) .'
+                    )
+                '); 
+            
+            
+            //$id = DB_DataObject::Factory('cohead');
+            //$id->query('SELECT invfifo_cohead_void_flag_order(cohead_id) FROM cohead where cohead_id IN ( 
+            //             ' . implode(',', $locs) .'
+            //        )
+            //    ');
+            //   
+            
+        
+        
+        
+       
+        
+         
+        
+        $tot = count($locs);
+
+        foreach($locs as $n=>$cohead_id) {
+        
+            $id = DB_DataObject::Factory('invdetail');
+            $id->query("SELECT invfifo_cohead_void_flag_order($cohead_id)");
+            $id->free();
+            usleep(10);
+            if (!($n % 50)) {
+                sleep(5);
+                echo "$n/$tot\n";
+            }
+            
+        }
+        
+        die("DONE");
+
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessFifoAdjustment.php b/Fifo/ProcessFifoAdjustment.php
new file mode 100644 (file)
index 0000000..faf402b
--- /dev/null
@@ -0,0 +1,415 @@
+<?php
+
+/**
+ * reverse the stock
+ * post adjustment
+ * 
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessFifoAdjustment extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+    static $cli_desc = "Fix Fifo Adjustment.";
+   
+    static $permitError = false;
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    function get()
+    {
+        
+        $this->transObj = DB_DataObject::Factory('invdetail');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        
+        echo "RUN ProcessCoheadvoids and invfifo_apply_gl_cohead_all() before running this\n"; 
+        
+        
+        
+        
+        
+        
+        
+        // check that stuff below is going to wokr.
+        DB_DataObject::Factory('invadjgrp');
+        DB_DataObject::Factory('invadj');
+        
+        $yearperiod = DB_DataObject::factory('yearperiod');
+        $yearperiod->yearperiod_closed = FALSE;
+        $yearperiod->orderBy('yearperiod_start ASC');
+        if(!$yearperiod->find(true)){
+            $this->jerr('All yearperiod have been closed?!');
+        }
+        
+        // find the max invdetail_id
+        $invdetail = DB_DataObject::factory('invdetail');
+        $invdetail->query("SELECT MAX(invdetail_id) AS max FROM invdetail");
+        $invdetail->fetch();
+        $max = $invdetail->max;
+        
+        
+        $period = DB_DataObject::factory('period');
+        $period->whereAdd("
+            period_start >= '{$yearperiod->yearperiod_start}'::date
+        "); 
+        $period->orderBy('period_start ASC');
+        if(!$period->find(true)){
+            $this->jerr("There is no any period in open yearperiod?!");
+        }
+        
+        // temp open period..
+        $tmp = DB_DataObject::factory('period');
+        $tmp->query("SELECT period_temp_open('{$period->period_start}'::DATE) AS v_result");
+        $tmp->fetch();
+        $v_result = $tmp->v_result;
+        
+        //DB_DataObject::debugLevel(1);
+        // fetching all problem order..
+        $cohead = DB_DataObject::factory('cohead');
+        $cohead->whereAdd('cohead_fifo_has_error = true');
+        $cohead->whereAdd("cohead_orderdate < '2013-08-01'");
+        //$cohead->whereAdd("cohead_orderdate > '2013-09-01'");
+       
+        $coheads = $cohead->fetchAll('cohead_id','cohead_number');
+        
+        echo "got coheads\n";
+        //DB_DataObject::debugLevel(1);
+        
+        foreach ($coheads as $cohead_id => $cohead_number){
+            echo "PROCESS $cohead_number \n";
+            
+            $invdetail = DB_DataObject::factory('invdetail');  
+            $invdetail->query("
+                SELECT invfifo_cohead_void_flag_order_force({$cohead_id})  
+            ");
+            
+            $invdetail = DB_DataObject::factory('invdetail');
+            $invdetail->autoJoin();
+            $invdetail->autoJoinItem();
+            $invdetail->selectAdd();
+            $invdetail->selectAdd("
+                invhist_itemsite_id,
+                join_item.item_number as item_number,
+                COALESCE ((SELECT
+                            SUM(COALESCE(coitem_qtyreturned,0))
+                        FROM
+                            coitem
+                        WHERE
+                            coitem_cohead_id = $cohead_id
+                        and
+                            coitem_itemsite_id = invhist_itemsite_id
+                ) ,0) AS rec_returned,
+                COALESCE ((SELECT
+                            SUM(COALESCE(coitem_qtyshipped, 0))
+                        FROM
+                            coitem
+                        WHERE
+                            coitem_cohead_id = $cohead_id
+                        and
+                            coitem_itemsite_id = invhist_itemsite_id
+                ), 0) AS rec_shipped,
+
+                COALESCE(SUM(invdetail_qty),0) as tx_total
+            
+            ");
+            $invdetail->whereAdd("
+                    invhist_ordtype = 'SO'
+                AND
+                    (
+                        invhist_ordnumber LIKE '{$cohead->escape($cohead_number)}' || '-%'
+                        OR
+                        invhist_ordnumber ='{$cohead->escape($cohead_number)}'
+                    )
+            ");
+            $invdetail->groupBy("invhist_itemsite_id, join_item.item_number");
+            
+            $lines = $invdetail->fetchAll();
+            
+            $changes = 0;
+            
+            foreach($lines as $l) {
+                
+                if(($l->rec_returned - $l->rec_shipped) == $l->tx_total){
+                    continue;
+                }
+                echo "Doing cohead_number : $cohead_number , item_number : $l->item_number , itemsite_id : $l->invhist_itemsite_id     $l->rec_returned - $l->rec_shipped  != $l->tx_total \n";
+                
+                // fifo qty does not match..
+//                DB_DataObject::debugLevel(1);
+                $inv = DB_DataObject::factory('invdetail');
+                $inv->autoJoin();
+                $inv->autoJoinItem();
+                
+                $inv->selectAdd("
+                    ROUND(COALESCE((SELECT SUM(  COALESCE(coitem_qtyreturned,0) - COALESCE(coitem_qtyshipped,0) ) from coitem
+                        where coitem_cohead_id = $cohead_id
+                        AND
+                        coitem_linenumber =  SPLIT_PART(SUBSTRING(invhist_ordnumber, " . (strlen($cohead_number) + 2) . "), '.', 1)::INTEGER
+                        AND
+                        coitem_subnumber =   (0 || SPLIT_PART(SUBSTRING(invhist_ordnumber, " . (strlen($cohead_number) + 2) . "), '.', 2))::INTEGER
+                            
+                    ),0),0) AS coitem_shipped,
+                    
+                    (
+                        SELECT 
+                                SUM(COALESCE(invdetail_qty,0)) 
+                        FROM 
+                                invdetailview
+                        WHERE
+                                invdetailview.invhist_ordnumber = join_invhist.invhist_ordnumber
+                    ) AS invhist_qty
+
+                ");
+                
+                $inv->whereAdd("
+                        
+                        invhist_ordtype = 'SO'
+                    AND
+                        (
+                            invhist_ordnumber LIKE '{$cohead->escape($cohead_number)}' || '-%'
+                            OR
+                            invhist_ordnumber ='{$cohead->escape($cohead_number)}'
+                        )
+                    AND
+                        invhist_itemsite_id = $l->invhist_itemsite_id
+                ");
+                $inv->orderBy(" invhist_ordnumber ASC ");
+                
+                $inv->find(); 
+                $reversed = array();
+                while ($inv->fetch()){
+                    
+                    $ori = clone ($inv);
+                    
+                    if(
+                        (
+                            ($ori->invfifo_void != 0 && $ori->coitem_shipped == 0) 
+                            || 
+                            ($ori->invdetail_qty == $ori->coitem_shipped)
+                        )
+                        ||
+                        (in_array($ori->invhist_ordnumber, $reversed))
+                        ||
+                        ($ori->coitem_shipped == $ori->invhist_qty)
+                        
+                    ){
+                       continue;
+                    }
+                    
+                    
+                    $reversed[] = $ori->invhist_ordnumber;
+                    
+                    
+                    $date = $ori->invhist_transdate;
+                    
+                    if(strtotime($ori->invhist_transdate) < strtotime($period->period_start)){
+                        $date = $period->period_start;
+                    }
+
+                    $ori->reverse($this,array('_force' => true, '_return_only' => true, '_as_of' => $date));
+                   
+                    $changes ++;
+                }
+               
+            }
+            
+            if ($changes) {
+                $fifo = DB_DataObject::factory('invdetail');
+                $fifo->query("SELECT invfifo_apply_gl_cohead($cohead_id)");
+            }
+            
+        }
+       
+        //DB_DataObject::DebugLevel(1);
+        
+        $invdetail = DB_DataObject::factory('invdetail');
+        $invdetail->query("SELECT invdetail_location_id FROM invdetail WHERE invdetail_id > $max LIMIT 1");
+        $invdetail->fetch();
+        
+        $loc = $invdetail->invdetail_location_id;
+        
+        if(!$loc){
+            $this->jerr('Nothing to do, exit directly!');
+        }
+        
+        $invdetail = DB_DataObject::factory('invdetail');
+        $invdetail->autoJoin();
+        $invdetail->selectAdd();
+        $invdetail->selectAdd("
+            DISTINCT(join_invhist.invhist_transdate::date) AS transdate
+        ");
+        $invdetail->whereAdd("invdetail_id > $max");
+        $dates = $invdetail->fetchAll('transdate');
+        
+         
+        foreach($dates as $date){
+            $invadjgrp = DB_DataObject::factory('invadjgrp');
+            $invadjgrp->setFrom(array(
+                'invadjgrp_name' => "Magento-June-fix-Adjustment for {$date}",
+                'invadjgrp_transdate' => "$date",
+                'invadjgrp_location_id' => $loc,
+                'invadjgrp_posted' => true,
+                'invadjgrp_comments' => "Reverse affect of Magento import fixes  {$date}",
+                'invadjgrp_void' => false
+            ));
+            $invadjgrp->insert();
+            echo "create invadjgrp for {$date} \n";
+            if(!$invadjgrp->pid()){
+                $this->jerr("insert invadjgrp for {$date} fail");
+            }
+            
+            
+//            DB_DataObject::debugLevel(1);
+            $invdetail = DB_DataObject::factory('invdetail');
+            $invdetail->autoJoin();
+            $invdetail->selectAdd();
+            $invdetail->selectAdd("
+                join_invhist.invhist_itemsite_id AS itemsite_id,
+                SUM(invdetail_qty) AS invdetail_qty
+            ");
+            $invdetail->whereAdd("
+                    invdetail_id > {$max}
+                AND
+                    join_invhist.invhist_transdate::date = '$date'::date
+            ");
+            $invdetail->groupBy('itemsite_id');
+                    
+            if (!$invdetail->find()) {
+                $this->jerr("no items found?");
+            }
+            
+            while ($invdetail->fetch()){
+                
+                
+                $inv = clone ($invdetail);
+                
+                if (!abs($inv->invdetail_qty)) {
+                    continue; //$this->jerr("0 quantity?");
+                }
+                
+                $invadj = DB_DataObject::factory('invadj');
+                $invadj->setFrom(array(
+                    'invadj_transdate' => "$date",
+                    'invadj_location_id' => $loc,
+                    'invadj_itemsite_id' => $inv->itemsite_id,
+                    'invadj_qty_by' => $inv->invdetail_qty * -1,
+                    'invadj_posted' => false,
+                    'invadj_comments' => "Reverse affect of Magento import fixes  {$date}",
+                    'invadj_voids_id' => 0,
+                    'invadj_invdetail_id' => 0, //$inv->invdetail_id, when we post, it will auto set!
+                    'invadj_voided_by_id' => 0,
+                    'invadj_invadjgrp_id' => $invadjgrp->pid()
+                ));
+                //print_r($invadj);
+                $invadj->insert();
+                if(!$invadj->pid()){
+                    $this->jerr("insert invadj fail");
+                }
+                
+            }
+            
+            $invadjgrp->post($this);
+        }
+        
+        if($v_result > 0){
+            $tmp = DB_DataObject::factory('period');
+            $tmp->query("SELECT period_temp_close($v_result)");
+        }
+        
+        // check the stock level at start
+        $invdetail = DB_DataObject::factory('invdetail');
+        $invdetail->_join .= "
+            LEFT JOIN
+                    invhist
+            ON
+                    invdetail_invhist_id = invhist_id
+            LEFT JOIN
+                    invfifo
+            ON
+                    invfifo_invdetail_id = invdetail_id
+        ";
+        $invdetail->selectAdd();
+        $invdetail->selectAdd("
+            invhist_itemsite_id,
+            SUM(invdetail_qty) AS invdetail_qty
+        ");
+        $invdetail->whereAdd("
+                invdetail_location_id = {$loc}
+            AND
+                invdetail_id <= $max
+            AND 
+                invfifo_void = 0
+        ");
+        $invdetail->groupBy('invhist_itemsite_id');
+        
+        $start_stock = $invdetail->fetchAll('invhist_itemsite_id', 'invdetail_qty');
+        
+        // check the stock level at the end
+        $invdetail = DB_DataObject::factory('invdetail');
+        $invdetail->_join .= "
+            LEFT JOIN
+                    invhist
+            ON
+                    invdetail_invhist_id = invhist_id
+            LEFT JOIN
+                    invfifo
+            ON
+                    invfifo_invdetail_id = invdetail_id
+        ";
+        $invdetail->selectAdd();
+        $invdetail->selectAdd("
+            invhist_itemsite_id,
+            SUM(invdetail_qty) AS invdetail_qty
+        ");
+        $invdetail->whereAdd("
+                invdetail_location_id = $loc
+            AND
+                invfifo_void = 0
+        ");
+        $invdetail->groupBy('invhist_itemsite_id');
+        
+        $end_stock = $invdetail->fetchAll('invhist_itemsite_id', 'invdetail_qty');
+       
+        $diff = array();
+        foreach ($end_stock as $key => $value){
+            if(!isset($start_stock[$key])){
+                $diff[] = "$key not set";
+                continue;
+            }
+            
+            $start = isset($error[$key]) ? $error[$key] + $start_stock[$key] : $start_stock[$key];
+            
+            if($start  != $value){
+                $diff[] = "$key , start : $start , end : $value";
+            }
+        }
+        
+        //$this->jerr("canceled");
+        
+        if(count($diff)){
+            $this->jerr("Stock level not correct! \n " . print_r($diff,true));
+        }
+        
+        
+        
+        $this->transObj->query('COMMIT');
+        $this->transObj = false;
+        
+        $this->jok('DONE');
+         
+   
+    }
+     
+    
+}
\ No newline at end of file
diff --git a/Fifo/ProcessGl.php b/Fifo/ProcessGl.php
new file mode 100644 (file)
index 0000000..85214e2
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessGl extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+    static $cli_desc = "Post GL entries.";
+   
+    static $permitError = false;
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        $id = DB_DataObject::Factory('cohead');
+        
+        $locs = $id->fetchAll('cohead_id', 'cohead_number');
+        $id->free();
+        
+        $tot = count($locs);
+        $n=0;
+        foreach($locs as $cohead_id => $cohead_number) {
+        
+            $id = DB_DataObject::Factory('invdetail');
+            echo "SELECT invfifo_apply_gl_cohead($cohead_id)\n";
+            $id->query("SELECT invfifo_apply_gl_cohead($cohead_id) as result");
+            $id->fetch();
+            $res = $id->result;
+            $id->free();
+            echo "DONE $cohead_number - adjust: $res\n";
+            
+            if (!($n % 50)) {
+                echo "$n/$tot\n";
+            }
+            $n++;
+            //if ($n > 50) { exit; }
+        }
+        
+        die("DONE");
+    
+        
+        die("DONE");
+         
+   
+    }
+     
+    
+}
\ No newline at end of file
diff --git a/Fifo/ProcessOldLanded.php b/Fifo/ProcessOldLanded.php
new file mode 100644 (file)
index 0000000..65dbe8d
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessOldLanded extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Move old landed costs to new system.";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // old landed costs where stored in
+        // a) JE in Cost of freight
+        // NE-JE-IR-LANDEDCOST-XXXX-XXXX-IR11216
+        
+        //
+       //DB_DataObject::DebugLevel(1);
+        
+        $curr = DB_DataObject::Factory('curr_symbol')->base();
+        
+        //
+          $accnt = DB_DataObject::Factory('accnt');
+            // ??? 
+        $accnt->whereAdd("accnt_descrip like '%Cost of Freight%'");
+        $ids = $accnt->fetchAll('accnt_id');
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->whereAdd("gltrans_docnumber LIKE 'NS-JE-IR-LANDCOST%'");
+        $all = $gl->fetchAll();
+        $bad = array();
+        foreach($all as $gl) {
+            // try and find the item reciept.
+            //print_R($gl);
+            $m = array();
+            //var_dump($gl->gltrans_notes);
+            preg_match('/Landed cost for (.*)$/', $gl->gltrans_notes, $m);
+            //print_R($m);exit;
+            $ir = $m[1];
+            if (empty($ir)) {
+                echo("NOT FOUND");
+                print_R($gl);exit;
+            }
+            echo "$ir\n";
+            $rg = DB_DataObject::Factory('recvgrp');
+            if (!$rg->get('recvgrp_number', $ir)) {
+                $bad[] = $ir;
+                //print_R($gl);
+                //die("recgrp not found");;
+                continue;
+            }
+            // do we have a record of it..
+            $rgl = DB_DataObject::Factory('recvgrpland');
+            if ($rgl->get('recvgrpland_glseries' , $gl->gltrans_sequence)) {
+                continue;
+            }
+            
+            
+            
+            $rgl = DB_DataObject::Factory('recvgrpland');
+            $rgl->setFrom(array(
+                'recvgrpland_glseries' => $gl->gltrans_sequence,
+                
+                //'recvgrpland_vohead_id' => null
+                'recvgrpland_recvgrp_id' => $rg->pid(),
+                'recvgrpland_date' => $gl->gltrans_date,
+                'recvgrpland_cost' => abs($gl->gltrans_amount),
+                'recvgrpland_curr_id' => $curr->pid(),
+
+                
+            ));
+            $rgl->insert();
+            
+            
+            
+            
+        }
+        print_R($bad);
+        die("DONE");
+        
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessPoheadVoids.php b/Fifo/ProcessPoheadVoids.php
new file mode 100644 (file)
index 0000000..0390cf8
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessPoheadVoids extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Flag voids for poheads.";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        $id = DB_DataObject::Factory('pohead');
+        
+        $locs = $id->fetchAll('pohead_id');
+        $id->free();
+        
+        $tot = count($locs);
+        foreach($locs as $n=>$pohead_id) {
+        
+            $id = DB_DataObject::Factory('invdetail');
+            $id->query("SELECT invfifo_pohead_void_flag_order($pohead_id)");
+            $id->free();
+            if (!($n % 50)) {
+                echo "$n/$tot\n";
+            }
+            
+        }
+        
+        die("DONE");
+
+         
+   
+    }
+     
+}
\ No newline at end of file
diff --git a/Fifo/ProcessValues.php b/Fifo/ProcessValues.php
new file mode 100644 (file)
index 0000000..8400485
--- /dev/null
@@ -0,0 +1,299 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessValues extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+    static $cli_desc = "Fill in Fifo dollar values. - use /BIG to only do the large ones..";
+   
+    static $permitError = false;
+    
+    var $loc_only = false;//187; //false;
+    
+    var $efforts = 10;
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    function get($v = '')
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        
+        // clear up trailing voided coheads..
+        
+       
+        //DB_DataObject::debugLevel(1);
+        $id = DB_DataObject::Factory('invfifo');
+        $id->query("select
+                   distinct(invhist_itemsite_id) as itemsite_id
+                   from
+                   invdetailview
+                   where
+                        ( 
+                                invfifo_cost_before > invfifo_cost_after
+                            OR
+                                invfifo_cost_before < 0
+                            OR
+                                (
+                                    invfifo_cost_before = 0
+                                    and
+                                    invfifo_qty_before > 0
+                                )
+                            OR
+                                (
+                                    -- landed unit cost is zero or negative -- when it's not void..
+                                    
+                                   invfifo_landedunitcost <= 0.0
+                                  
+                                )
+                        )
+                        and
+                            invfifo_void = 0
+            ");
+        
+        $is = array();
+        while ($id->fetch()) {
+            $is[] = $id->itemsite_id ;
+        }
+        if (count($is)) {
+            $id = DB_DataObject::Factory('invfifo');
+            $id->query("delete from invfifopos where invfifopos_itemsite_id IN (". implode(',', $is) .')');
+            
+        }
+        
+        if ($v == 'BAD') {
+            //DB_DAtaObject::debugLevel(1);
+            $this->efforts =10;
+            echo "running process\n";
+            $this->runStandard($is);
+        
+            die("DONE");
+        }
+        
+        
+       if ($v == 'BIG') {
+            //DB_DAtaObject::debugLevel(1);
+            $id = DB_DataObject::Factory('invfifo');
+            
+            $id->query("SELECT invfifopos_itemsite_id FROM invfifopos WHERE invfifopos_lastadjustment != 0.0 ORDER BY invfifopos_lastadjustment ASC");
+            $is = array();
+            while ($id->fetch()) {
+                $is[] = $id->invfifopos_itemsite_id;
+            }
+            $id->free();
+            $this->efforts =10;
+            echo "running process\n";
+            $this->runStandard($is);
+        
+            die("DONE");
+       }
+       
+         
+      
+        if ($v == 'RESET') {
+            $id = DB_DataObject::Factory('invfifo');
+            $id->query("delete from invfifopos");
+            $v = '';
+            
+            
+            
+        }
+       
+       
+       
+        
+        if (!empty($v)) {
+            $this->runSingle($v);
+            die("DONE");
+        }
+        
+          $id = DB_DataObject::Factory('invdetail');
+        $id->autoJoin();
+       
+        $id->selectAdd();
+        $id->selectAdd('distinct(invhist_itemsite_id) as itemsite_id');
+        $id->orderBy('invhist_itemsite_id ASC');
+        if (!empty($this->loc_only)) {
+            $id->invdetail_location_id = $this->loc_only;
+        }
+        
+        $is = $id->fetchAll('itemsite_id');
+        $id->free();
+        
+        //$this->runTest($is);
+        
+        $this->runStandard($is);
+        
+        die("DONE");
+    }
+    function runStandard($is) {
+        $tot = count($is);
+        
+        
+        $start = time();
+        $id = DB_DataObject::Factory('invdetail');
+        $ftot = $id->count();
+        
+        
+        
+        
+        $fdone = 0;
+        foreach($is as $n=>$itemsite) {
+            
+            // before we do fifo calcs make sure the qty's are correct.
+            
+            $id = DB_DataObject::Factory('invdetail');
+            $id->query(" SELECT invfifo_fill_all_itemsite({$itemsite})  ");
+            
+            
+            
+            
+            $id = DB_DataObject::Factory('invdetail');
+            $id->autoJoin();
+            $id->whereAdd("invhist_itemsite_id = $itemsite");
+            $fdone += $id->count(); // 0.09 seconds.
+            $past = array();
+            for($i = 0; $i< $this->efforts ;$i++) {
+                $id = DB_DataObject::Factory('invdetail');
+                
+                
+                $id->query("SELECT invfifo_update_from_invdetail_all($itemsite) as result");
+                $id->fetch();
+                $res= $id->result;
+                $id->free();
+                if (round($res,2) == 0.00 ) {
+                    break;
+                }
+                echo ".... $res\n";
+                $match =0;
+                for ($pp= 0; $pp < min(10, count($past)) ;$pp++) {
+                    if ($past[$pp]  == $res) {
+                        $match++;
+                        continue;
+                    }
+                    break;
+                }
+                if ($match == 10) {
+                    break;
+                }
+                array_unshift($past, $res);
+                
+                
+                
+            }
+            //if (!($n % 10)) {
+                $dur = (time() - $start) / 60;
+                
+                $complete = ((($dur/ $fdone) * $ftot) - $dur) / 60;
+                
+                $mu = memory_get_usage();
+                echo "$itemsite - $n/$tot  $fdone/$ftot  " .
+                    "- Memory - $mu | So far : ". number_format($dur,2)."m | est. complet = ". number_format($complete,2)."hours ($res)\n";
+            //}
+            //sleep(1);
+        }
+    
+        
+        die("DONE");
+         
+   
+    }
+    
+    function runSingle($itemsite )
+    {
+        //DB_DataObject::debugLevel(1);
+        for($i = 0; $i< 50;$i++) {
+            
+            $itemsite = (int)$itemsite;
+            $start = time();
+            $id = DB_DataObject::Factory('invdetail');
+            echo "SELECT invfifo_update_from_invdetail_all($itemsite) as result\n";
+            $id->query("SELECT invfifo_update_from_invdetail_all($itemsite) as result");
+            $id->fetch();
+            echo "GOT $id->result\n";
+            if (round($id->result,2) == 0.00 ) {
+                break;
+            }
+        }
+        exit;
+        
+   
+    }
+    
+    
+    // 226619 -- slow..
+    function runTest($is)
+    {
+        //DB_DataObject::debugLevel(1);
+        $tot = count($is);
+        
+        
+        $start = time();
+        $id = DB_DataObject::Factory('invdetail');
+        $ftot = $id->count();
+        
+        // biggies...
+        //1559 
+
+        
+        $fdone = 0;
+        foreach($is as $n=>$itemsite) {
+            
+           // $itemsite = 1559;
+            
+            $id = DB_DataObject::Factory('invdetail');
+            $id->autoJoin();
+            $id->whereAdd("invhist_itemsite_id = $itemsite AND invfifo_void = 0");
+            $id->orderBy('
+                invhist_transdate ASC,
+                invdetail_id ASC
+            ');
+            
+            $fdone += $id->count();// 0.001 seconds.
+            $id->selectAdd();
+            $id->selectAdd('invdetail_id');
+            $ids = $id->fetchAll('invdetail_id'); // 0.01
+            
+            
+            
+            foreach($ids as $nn=>$i) {
+                $st= microtime(true);
+                $id = DB_DataObject::Factory('invdetail');
+                $id->query("SELECT invfifo_update_from_invdetail($i)");
+                $id->free();
+                if (!($nn % 10)) {
+                    echo "$nn/". count($ids) . "\n";
+                }
+
+                $totals[$i] = microtime(true) - $st;
+               //if ($nn > 500) break;
+            }
+            asort($totals);
+            print_r($totals);
+            exit;
+            
+        }
+    
+        
+        die("DONE");
+         
+   
+    }
+    
+}
\ No newline at end of file
diff --git a/Fifo/ProcessValuesWalk.php b/Fifo/ProcessValuesWalk.php
new file mode 100644 (file)
index 0000000..fb758cf
--- /dev/null
@@ -0,0 +1,238 @@
+<?php
+
+
+/**
+ *
+ * Idea is to test the walking through of a sequence
+ * to see if we can work out a method of ordering the calculations.
+ *
+ *
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ProcessValuesWalk extends  Pman_Xtuple_Fifo_ProcessBase
+
+{
+  
+    static $cli_desc = "Fill in Fifo dollar values.";
+   
+    static $permitError = false;
+    
+    var $loc_only = false;//187; //false;
+    
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+         
+    }
+    
+    
+    
+    function get($v)
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+        
+      
+        
+        
+        if (!empty($v)) {
+            $this->runSingle($v);
+            die("DONE");
+        }
+        
+        die("single only");
+    }
+    
+    function runSingle($itemsite )
+    {
+        // DB_DataObject::debugLevel(1);
+         
+        $itemsite = (int)$itemsite;
+        $start = time();
+        
+        
+          $id = DB_DataObject::Factory('invdetail');
+        
+        
+        
+        
+        $id->query("SELECT
+       
+                  count(invdetail_id) as nres
+            FROM 
+                    
+                  invdetailview
+          WHERE
+              invhist_itemsite_id = $itemsite
+              AND
+              invfifo_void = 0
+              
+        ");
+        $id->fetch();
+        
+        $total = $id->nres;
+        
+        //exit;
+        $id = DB_DataObject::Factory('invdetail');
+        $id->query("SELECT
+                        *
+                    FROM
+                      
+                invdetailview
+            WHERE
+                invhist_itemsite_id =  {$itemsite}
+                AND
+                invfifo_void = 0
+                AND
+                (
+                    invhist_transtype = 'RP'
+                    OR
+                    invhist_transtype = 'AD'
+                    OR
+                    invhist_transtype = 'RS'
+                ) AND
+                    invdetail_qty > 0
+                    
+            ORDER BY
+         
+                invhist_transdate ASC,
+                invdetail_id ASC
+            
+        ");
+       
+        while ($id->fetch()) {
+            $all[] = clone($id);
+        }
+        $done = array();
+        foreach($all as $id) {
+            $idr = DB_DataObject::Factory('invdetail');
+            $idr->query("SELECT invfifo_update_from_invdetail({$id->invdetail_id},true)");
+            
+            $done[] = $id->invdetail_id;
+            // fill in all outgoing based on these reciepts..
+            
+            
+            $done = array_unique(array_merge($done, $this->processOut($id, $done)));
+            
+            
+        }
+        echo "DONE : ". count($done) . " out of $total \n";
+        //print_R($done);
+    
+        exit;
+        
+        print_R($all);
+        
+        // pass 1 - incomming stock only..
+        // pass 2 - 
+        
+        
+        $locs = array();
+        while (true) {
+            $id = array_shift($all);
+            switch($id->invhist_transtype) {
+                case 'AD': // adjustment
+                    
+                
+                
+            }
+            exit;
+            
+            
+            
+            
+        }
+        
+        
+           
+        
+        exit;
+        
+   
+    }
+    
+    function processOut($idr, $done= array())
+    {
+        if (empty($done)) {
+            $done = array(0);
+        }
+      
+        $id = DB_DataObject::Factory('invdetail');
+        
+        
+        
+        
+        $id->query("SELECT
+       
+              *
+                FROM
+                    
+              invdetailview
+          WHERE
+              invhist_itemsite_id =  {$idr->invhist_itemsite_id}
+              AND
+              invfifo_void = 0
+              AND
+              invdetail_qty < 0
+              AND
+              invfifo_qty_before >= {$idr->invfifo_qty_before}
+              AND
+              invfifo_qty_before <= {$idr->invfifo_qty_after}
+              AND
+              invdetail_location_id = {$idr->invdetail_location_id}
+             
+             
+             AND
+             invdetail_id NOT IN (". implode(',', $done) . ") 
+          ORDER BY
+       
+              invhist_transdate ASC,
+              invdetail_id ASC
+          
+        ");
+        $all = array();
+        while($id->fetch()) {
+            $all[] = clone($id);
+            $ret[] = $id->invdetail_id;
+        }
+       // $done = array();
+        foreach($all as $id) {
+            $idr = DB_DataObject::Factory('invdetail');
+            $idr->query("SELECT invfifo_update_from_invdetail({$id->invdetail_id},true)");
+            $done[] = $id->invdetail_id;
+            
+            // if it's a transfer, then flag the reverse as done as well..
+            if ($id->invhist_transtype == 'RL') {
+                $idr = DB_DataObject::Factory('invdetail');
+                $idr->query("SELECT *
+                                FROM invdetailview WHERE invdetail_invhist_id = {$id->invhist_id} AND invdetail_id != {$id->invdetail_id}
+                            ");
+                $idr->fetch();
+                $done[] = $idr->invdetail_id ;
+                $done = array_unique(array_merge($this->processOut($idr , $done)));
+                
+                
+            }
+            
+            
+        }
+        return $done;
+        
+        
+        
+    }
+    
+}
+
+
diff --git a/Fifo/ResetVoids.php b/Fifo/ResetVoids.php
new file mode 100644 (file)
index 0000000..2429420
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * fill in any fifo basic entries that have not been processed..
+ * -- does not fill in values.. - just qty's
+ *
+ */
+require_once 'ProcessBase.php';
+class Pman_Xtuple_Fifo_ResetVoids extends Pman_Xtuple_Fifo_ProcessBase
+{
+     static $cli_desc = "Resets all voids flags. - do not run if you do not know what you are doing!";
+   
+    static $permitError = false;
+    
+   
+    function get()
+    {
+        // set up the failure code..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // we have to have a pointer to work out where we left off..
+        // this process can go by invdetail_id ASC..
+        
+       
+        
+        $id = DB_DataObject::Factory('invdetail');
+        $id->query("UPDATE invfifo set invfifo_void = 0 where invfifo_void !=0");
+        $id->free();
+        
+            
+        
+        
+        die("DONE");
+
+        
+    }
+     
+}
\ No newline at end of file
diff --git a/Import/AUPostAccounts.php b/Import/AUPostAccounts.php
new file mode 100644 (file)
index 0000000..5c4b2a4
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_AUPostAccounts extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('custinfo');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $req = array('CUSTOMER', 'ACCOUNT NO.');
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        
+        $missing = array();
+        foreach ($rows as $row){
+            if(empty($row['CUSTOMER']) || empty($row['ACCOUNT NO.'])){
+                continue;
+            }
+            $custinfo = DB_DataObject::factory('custinfo');
+            if(!$custinfo->get('cust_name',$row['CUSTOMER'])){
+                $missing[] = $row['CUSTOMER'];
+                continue;
+            }
+            
+            $ca = DB_DAtaObject::factory('charass');
+            $ca->query("SELECT
+                    charass_setvalue(
+                       'C',{$custinfo->pid()},
+                       'AU-POST-ACCNO', '{$row['ACCOUNT NO.']}'
+                    );");
+            
+        }
+        
+        $this->jok('data imported successfully! <br/> Missing : <br/>' . implode("<br/>", $missing));
+        
+        
+        exit;
+    }
+}
diff --git a/Import/AUPurchaseOrder.php b/Import/AUPurchaseOrder.php
new file mode 100644 (file)
index 0000000..7d535f4
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_AUPurchaseOrder extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('poitem');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $pohead_id = $_REQUEST['pohead_id'];
+        
+        $req = array('ITEM', 'ITEM DESCRIPTION', 'ON HAND', 'AVG COST');
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if(!array_filter($n)){ // empty row
+                continue;
+            }
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        
+        //print_R($rows);exit;
+        
+        // check pohead
+        $pohead = DB_DataObject::factory('pohead');
+        if(!$pohead->get($pohead_id)){
+            $this->jerr('error occur on finding pohead');
+        }
+        
+        $max_num = 0;
+        $poitem = DB_DataObject::factory('poitem');
+        $poitem->selectAdd();
+        $poitem->selectAdd("
+            MAX(poitem_linenumber) as max_num
+        ");
+        $poitem->poitem_pohead_id = $pohead->pid();
+        $poitem->find(true);
+        if(!empty($poitem->max_num)){
+            $max_num = $poitem->max_num;
+        }
+        
+        $missing = array();
+        foreach ($rows as $i => $row){
+            if (empty($row['ON HAND']) || $row['ON HAND'] < 1) {
+                continue;
+            }
+            if(empty($row['ITEM'])){
+                unset($rows[$i]);
+                continue;
+            }
+            
+            $item = DB_DataObject::factory('item')->lookupSKU($row['ITEM']);
+            
+            if(!$item){
+                
+                $missing[] = $row['ITEM']  . ' does not exist';
+                continue;
+            }
+            
+            $itemsite = DB_DataObject::factory('itemsite');
+            if(!$itemsite->get('itemsite_item_id', $item->pid())){
+                $missing[] = $row['ITEM'] . ' does not exist in item site';
+                continue;
+            }
+            $rows[$i]['ITEMSITE ID'] = $itemsite->pid();
+            
+        }
+        
+        if(count($missing)){
+            $this->jerr(implode("\n", $missing));
+        }
+        
+        foreach($rows as $i => $row){
+            // create poitem
+             if (empty($row['ON HAND']) || $row['ON HAND'] < 1) {
+                continue;
+            }
+            
+            $poitem = DB_DataObject::factory('poitem');
+            $poitem->setFrom(array(
+                'poitem_status' => $pohead->pohead_status,
+                'poitem_pohead_id' => $pohead->pid(),
+                'poitem_linenumber' => $max_num + ($i + 1),
+                'poitem_duedate' => date('Y-m-d'),
+                'poitem_itemsite_id' => $row['ITEMSITE ID'],
+                'poitem_qty_ordered' => $row['ON HAND'],
+                'poitem_unitprice' => $row['AVG COST'],
+                'poitem_itemsrc_id' => $poitem->sqlValue('NULL') 
+            ));
+            
+            foreach($poitem->defaults() as $k => $v){
+                if (!isset($poitem->$k)) {
+                    $poitem->$k = $v;
+                }
+            }
+            
+            $poitem->insert();
+            
+            if(!$poitem->pid()){
+                $this->jerr('error occur on insert poitem ' . $row['ITEM CODE']);
+            }
+            
+        }
+        $this->jok('IMPORTED');
+        
+        exit;
+    }
+}
diff --git a/Import/CreditMemo.php b/Import/CreditMemo.php
new file mode 100644 (file)
index 0000000..b012bff
--- /dev/null
@@ -0,0 +1,190 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_CreditMemo extends Pman_Roo
+{
+    
+    /**
+     *  get .. same as roo... 
+     * 
+     */
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    
+    function get()
+    {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        $this->jerr("INVALID");
+        //DB_DataObject::DebugLevel(1);
+        require_once 'File/Convert.php';
+        $fc = new File_Convert('/tmp/sku.csv', 'text/csv');
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    
+    function post( )
+    {
+        
+        $this->sessionState(0); // turn off the session..
+        
+        $this->transObj = DB_DataObject::Factory('custinfo');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        if (empty($_REQUEST['onid'])) {
+            $this->jerr('no order found');
+            
+        }
+        
+         
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    function importCsv($csv)
+    {
+        
+        ini_set("auto_detect_line_endings", true);
+
+        $req = array('ITEM CODE', 'QTY', 'PRICE');
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        // we need to break this into cols..
+        $cols = false;
+        $rows = array();
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+             
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                if (empty($cols)) {
+                    continue;
+                }
+                
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                        
+                    }
+                }
+                continue;
+            }
+            $row = array();
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+         
+        if (empty($cols)) {
+            $this->jerr("could not find a row with Item Code, Qty and Price");
+        }
+        fclose($fh);
+        
+        
+        $cmhead = DB_DataObject::Factory('cmhead');
+        if (!$cmhead->get($_REQUEST['onid'])) {
+            $this->jerr("order is not valid");
+        }
+        
+        //DB_DataObject::debugLevel(1);
+        $missing = array();
+        
+        foreach($rows as $row)
+        {
+            if (!strlen(trim(implode('', array_values($row))))) {
+                continue;
+            }
+            if (!strlen(trim($row['ITEM CODE']))) {
+                $missing[]  = implode('', array_values($row));
+            }
+            
+            
+            $item = DB_DataObject::factory('item')->lookupSKU($row['ITEM CODE']);
+            
+            if (!$item) {
+                $missing[] = $row['ITEM CODE'];
+                continue;
+            }
+            if (!empty($missing)) {
+                continue;
+            }
+            
+            $citem = DB_DataObject::Factory('cmitem');
+            $citem->setFrom($citem->defaults());
+            $citem->setFrom(array(
+                'cmitem_cmhead_id' => $cmhead->pid(),
+                'cmitem_itemsite_id' => $item->itemsite()->pid(),
+                'cmitem_qtycredit' => $row['QTY'],
+                'cmitem_qtyreturned' => $row['QTY'],
+                'cmitem_unitprice' => $row['PRICE'],
+                'cmitem_comments' => $item->item_descrip1,
+                'cmitem_linenumber' => $this->nextline($cmhead)
+                
+            ));
+            $citem->insert();
+            
+        }
+        if (!empty($missing)) {
+            $this->jerr("missing these codes : " . implode("\n", $missing));
+        }
+        
+        $this->jok("IMPORTED");
+         
+    
+    }
+    
+    
+    function nextline($cmhead)
+    {
+        static $line = false;
+        if ($line !== false) {
+            $line++;
+            return $line;
+        }
+        $t = DB_DataObject::Factory('cmitem');
+        $t->selectAdd();
+        $t->cmitem_cmhead_id = $cmhead->pid();
+        $t->selectAdd('MAX(cmitem_linenumber) as cmitem_linenumber');
+        if (!$t->find(true)) {
+            $line = 1;
+            return $line;
+        }
+        $line = $t->cmitem_linenumber +1;
+        return $line;
+    }
+        
+        
+        
+         
+}
+   
\ No newline at end of file
diff --git a/Import/Customers.php b/Import/Customers.php
new file mode 100644 (file)
index 0000000..207865d
--- /dev/null
@@ -0,0 +1,311 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_Customers extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('vendinfo');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $req = array(
+            'ACTIVE STATUS', 'CUSTOMER', 'BALANCE', 'BALANCE TOTAL', 'COMPANY', 'MR, MRS',
+            'FIRST NAME', 'M.I.', 'LAST NAME', 'CONTACT', 'PHONE', 'FAX', 'ALT. PHONE', 'ALT. CONTACT', 'EMAIL', 'BILL TO 1',
+            'BILL TO 2', 'BILL TO 3', 'BILL TO 4', 'BILL TO 5', 'SHIP TO 1', 'SHIP TO 2', 'SHIP TO 3', 'SHIP TO 4', 'SHIP TO 5',
+            'CUSTOMER TYPE', 'TERMS', 'REP', 'TAX CODE', 'RESALE NUM', 'ACCOUNT NO.', 'CREDIT LIMIT', 'JOB STATUS', 'JOB TYPE',
+            'JOB DESCRIPTION', 'START DATE', 'PROJECTED END', 'END DATE', 'NOTE'
+        );
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        
+        $tz = DB_DataObject::Factory('taxzone');
+        $tz->whereAdd("taxzone_code != 'NO TAX'");
+        if (!$tz->find(true)) {
+            $this->jerr("could not find tax zone for taxable");
+        }
+        
+        
+        foreach ($rows as $row){
+            $custinfo = DB_DataObject::factory('custinfo');
+            if(empty($row['COMPANY'])){
+                continue;
+            }
+            $checkTerms = true;
+            if(!$custinfo->get('cust_name', $row['COMPANY'])){ // customer not exist
+                $custinfo->setFrom(array(
+                    'cust_active'       => $row['ACTIVE STATUS'] == 'Active' ? TRUE : FALSE,
+                    'cust_salesrep_id'  => $this->salesrep($row['REP']),
+                    'cust_name'         => $row['COMPANY'],
+                    'cust_number'       => str_replace(' ', '', strtoupper($row['COMPANY'])),
+                    'cust_creditlmt'    => empty($row['CREDIT LIMIT']) ? 0 : $row['CREDIT LIMIT'],
+                    'cust_terms_id'     => $this->terms($row['TERMS']),
+                    'cust_taxzone_id'   => $tz->pid()
+                ));
+                
+                
+                foreach($custinfo->defaults() as $k=>$v) {
+                    if (!isset($custinfo->$k)) {
+                        $custinfo->$k = $v;
+                    }
+                }
+
+                $custinfo->insert();
+                
+                $checkTerms = false;
+            }
+            
+            if(!$custinfo->pid()){
+                $this->jerr("error occur on insert customer " . $row['COMPANY']);
+            }
+            
+            // check the terms
+            if($checkTerms){
+                $terms_id = $this->terms($row['TERMS']);
+                if($custinfo->cust_terms_id  != $terms_id){
+                    $oldcust = clone($custinfo);
+                    $custinfo->cust_terms_id = $terms_id;
+                    $custinfo->update($oldcust);
+                }
+            }
+            
+            // check cntct and update cust_cntct_id
+            $cntct = DB_DataObject::factory('cntct');
+            if(empty($row['FIRST NAME']) && empty($row['LAST NAME'])){
+                $row['FIRST NAME'] = $row['CONTACT'];
+                
+                if(empty($row['CONTACT'])){
+                    $row['FIRST NAME'] = $row['CUSTOMER'];
+                }
+                
+            }
+           
+            $c = array(
+                'cntct_first_name'  => empty($row['MR, MRS']) ? $row['FIRST NAME'] : $row['MR, MRS'] . ' ' . $row['FIRST NAME'],
+                'cntct_last_name'   => $row['LAST NAME'],
+                'cntct_active'      => 1,
+                'cntct_phone'       => $row['PHONE'],
+                'cntct_fax'         => $row['FAX'],
+                'cntct_email'       => $row['EMAIL'],
+                'cntct_notes'       => $row['NOTE'],
+                'cntct_crmacct_id'  => $cntct->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$custinfo->pid()})")
+            );
+            $c['cntct_name'] = empty($c['cntct_last_name']) ? $c['cntct_first_name'] : $c['cntct_first_name'] . ' ' . $c['cntct_last_name'];
+            if(!$cntct->get('cntct_name', $c['cntct_name'])){
+                $cntct = $cntct->createFromArray($c);
+            }
+            if(!$cntct->pid()){
+                $this->jerr("error occur on insert cntct " . $row['CUSTOMER']);
+            }
+            
+            
+            if(!$cntct->cntct_addr_id){
+                $addrs = $this->addrValue($row);
+                $addr = DB_DataObject::Factory('addr');
+                $addr->createFromArray($addrs);
+                
+                if(!$addr->pid()){
+                    $this->jerr("error occur on insert address " . $row['CUSTOMER']);
+                }
+
+                $oldcn = clone($cntct);
+                $cntct->cntct_addr_id = $addr->pid();
+                $cntct->update($oldcn);
+            }
+            
+            if(!$custinfo->cust_cntct_id){
+                $oldcust = clone($custinfo);
+                $custinfo->cust_cntct_id = $cntct->pid();
+                $custinfo->update($oldcust);
+            }
+            
+            // fetch all cntct id to update the shipment list
+            $cn = DB_DataObject::factory('cntct');
+            $cn->whereAdd("
+                cntct_crmacct_id = (SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$custinfo->pid()})
+            ");
+            $list = $cn->fetchAll('cntct_id');
+            
+            $custinfo->updateShipList($list);
+            
+        }
+        
+        $this->jok("DONE");
+        
+        exit;
+    }
+    
+    /*
+     * use default salesrep accounts if the code does not exist
+     */
+    function salesrep($salesrep_name)
+    {
+        $salesrep = DB_DataObject::factory('salesrep');
+        if(!$salesrep->get('salesrep_name', $salesrep_name)){
+            $salesrep->get('salesrep_name', 'accounts');
+        }
+        return $salesrep->pid();
+        
+    }
+    
+    /*
+     * use default terms C.O.D. if the code does not exist
+     */
+    function terms($t)
+    {
+        $terms = DB_DataObject::factory('terms');
+        $terms->whereAdd("
+            terms_code ILIKE '%{$terms->escape($t)}%'
+            OR
+            terms_descrip ILIKE '%{$terms->escape($t)}%'
+        ");
+        if($terms->find(true)){
+            return $terms->pid();
+        }
+        
+        $terms->setFrom(array(
+            'terms_code' => strtoupper($t),
+            'terms_descrip' => $t,
+            'terms_type' => 'D',
+            'terms_duedays' => 0,
+            'terms_discprcnt' => 0,
+            'terms_cutoffday' => 0,
+            'terms_ap' => TRUE,
+            'terms_ar' => TRUE 
+        ));
+        $terms->insert();
+        
+        if(!$terms->pid()){
+            $this->jerr("error occur on insert a terms " . $t);
+        }
+        
+        return $terms->pid();
+    }
+    
+    function addrValue($row)
+    {
+        $australiaStates = array(
+            'ACT'   => 'Australian Capital Territory',
+            'JBT'   => 'Jervis Bay Territory',
+            'NSW'   => 'New South Wales',
+            'NT'    => 'Northern Territory',
+            'QLD'   => 'Queensland',
+            'SA'    => 'South Australia',
+            'TAS'   => 'Tasmania',
+            'VIC'   => 'Victoria',
+            'WA'    => 'Western Australia'
+        );
+        $address = array(
+            'SHIP TO 5' => '',
+            'SHIP TO 4' => '',
+            'SHIP TO 3' => 'addr_line3', 
+            'SHIP TO 2' => 'addr_line2',
+            'SHIP TO 1' => 'addr_line1'
+        );
+        
+        $city = '';
+        $state = '';
+        $postalcode = '';
+
+        foreach (array_keys($address) as $a){
+            if(empty($row[$a])){
+                unset($address[$a]);
+                continue;
+            }
+            foreach ($australiaStates as $k => $v){
+                if(!preg_match("/{$k}\s{0,}[0-9]{0,}$/", $row[$a])){
+                    continue;
+                }
+                $city = trim(preg_replace("/{$k}\s{0,}[0-9]{0,}$/", '', $row[$a]));
+                
+                $postalcode = trim(preg_replace("/{$city}/", '', $row[$a]));
+                
+                $state = $v;
+            }
+            unset($address[$a]);
+            break;
+        }
+
+        foreach ($address as $k => $v){
+            if(empty($v)){
+                $row['SHIP TO 3'] = implode(' ', array($row['SHIP TO 3'], $row['SHIP TO 4']));
+            }
+        }
+        $addrs = array(
+            'addr_active'       => 1,
+            'addr_line1'        => isset($address['SHIP TO 1']) ? $row['SHIP TO 1'] : '',
+            'addr_line2'        => isset($address['SHIP TO 2']) ? $row['SHIP TO 2'] : '',
+            'addr_line3'        => isset($address['SHIP TO 3']) ? $row['SHIP TO 3'] : '',
+            'addr_city'         => $city,
+            'addr_state'        => $state,
+            'addr_postalcode'   => $postalcode
+        );
+        
+        return $addrs;
+    }
+}
diff --git a/Import/ExpCat.php b/Import/ExpCat.php
new file mode 100644 (file)
index 0000000..065eb19
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_ExpCat extends Pman_Roo
+{
+    
+    /**
+     *  get .. same as roo... 
+     * 
+     */
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        die("access denied");
+    }
+    
+    
+    function get()
+    {
+         DB_DAtaObject::debugLevel(1);
+         $ep = DB_DataObject::Factory('expcat');
+         $ep->autoGenerateFromAccounts($this);
+         die("done"); 
+    }
+    
+     
+    
+}
diff --git a/Import/Flrpt.php b/Import/Flrpt.php
new file mode 100644 (file)
index 0000000..d610b0c
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_Flrpt extends Pman_Roo
+{
+    
+    static $cli_desc = "Copy reports from hk office to other offices...";
+   
+    
+   
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get($flhead_id)
+    {
+        if (empty($flhead_id)) {
+            print_r(json_decode( file_get_contents('http://localhost/dragon/hk.php/Roo/flhead?_columns=flhead_id,flhead_name')));
+            
+            $this->jerr("pick an available report");
+        }
+        
+        $this->transObj = DB_DataObject::Factory('gltrans');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        // sandobx or live???
+        $url = 'http://localhost/dragon/hk.php/Roo/Flhead?flhead_id='.$flhead_id.'&_to_json=1';
+        $res = json_decode(file_get_contents($url),true);
+        
+        if(count($res['data']) < 1) {
+            $this->jerr('no data found');
+        }
+        //$res['data']['flhead_name'] = 'TESTING';
+        $flhead = DB_DataObject::factory('flhead');
+        if($flhead->get('flhead_name' , $res['data']['flhead_name'])){
+            $this->jerr('flhead already exists');
+        }
+        
+        $flhead->setFrom($res['data']);
+        $flhead->insert();
+        
+        if(!$flhead->pid()){
+            $this->jerr('error occur on insert flhead');
+        }
+        if(!count($res['data']['groups'])){
+            $this->jerr('no groups found');
+        }
+        $grp = $res['data']['groups'];
+        $this->walkgrp($grp, $flhead->pid());
+        
+        if(count($res['data']['col'])){
+            $this->walkcol($res['data']['col'], $flhead->pid());
+        }
+        
+         $this->transObj->query('COMMIT');
+        
+        exit;
+    }
+    
+    function walkgrp($grp, $hid, $pargrp = '-1')
+    {
+        foreach($grp as $g){
+            $g['flgrp_flhead_id'] = $hid;
+            if($g['flgrp_flgrp_id'] > 0){ // get and parent
+                $g['flgrp_flgrp_id'] = $pargrp;    
+            }
+            $flgrp = DB_DataObject::factory('flgrp');
+            $flgrp->setFrom($g);
+            $flgrp->insert();
+            
+            if(!$flgrp->pid()){
+                $this->jerr('error occur on insert group : ' . $g['flgrp_name']);
+            }
+            
+            if(count($g['items'])){
+                $this->walkitem($g['items'], $hid, $flgrp->pid());
+            }
+            
+            if(count($g['groups'])){
+                $this->walkgrp($g['groups'], $hid, $flgrp->pid());
+            }
+        }
+        
+    }
+    
+    function walkitem($item, $hid, $gid)
+    {
+        foreach($item as $i){
+            $i['flitem_flhead_id'] = $hid;
+            $i['flitem_flgrp_id'] = $gid;
+            $flitem = DB_DataObject::factory('flitem');
+            $flitem->setFrom($i);
+            $flitem->insert();
+        }
+    }
+    
+    function walkcol($col, $hid)
+    {
+        foreach($col as $c){
+            if(!count($c['report'])){
+                $this->jerr('Missing report details');
+            }
+            $report = DB_DataObject::factory('report');
+            
+            if(!$report->get('report_name', $c['report']['report_name'])){
+                $report->setFrom($c['report']);
+                $report->insert();
+            }
+            
+            if(!$report->pid()){
+                $this->jerr('error occur on insert report : ' . $c['report']['report_name']);
+            }
+            
+            $c['flcol_flhead_id'] = $hid;
+            $c['flcol_report_id'] = $report->pid();
+            $flcol = DB_DataObject::factory('flcol');
+            $flcol->setFrom($c);
+            $flcol->insert();
+        }
+    }
+}
diff --git a/Import/InvAdjustment.php b/Import/InvAdjustment.php
new file mode 100644 (file)
index 0000000..d7f0e39
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_InvAdjustment extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('invadjgrp');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $ret = $this->importCsv($csv);
+        
+        $this->jdata($ret);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $invadjgrp_id = $_REQUEST['invadjgrp_id'];
+        
+        if(!$invadjgrp_id || $invadjgrp_id < 1){
+            $this->jerr('invalid invadjgrp id');
+        }
+        
+        $grp = DB_DataObject::factory('invadjgrp');
+        if(!$grp->get($invadjgrp_id)){
+            $this->jerr('error occur on getting invadjgrp');
+        }
+        
+        if($grp->invadjgrp_posted){
+            $this->jerr('Can not update posted');
+        }
+        
+        $req = array('CODE', 'QTY');
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        
+        $errmsg = array();
+        $ret = array();
+        
+        $done = array();
+        
+        foreach ($rows as $row){
+            if (empty($row['CODE'])) {
+                continue;
+            }
+            
+            $item = DB_DataObject::factory('item');
+            $item = $item->lookupSKU($row['CODE']);
+            if (!$item) {
+                $errmsg[] = $row['CODE'];
+                continue;
+            }
+            if (isset($done[$item->item_number])) {
+                continue; // dupes.
+            }
+            $done[$item->item_number] = 1; 
+            //DB_DataObject::debugLevel(1);
+            $itemsite = $item->itemsite();
+            
+            
+            $invdetail = DB_DataObject::factory('invdetail');
+            $invdetail->query("
+                    SELECT
+                        ROUND(
+                            COALESCE(
+                                invdetail_atdate(
+                                    '{$grp->invadjgrp_transdate}'::date + INTERVAL '1 DAY',
+                                    {$grp->invadjgrp_location_id},
+                                    {$itemsite->pid()}
+                                )
+                            , 0)
+                        ,0)
+                    AS stock_balance
+            ");
+            $invdetail->fetch();
+            
+            $balance = $invdetail->stock_balance;
+            
+            $ret[] = array(
+                'item_number' => $item->item_number,
+                'itemsite_id' => $itemsite->pid(),
+                'balance' => $balance,
+                'qty' => $row['QTY']
+            );
+
+            
+//            $invadj = DB_DataObject::factory('invadj');
+//            $invadj->setFrom(array(
+//                'invadj_transdate' => $grp->invadjgrp_transdate,
+//                'invadj_location_id' => $grp->invadjgrp_location_id,
+//                'invadj_itemsite_id' => $itemsite->pid(),
+//                'invadj_qty_by' => $adj,
+//                'invadj_posted' => FALSE,
+//                'invadj_comments' => $grp->invadjgrp_comments,
+//                'invadj_voids_id' => 0,
+//                'invadj_voided_by_id' => 0,
+//                'invadj_invadjgrp_id' => $grp->pid()
+//            ));
+//            if(!$invadj->insert()){
+//                $this->jerr("Error occur on insert adjustment for {$row['CODE']}");
+//            }
+            
+        }
+        
+        if(count($errmsg)){
+            $this->jerr("MISSING ITEM : \n" . implode("\n", $errmsg));
+        }
+        
+        return $ret;
+    }
+}
diff --git a/Import/JournalEntry.php b/Import/JournalEntry.php
new file mode 100644 (file)
index 0000000..4d7abf5
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_JournalEntry extends Pman_Roo
+{
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+   
+    function post()
+    {   
+        $this->transObj = DB_DataObject::Factory('gltrans');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->adjustBalances($csv);
+        
+    }
+    
+    function adjustBalances($csv)
+    {
+        
+        ini_set("auto_detect_line_endings", true);
+        
+        $reference = $_REQUEST['reference'];
+        $apply_date = $_REQUEST['apply_date'];
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                
+                if (!in_array('ADJUST',$cols)) {
+                    $this->jerr('Missing ADJUST value : ' . implode(' , ' , $cols));
+                
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            // ignore the accnt if the adjust is 0
+            if (empty($row['ADJUST']) || $row['ADJUST'] == 0) {
+                continue;
+            }
+            $rows[] = $row;
+        }
+        
+        fclose($fh);
+        $gl = DB_DataObject::factory('gltrans');
+        $gl->query("
+            SELECT 
+                fetchGLSequence() 
+            AS
+                glsequence
+        ");  $gl->fetch();
+         $seq = $gl->glsequence;       // v_glsequence
+        foreach ($rows as $i => $row){
+            if(empty($row['NAME'])){
+                continue;
+            }
+            $accnt = DB_DataObject::factory('accnt');
+            if(!$accnt->get('accnt_name', $row['NAME'])){
+                continue;
+            }
+            
+            $gl = DB_DataObject::factory('gltrans');
+            $gl->query("
+                SELECT
+                    insertIntoGLSeries(
+                         $seq,
+                        'G/L',
+                        'JE',
+                        '{$gl->escape($reference)}',
+                        {$accnt->pid()},
+                        {$row['ADJUST']},
+                        '$apply_date'::date
+                    ) 
+                AS
+                    result
+            ");
+            $gl->fetch();
+            if ($gl->result < 1) {
+                $this->jerr("insertIntoGLSeries INV ASS failed");
+            }
+        }
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("SELECT sum(glseries_amount) as result FROM glseries WHERE  glseries_sequence = $seq ");
+        $gl->fetch();
+        $sum = $gl->result; // the type here is string
+        
+        if(abs($sum) > 1.0){
+            $this->jerr('glseries amount is greater than 1.0');
+        }
+        
+        if($sum != 0){
+            $rounding = $sum * -1;
+            $gl = DB_DataObject::factory('gltrans');
+            $gl->query("
+                SELECT
+                    insertIntoGLSeries(
+                         $seq,
+                        'G/L',
+                        'JE',
+                        '{$gl->escape($reference)}',
+                        fetchMetricValue('CurrencyGainLossAccount')::integer, 
+                        {$rounding},
+                        '$apply_date'::date
+                    ) 
+                AS
+                    result
+            ");
+            $gl->fetch();
+            if ($gl->result < 1) {
+                $this->jerr("rounding insertIntoGLSeries failed");
+            }
+        }
+
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("
+            UPDATE 
+                glseries
+            SET 
+                glseries_notes = '{$gl->escape($reference)}'
+            WHERE
+                glseries_sequence = $seq
+        ");
+                
+        $gl = DB_DataObject::Factory('gltrans');
+        $gl->query("
+            SELECT
+                postGLSeriesNoSumm(
+                    $seq,
+                    COALESCE(NULL,fetchJournalNumber('G/L'))
+                ) 
+            AS 
+                result
+        ");
+        $gl->fetch();
+        
+        if ($gl->result < 1) {
+            $this->jerr("post GL seriese failed");
+        }
+        
+        
+        $this->jok("DONE");
+        
+        exit;
+    }
+    
+}
diff --git a/Import/Magento.php b/Import/Magento.php
new file mode 100644 (file)
index 0000000..4c00159
--- /dev/null
@@ -0,0 +1,863 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_Magento extends Pman_Roo
+{
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            $this->authUser = DB_DataObject::Factory('Person');
+            $this->authUser->get('email','brian@bloomandgrowdirect.com');
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    var $timer = false;
+    
+    function get()
+    { 
+        ini_set('memory_limit', '1024M'); 
+        $this->sessionState(0); // turn off session..
+       //$this->transObj = DB_DataObject::Factory('coitem');
+        
+//        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $this->timer = microtime(true);
+        
+        require_once 'File/Convert.php';
+        
+        $this->debugLog('reading /tmp/magento.csv');
+        $fc = new File_Convert('/tmp/magento.csv', 'text/csv');
+        $csv = $fc->convert('text/csv');
+        $this->debugLog('running import CSV');
+        $this->importCsv($csv);
+        
+    }
+    
+    
+    function debugLog($str)
+    {
+        if (!HTML_FlexyFramework::get()->cli) {
+            return;
+        }
+        static $start = false;
+        if (!$start) {
+            
+            $start = microtime(true);
+        }
+        $timed = microtime(true) - $start;
+        
+    
+        echo number_format($timed/60 ,2, '.',','). 'm MEM:' . number_format(memory_get_usage() /1000000,0, '.',','). 'M : '. $str . "\n";
+
+    }
+    
+    
+    function post()
+    {
+        ini_set('memory_limit', '512M'); 
+        set_time_limit(0);
+        $this->timer = microtime(true);
+        
+        $this->sessionState(0); // turn off session..
+        //$this->transObj = DB_DataObject::Factory('coitem');
+      
+//        $this->transObj->query('BEGIN');
+                
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($content)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $this->debugLog('reading file');
+        
+        $fh = fopen($content, 'r');
+        
+        if (!$fh) {
+            $this->jerr("invalid content file");
+        }
+        // new format header
+        $reqs = array(
+            'ORDER ID', 'CREATION DATE', 'BILLING NAME', 
+            'CUSTOMER EMAIL', 'SHIPPING NAME', 'SHIPPING ADDRESS',
+            'SHIPPING CITY', 'SHIPPING STATE', 'SHIPPING POSTCODE', 
+            'SHIPPING COUNTRY', 'SHIPPING TELEPHONE', 'SHIPPING METHOD', 
+            'DELIVERY NOTE', 'SIGNATURE REQUIRED?', 'TOTAL WEIGHT', 
+            'CUSTOMER BALANCE', 'SHIPPING', 'GRAND TOTAL', 'GIFT CARD',
+            'TAX AMOUNT', 'SKU', 'PRODUCT NAME', 
+            'QTY', 'UNIT PRICE', 'SUBTOTAL', 
+            'DISCOUNT', 'DISCOUNTED TOTAL', 'PAYMENT METHOD', 
+            'GIFT WRAP ID', 'COUPON CODE', 'CUSTOMER GROUP'
+        );
+        
+        $cols = false;
+        $rows = array();
+        
+        
+        // load customers..
+        
+        $c = DB_DataObject::factory('custinfo');
+        $c->whereAdd("
+            cust_number = 'MGCREDITCARD'
+            OR
+            cust_number= 'MGPAYPAL'
+            OR
+            cust_number = 'MGDEPOSIT'
+        ");
+        
+        $customers = $c->fetchAll('cust_id', 'cust_number');
+        
+        if(count(array_values($customers)) != 3){
+            $this->jerr("error occur on getting MGCREDITCARD, MGPAYPAL and MGDEPOSIT customers". print_R($customers,true));
+        }
+        
+        foreach($customers as $id=>$n) {
+            $rows[$n] = array();
+        }
+        
+        $this->errmsg = array();
+        
+        $no_lines_in_file= count(file($content)) ;
+        
+        $no_split = $no_lines_in_file > 500 ? false : true; // small file just group by customers.. big file group by the first two char of the order number!
+        
+        if (!HTML_FlexyFramework::get()->cli && !$no_split && $no_lines_in_file > 2500) {
+            $this->jerr("file is too large to upload - please send to admin to import ($no_lines_in_file)");
+        }
+        
+        $ln = '';
+        $lnum=  0;
+        $od = false;
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            $lnum++;
+            if (!strlen(implode('', $n))) {
+                continue;
+            }
+            if (!$cols) {
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($reqs as $req) {
+                    if (!in_array($req,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            
+            foreach ($cols as $k => $c){
+                $c = strtoupper($c);
+                if (empty($c) || !strlen(trim($c))) {
+                    continue;
+                }
+                
+                if($c == 'ORDER ID'){
+                    if($ln != $n[$k]){
+                        $ln = $n[$k];
+                        $row = 1;
+                    }
+                    $r[$c] = substr($n[$k], -4) * 10000 + $row;
+                    
+                    continue;
+                }
+                if($c == 'CREATION DATE'){
+                   $r[$c] = date('Y-m-d',strtotime(str_replace('/', '-', $n[$k]))); 
+                   continue;
+                }
+                if (!isset($n[$k])) {
+                    $this->jerr("Error on line $lnum - missing data in column $c");
+                }
+                $r[$c] = $n[$k];
+            }
+            
+            if ($od === false) {
+                $od = $r['CREATION DATE'];
+            } 
+            if ($od != $r['CREATION DATE']) {
+                $this->jerr("the file contains orders for multiple days first was $od, found {$r['CREATION DATE']}
+                            - either download again, or remove the extra lines");
+            }
+            
+            if (empty($r['QTY']) || (floor($r['QTY']) != $r['QTY'])) {
+                $this->jerr("Error on line $lnum - {$r['QTY']} is not a valid quantity");
+            }
+            
+            
+            $row++;
+            $index = $no_split ? 1 : floor($r['ORDER ID'] / 1000000);
+            
+            if($r['PAYMENT METHOD'] == 'creditcard' || $r['PAYMENT METHOD'] == 'free'){
+                $rows['MGCREDITCARD'][$index][] = $r;
+                continue;
+                
+            }
+            
+            if($r['PAYMENT METHOD'] == 'paypal_express'){
+                $rows['MGPAYPAL'][$index][] = $r;
+                continue;
+            }
+            if($r['PAYMENT METHOD'] == 'directdeposit_au'){
+                $rows['MGDEPOSIT'][$index][] = $r;
+                continue;
+            }
+            $this->jerr("invalid payment type: {$r['PAYMENT METHOD']} on   line $lnum");
+            
+        }
+        
+        fclose($fh);
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        $total   = 0.0;
+        $billed = 0.0;
+        
+        foreach($customers as $cid => $cname) {
+            
+            
+            if (empty($rows[$cname])) {
+                continue;
+            }
+            
+            foreach ($rows[$cname] as $k => $v){
+                $this->transObj = DB_DataObject::Factory('cohead');
+                $this->transObj->query('BEGIN');
+                $this->transObj->lockTables();
+                list( $ltotal, $lbilled)  = $this->createOrder($cid, $cname, $v, ($no_split) ? '' : ($k));
+                
+                if (!empty($this->errmsg)) {
+                    $this->jerr(implode("\n", $this->errmsg));
+                }
+                
+                $this->transObj->query('COMMIT');
+                $this->transObj = false;
+                
+                $GLOBALS['_DB_DATAOBJECT']['RESULTS']   = array();
+                $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
+                
+                
+                $total += $ltotal;
+                $billed += $lbilled;
+            }
+            
+        }
+        
+        $msg = empty($this->ok_message) ? 'data imported successfully' : $this->ok_message;
+
+        $this->addEvent('MAGENTO', false, $msg);
+        
+        $this->jok($msg . ' TOTAL: '. number_format($total,2) . ' BILLED: ' .number_format($billed, 2) . ' Time:' . (microtime(true) - $this->timer) . ' seconds' );
+       
+    }
+    
+    function createOrder($cust_id, $cust_name, $rows, $suffix = '')
+    {
+        
+        $this->debugLog("creating order $cust_name - $suffix");
+        $customer = DB_DataObject::Factory('custinfo');
+        $customer->get($cust_id);
+        $location_id = DB_DataObject::Factory('location')->defaultByItemsite()->itemsite_location_id;
+        
+        if(empty($rows)){
+            $this->warning[] = "No products sold for " . $cust_name;
+            return;
+        }
+        
+        $order_date = $rows[0]['CREATION DATE'];
+        
+        $prefix = array(
+            'MGCREDITCARD' => 'MGC',
+            'MGPAYPAL' => 'MGP',
+            'MGDEPOSIT' => 'MGD',
+            
+        );
+        
+        if(!empty($suffix)){
+            static $oldvoid = array();
+            $nox = $prefix[$cust_name] . str_replace('-', '', $order_date);
+            if (!in_array($nox, $oldvoid)) {
+                $this->debugLog('void the non-x sales order');
+                
+                $co = DB_DataObject::factory('cohead');
+                if($co->get('cohead_number',$nox)){
+                    $this->voidInvAndShipments($co);
+                    $co->void();
+                }
+                
+                $oldvoid[] = $nox;
+            }
+            $suffix = 'x'.$suffix;
+        }
+        
+        $cohead_number = $prefix[$cust_name] . str_replace('-', '', $order_date) . $suffix;
+        
+        $co = DB_DataObject::factory('cohead');
+        
+        if($co->get('cohead_number',$cohead_number)){
+            
+            $this->voidInvAndShipments($co);
+        
+        } else {
+            
+            $this->debugLog('creating new head');
+            // create cntct if not exists
+            $cntct = array(
+                'cntct_first_name' => $customer->cust_name,
+                'cust_id'  =>        $cust_id,
+                'cntct_active'     => 1,
+                'cntct_name'       => $customer->cust_name
+            );
+            // simple address for customer..
+            $addr = array(
+                'addr_active' => 1,
+                'addr_line1'  => 'Address for ' . $customer->cust_name . ' account'
+            );
+            $cn = $this->checkcntctAndaddr($cntct, $addr);
+
+            if(!$cn->cntct_id){
+                $this->jerr('error occur on getting the contact of ' . $customer->cust_name);
+            }
+            $sr = $this->authUser->salesrep();
+            
+            $co = DB_DataObject::factory('cohead');
+
+            $co->setFrom(array(
+                'cohead_cust_id'           => $cust_id,
+                'cohead_number'            => $cohead_number,
+                'cohead_cust_id_cust_name' => $cust_name,
+                'cohead_orderdate'         => $order_date,
+                'cohead_targetdate'        => $order_date,
+                'cohead_location_src'      => $location_id,
+                'cohead_terms_id'          => $customer->cust_terms_id,
+                'cohead_salesrep_id'       => empty($sr->salesrep_id) ? $customer->cust_salesrep_id : $sr->salesrep_id,
+                'cohead_billto_cntct_id'   => $cn->pid(),
+                'cohead_shipto_cntct_id'   => $cn->pid(),
+                'cohead_curr_id'           => $customer->cust_curr_id,
+                'cohead_taxzone_id'        => $customer->cust_taxzone_id
+                
+            ));
+
+            foreach($co->defaults() as $k=>$v) {
+                if (!isset($co->$k)) {
+                    $co->$k = $v;
+                }
+            }
+
+            $co->insert();
+            $oldco = clone($co);
+            $co->updateAddress();
+            $co->fixMisc();
+            $co->update($oldco);
+            
+        }
+        
+        $this->debugLog('adding lines');
+        
+        $total = 0.0;
+        $delivery = 0.0;
+        $billitems = array();
+        $invoice_total = 0.0;
+        $toShipment = array();
+        $gift = 0.0;
+        
+        $this->debugLog("number of items " . count($rows));
+       
+        foreach ($rows  as $r){
+            
+            // do we have the itme??
+            $i = DB_DataObject::factory('item')->lookupSKU($r['SKU']);
+            if (!$i) {
+                $this->errmsg[] = $r['SKU'] . ' not found';
+                continue;
+            }
+            
+            // delete the old line numbers.. AGHH !!! = this has been destroying data!!! (it did not have coitem_cohead_id before..)
+            $coitem = DB_DataObject::factory('coitem');
+            $coitem->coitem_cohead_id = $co->pid();
+            
+            if($coitem->get('coitem_linenumber', $r['ORDER ID'])){ // coitem not exist
+               $coitem->delete();    
+            }
+            
+            $coitem = DB_DataObject::factory('coitem');
+            // create the coitem
+            
+            $itemsite = $i->itemsite();
+            if (!$itemsite) {
+                $this->jerr("product {$i->item_number} has not been created correctly - missing itemsite");
+            }
+            
+            $coitem_custprice = round(($r['UNIT PRICE']) * (10 / 11) ,3); // take out the tax
+            
+            // grand total = unit price + discount + shipping -customer balance - gift card
+            
+            $discount_rate = round((abs($r['DISCOUNT']) / ($r['GRAND TOTAL'] - $r['SHIPPING'] - $r['DISCOUNT'] + $r['CUSTOMER BALANCE'] + $r['GIFT CARD'])), 3); // discount rate
+            
+            $coitem_price = round(($coitem_custprice * (1 - $discount_rate)), 3);
+            
+             
+            $coitem->setFrom(array(
+                'coitem_cohead_id'    => $co->pid(),
+                'coitem_linenumber'   => $r['ORDER ID'],
+                'coitem_itemsite_id'  => $itemsite->pid(),
+                'coitem_qtyord'       => $r['QTY'],
+                'coitem_price'        => $coitem_price,
+                'coitem_custprice'    => $coitem_custprice, 
+                'coitem_qtyshipped'   => 0,
+                'coitem_location_src' => $co->cohead_location_src,
+                'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                'coitem_scheddate'    => $r['CREATION DATE']
+            ));
+            foreach($coitem->defaults() as $k=>$v) {
+                if (empty($coitem->$k)) {
+                    $coitem->$k = $v;
+                }
+            }
+            
+            $coitem->insert();
+            
+            if(!$coitem->coitem_id){
+                $this->errmsg[] = $r['SKU'] . ' error occur on insert';
+                continue;
+            }
+            
+            $toShipment[$coitem->pid()] = $coitem;
+            
+            if(substr($r['ORDER ID'],-4,4) == 1){ 
+                
+                $total +=  ($r['GRAND TOTAL'] + $r['CUSTOMER BALANCE'] + $r['GIFT CARD']) ; // with tax
+                
+//                if ( $r['PAYMENT METHOD'] == 'free' ) {
+//                    $r['SHIPPING']  = 0.0;
+//                }
+                
+                $delivery += round(($r['SHIPPING'] * (10 / 11)), 3); // without tax
+                
+                $gift += round((($r['CUSTOMER BALANCE'] + $r['GIFT CARD']) * (10 / 11)), 3); // without tax
+            }
+            
+            $x = array(
+                'cobill_coitem_id'  => $coitem->pid(),
+                'cobill_qty'        => $coitem->coitem_qtyord
+            );
+            
+            $billitems[] = (object)$x;
+            
+            $invoice_total += round($coitem->coitem_qtyord * $coitem->coitem_price, 3);
+            
+            
+            
+        }
+        
+        if (!empty($this->errmsg)) {
+            return false;
+        }
+        
+        // last row - create shipment...
+        
+        if(count($toShipment)){
+            $d = array(
+                'curr'    => $co->cohead_curr_id
+            );
+            $this->orderShipments($toShipment,$d);
+            
+        }
+        
+        $this->debugLog('sorting out discounts');
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->get('coitem_cohead_id', $co->pid());
+        if($coitem->find(true)){
+            $coitem->updatePretaxDiscount($this); 
+        }
+        
+        if ($delivery > 0) {
+            $this->debugLog('sorting out delivery');
+            
+            $i = dB_DataObject::Factory('item');
+            if (!$i->get('item_number', 'Z-DELIVERY CHARGE')) { 
+                $this->jerr("delivery charge not found");
+            }
+            $itemsite = $i->itemsite();
+            
+            // add z-Delivery Charge coz it's taxable
+            $coitem = DB_DataObject::factory('coitem');
+            $coitem->coitem_cohead_id = $co->pid();
+            $coitem->coitem_itemsite_id = $itemsite->pid();
+            $coitem->coitem_linenumber = 9999998;
+            if (!$coitem->find(true)) {
+            
+                    $coitem->setFrom(array(
+                        'coitem_cohead_id'    => $co->pid(),
+                        'coitem_linenumber'   => 9999998, // need a line number..
+                        'coitem_itemsite_id'  => $coitem->coitem_itemsite_id,
+                        'coitem_qtyord'       => 1,
+                        'coitem_price'        => round($delivery,3),
+                        'coitem_custprice'    => round($delivery,3),
+                        'coitem_qtyshipped'   => 0,
+                        'coitem_location_src' => $co->cohead_location_src,
+                        'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                        'coitem_scheddate'    => $order_date
+                    ));
+                
+                foreach($coitem->defaults() as $k=>$v) {
+                    if (empty($coitem->$k)) {
+                        $coitem->$k = $v;
+                    }
+                }
+                $coitem->insert();
+            } else {
+                $co_old = clone($coitem);
+                $coitem->setFrom(array(
+                    'coitem_price'        => round($delivery,3),
+                    'coitem_custprice'    => round($delivery,3),
+                    'coitem_location_src' => $co->cohead_location_src,
+                    'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                    'coitem_scheddate'    => $order_date
+                ));
+                $coitem->update($co_old);
+                
+                
+            }
+            // add freigth total to invoice..
+            $invoice_total +=  round($delivery,3) ;
+            
+            $x = array(
+                'cobill_coitem_id'  => $coitem->pid(),
+                'cobill_qty'        => $coitem->coitem_qtyord
+            );
+            
+            $billitems[] = (object)$x;
+            
+            
+        }
+       
+        
+        $i = DB_DataObject::Factory('item');
+        if (!$i->get('item_number', 'Z-LIST-DISCOUNT')) { 
+            $this->jerr("Z-LIST-DISCOUNT not found");
+        }
+        $itemsite = $i->itemsite();
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->coitem_cohead_id = $co->pid();
+        $coitem->coitem_itemsite_id = $itemsite->pid();
+        if($coitem->find(true)){
+            $x = array(
+                'cobill_coitem_id'  => $coitem->pid(),
+                'cobill_qty'        => $coitem->coitem_qtyord
+            );
+            
+            $billitems[] = (object)$x;
+            $invoice_total = $invoice_total + round(($coitem->coitem_qtyord * $coitem->coitem_price), 3);
+            
+            $co_old = clone ($co);
+            $co->setFrom(array(
+                'cohead_misc' => $coitem->coitem_qtyord * $coitem->coitem_price * -1,
+                'cohead_misc_descript' => 'DISCOUNT'
+            ));
+            $co->update($co_old);
+        }
+        
+        
+        $cobapply_list = array();
+        
+        if($gift > 0){ // check credit memo
+            
+            $cmhead = DB_DataObject::factory('cmhead');
+            $cmhead->setFrom(array(
+                'cmhead_number'          => $cmhead->nextNumber(),
+                'cmhead_cust_id'         => $co->cohead_cust_id,
+                'cmhead_billto_cntct_id' => $co->cohead_billto_cntct_id,
+                'cmhead_taxzone_id'      => $co->cohead_taxzone_id,
+                'cmhead_curr_id'         => $co->cohead_curr_id,
+                'cmhead_salesrep_id'     => $co->cohead_salesrep_id,
+                'cmhead_docdate'         => $co->cohead_targetdate,
+                'cmhead_location_id'     => $co->cohead_location_src
+            ));
+            
+            foreach($cmhead->defaults() as $k=>$v) {
+                if (empty($cmhead->$k)) {
+                    $cmhead->$k = $v;
+                }
+            }
+            
+            $cmhead->insert();
+            
+            if(!$cmhead->pid()){
+                $this->jerr('error occur on insert a credit memo');
+            }
+            
+            $i = dB_DataObject::Factory('item');
+            if (!$i->get('item_number', 'Z-DISCOUNT-VOUCHER')) { 
+                $this->jerr("Z-DISCOUNT-VOUCHER not found");
+            }
+            $itemsite = $i->itemsite();
+            
+            $cmitem = DB_DataObject::factory('cmitem');
+            $cmitem->setFrom(array(
+                'cmitem_cmhead_id' => $cmhead->pid(),
+                'cmitem_linenumber' => 999997,
+                'cmitem_itemsite_id' => $itemsite->pid(),
+                'cmitem_qtycredit' => 1,
+                'cmitem_qtyreturned' => 1,
+                'cmitem_unitprice' => $gift,
+                'cmitem_taxtype_id' => $cmitem->sqlValue("gettaxtypeid('Taxable'::text)"),
+                'cmitem_comments' => $i->item_descrip1,
+            ));
+            
+            foreach($cmitem->defaults() as $k=>$v) {
+                if (empty($cmitem->$k)) {
+                    $cmitem->$k = $v;
+                }
+            }
+            $cmitem->insert();
+            
+            if(!$cmitem->pid()){
+                $this->jerr('error occur on insert Z-DISCOUNT-VOUCHER to credit memo');
+            }
+            
+            $cmhead->post($this);
+            
+            $aropen = DB_DataObject::factory('aropen');
+            $aropen->aropen_cust_id = $customer->pid();
+            $aropen->aropen_doctype = 'C';
+            $aropen->aropen_docnumber = $cmhead->cmhead_number;
+            $cobapply_list = $aropen->fetchAll('aropen_id');
+            if(count($cobapply_list) != 1){
+                $this->jerr('error occur on getting cmhead aropen');
+            }
+             
+        }
+        
+        $this->debugLog('creating bill');
+        
+        // create the invoice for each magento order
+        $cobmisc = DB_DataObject::factory('cobmisc');
+        
+        $cobmisc->setFrom(array(
+            'cobmisc_cohead_id' => $co->pid(),
+            'cobmisc_invcdate'  => $order_date,
+            'cobmisc_shipdate'  => $order_date
+        ));
+        
+        $cobmisc->cobmisc_taxtype_id = $cobmisc->sqlValue("gettaxtypeid('Taxable'::text)");
+        $cobmisc->fixMisc();
+        
+        $t = $cobmisc->factory('cobmisc');
+        $t->query("SELECT createBillingHeader({$co->pid()}) AS cobmisc_id");
+        $t->fetch();
+        
+        $cobmisc->cobmisc_id = $t->cobmisc_id;
+        $cobmisc->updateItems($billitems);
+        
+        // apply the credit memo..
+        if (!empty($cobapply_list)) {
+           $cobmisc->updateCobApply($this,$cobapply_list);
+        }
+        
+        // post the bill.
+        
+        $t = $cobmisc->factory('cobmisc');
+        $t->get($cobmisc->cobmisc_id);
+        $t->post($this);
+        
+        // fetch again so it should have invoice..
+        $t = $cobmisc->factory('cobmisc');
+        $t->get($cobmisc->cobmisc_id);
+        
+        $invoice = $t->invchead();
+        
+        $aropen = $invoice->aropen();
+        
+        return array( $total, $aropen->aropen_amount);
+        
+    }
+    
+    function checkcntctAndaddr($cntct,$addrs)
+    {
+        $cn = DB_DataObject::factory('cntct');
+
+        if(!$cn->get('cntct_first_name', $cntct['cntct_first_name'])){ // contact not exists
+            $cn->setFrom($cntct);
+            $cn->cntct_crmacct_id = $cn->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$cntct['cust_id']})");
+            $cn->genNumber();
+            $cn->insert();
+        }
+
+        if(!$cn->cntct_addr_id){ // addr not exists
+            $addr = DB_DataObject::Factory('addr');
+            $addr->setFrom($addrs);
+            $addr->genNumber();
+            $addr->insert();
+
+            $oldcn = clone($cn);
+            $cn->cntct_addr_id = $addr->pid();
+            $cn->update($oldcn);
+
+        }
+        
+        return $cn;
+    }
+    
+    function checkshiptoinfo($customer, $cntct)
+    {
+        $sh = DB_DataObject::Factory('shiptoinfo');
+        $sh->shipto_cntct_id = $cntct->pid();
+        $sh->shipto_addr_id = $cntct->cntct_addr_id;
+        if ($sh->find(true)) {
+            return $sh->pid();
+        }
+        
+        $sh->setFrom(array(
+            'shipto_cust_id' => $cust_id,
+            'shipto_name' => $cntct->cntct_name,
+            'shipto_salesrep_id'=> $customer->cust_salesrep_id,
+            'shipto_active' => true,
+            'shipto_adefault' => false,
+            'shipto_shipchrg_id' => $customer->cust_shipchrg_id,
+            'shipto_taxzone_id' => $customer->cust_taxzone_id,
+            'shipto_shipform_id' => $customer->cust_shipform_id,
+            'shipto_commission' => 0,
+            'shipto_shipzone_id' => $customer->cust_taxzone_id
+
+        ));
+        $sh->genNum();
+        $sh->insert();
+        
+        return $sh->pid();
+        
+    }
+    
+    function orderShipments($toShipments,$d)
+    {
+        $this->debugLog('creating shipments');
+        
+        $ids = array_keys($toShipments);
+        $c = array_pop($toShipments);
+        
+        $cc = DB_DataObject::factory('coitem');
+        $cc->coitem_cohead_id = $c->coitem_cohead_id;
+        $cc->find();
+        
+        $x = array();
+        $shipitems = array();
+        while ($cc->fetch()){ // this query will take about 6 secs...
+            
+            $itemsite = $cc->itemsite();
+            // skip non-stock items..
+            if (!$itemsite->itemsite_stocked) {
+                continue;
+            }
+            
+            $x['shipitem_orderitem_id'] = $cc->pid();
+            $x['shipitem_qty'] = 0;
+            if(in_array($cc->pid(), $ids)){
+                $x['shipitem_qty'] = $cc->coitem_qtyord;
+            }
+            $shipitems[] = (object)$x;
+        }
+        
+        $sh = DB_DataObject::factory('shiphead');
+        
+        
+        
+        $sh->setFrom(array(
+            'shiphead_shipdate'        => $c->coitem_scheddate,
+            'shiphead_order_id'        => $c->coitem_cohead_id,
+            'shiphead_sfstatus'        => 'N',
+            'shiphead_location_id'     => $c->coitem_location_src,
+            'shiphead_shipto_id'       => $c->coitem_shipto_id,
+            //'shiphead_number'          => $cohead->cohead_number . substr($c->coitem_linenumber, 0, 4),
+            'shiphead_order_type'      => 'SO',
+            'shiphead_freight'         => 0, //$d['freight'],
+            'shiphead_freight_curr_id' => $d['curr'],
+            'shiphead_notes'           => '' // $r['SHIP NOTE']
+        ));
+        $sh->beforeInsert(array('shiphead_number' => 'Automatic'),$this);
+        //$this->jerr("about to create shipment: " . $sh->shiphead_number);
+        
+        $sh->insert();
+        
+        $sh->updateItems($shipitems, $this); 
+        
+        $sh->confirm($this); 
+    }
+    
+    function voidInvAndShipments($co)
+    {
+        $this->debugLog('deelting old invoices / shipments');
+        $invoices  = $co->cobmiscs();
+        
+        foreach($invoices as $i) {
+            $i->void($this, true);
+        }
+
+        // do it twice..
+        $invoices  = $co->cobmiscs();
+        foreach($invoices as $i) {
+            $i->void($this,true);
+        }
+        // delete the shipments...
+        $shipheads = $co->shipheads();
+
+        foreach($shipheads  as $s) {
+
+            if (!empty($s->shiphead_shipped) && !empty($s->shiphead_shipdate)) {
+                $res = $s->unconfirm($this,true);
+
+                if ($res !== true) {
+                    $this->jerr("ship unconfirm failed:" . $res);
+                }
+            }
+
+            if (!empty($s->shiphead_shipdate)) { // 395.43042492867 secs...
+                $res = $s->void($this,true);    // void shipitem will take 0.1 sec for each... a little bit long time...
+
+                if ($res !== true) {
+                    $this->jerr("ship voiding failed" . $res)  ;
+                }
+            }
+        }
+    }
+    //B_45 not found
+    //B_12 not found
+    //B_1 not found
+    //B_11 not found
+    
+    // 210203 not found
+    // 212103 not found
+    // Gift Wrapping not found
+    // Gift Wrapping not found
+    // 212204 not found
+    // Gift Wrapping not found
+    
+    
+}
diff --git a/Import/MagentoOld.php b/Import/MagentoOld.php
new file mode 100644 (file)
index 0000000..3e426bb
--- /dev/null
@@ -0,0 +1,866 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_MagentoOld extends Pman_Roo
+{
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            $this->authUser = DB_DataObject::Factory('Person');
+            $this->authUser->get('email','brian@bloomandgrowdirect.com');
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    var $timer = false;
+    
+    function get()
+    { 
+        ini_set('memory_limit', '1024M'); 
+        $this->sessionState(0); // turn off session..
+       //$this->transObj = DB_DataObject::Factory('coitem');
+        
+//        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $this->timer = microtime(true);
+        
+        require_once 'File/Convert.php';
+        
+        $this->debugLog('reading /tmp/magento.csv');
+        $fc = new File_Convert('/tmp/magento.csv', 'text/csv');
+        $content = $fc->convert('text/csv');
+        $this->debugLog('running import CSV');
+        $this->importCsv($content, '');
+        
+    }
+    
+    
+    function debugLog($str)
+    {
+        if (!HTML_FlexyFramework::get()->cli) {
+            return;
+        }
+        static $start = false;
+        if (!$start) {
+            
+            $start = microtime(true);
+        }
+        $timed = microtime(true) - $start;
+        
+    
+        echo number_format($timed/60 ,2, '.',','). 'm MEM:' . number_format(memory_get_usage() /1000000,0, '.',','). 'M : '. $str . "\n";
+
+    }
+    
+    
+    function post( )
+    {
+        ini_set('memory_limit', '512M'); 
+        set_time_limit(0);
+        $this->timer = microtime(true);
+        
+        $this->sessionState(0); // turn off session..
+        //$this->transObj = DB_DataObject::Factory('coitem');
+      
+//        $this->transObj->query('BEGIN');
+                
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($content, $header = '')
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        // defaut the header
+        $col = array(
+          'order number', 'order date', 'customer name', 'email', 'billing name', 'address',
+          'city', 'state', 'postalcode', 'country', 'phone', 'ship type', 'unknown1', 'ship note',
+          'signature required', 'weight', 'subtotal', 'freight', 'total', 'tax', 'item name', 'item description',
+          'quantity', 'item total', 'discount', 'payment type', 'unknown2', 'unknown3', 'discount description'
+        );
+        // header from file
+        if(!empty($header)){
+            $col = array();
+            $fh = fopen($header, 'r');
+            if (!$fh) {
+                $this->jerr("invalid header file");
+            }
+            while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+                foreach ($n as $h){
+                    $col[] = strtoupper(trim($h));
+                } 
+            }
+        }
+        $this->debugLog('reading file');
+        
+        $fh = fopen($content, 'r');
+        if (!$fh) {
+            $this->jerr("invalid content file");
+        
+            
+        }
+        // load customers..
+        
+        $c = DB_DataObject::factory('custinfo');
+        $c->whereAdd("
+            cust_number = 'MGCREDITCARD'
+            OR
+            cust_number= 'MGPAYPAL'
+            OR
+            cust_number = 'MGDEPOSIT'
+        ");
+        
+        $customers = $c->fetchAll('cust_id', 'cust_number');
+        
+        if(count(array_values($customers)) != 3){
+            $this->jerr("error occur on getting MGCREDITCARD, MGPAYPAL and MGDEPOSIT customers". print_R($customers,true));
+        }
+        
+        foreach($customers as $id=>$n) {
+            $rows[$n] = array();
+        }
+        $this->errmsg = array();
+        
+        $no_split = count(file($content)) > 500 ? false : true; // small file just group by customers.. big file group by the first two char of the order number!
+        
+        if (!HTML_FlexyFramework::get()->cli && !$no_split) {
+            $roo->jerr("file is too large to upload - please send to admin to import");
+        }
+        
+        $ln = '';
+        $on = '';
+        $od = false;
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!strlen(implode('', $n))) {
+                continue;
+            }
+            
+            foreach ($col as $k => $c){
+                $c = strtoupper($c);
+                if($c == 'ORDER NUMBER'){
+                    if($ln != $n[$k]){
+                        $ln = $n[$k];
+                        $row = 1;
+                    }
+                    $r[$c] = substr($n[$k], -4) * 10000 + $row;
+                    continue;
+                }
+                if($c == 'ORDER DATE'){
+                   $r[$c] = date('Y-m-d',strtotime(str_replace('/', '-', $n[$k]))); 
+                   continue;
+                }
+                
+                $r[$c] = $n[$k];
+            }
+            if ($od === false) {
+                $od = $r['ORDER DATE'];
+            } 
+            if ($od != $r['ORDER DATE']) {
+                $this->jerr("the file contains orders for multiple days first was $od, found {$r['ORDER DATE']}
+                            - either download again, or remove the extra lines");
+            }
+            
+            $row++;
+            $index = $no_split ? 1 : floor($r['ORDER NUMBER'] / 1000000);
+            
+            if($r['PAYMENT TYPE'] == 'creditcard' || $r['PAYMENT TYPE'] == 'free'){
+                $rows['MGCREDITCARD'][$index][] = $r;
+                continue;
+                
+            }
+            
+            if($r['PAYMENT TYPE'] == 'paypal_express'){
+                $rows['MGPAYPAL'][$index][] = $r;
+                continue;
+            }
+            if($r['PAYMENT TYPE'] == 'directdeposit_au'){
+                $rows['MGDEPOSIT'][$index][] = $r;
+                continue;
+            }
+            $this->jerr("invalid payment type: "  .$r['PAYMENT TYPE'] );
+            
+        }
+        
+        fclose($fh);
+        
+        $total   = 0.0;
+        $billed = 0.0;
+        
+        foreach($customers as $cid => $cname) {
+            
+            
+            if (empty($rows[$cname])) {
+                continue;
+            }
+            foreach ($rows[$cname] as $k => $v){
+                $this->transObj = DB_DataObject::Factory('cohead');
+                $this->transObj->query('BEGIN');
+                $this->transObj->lockTables();
+                list( $ltotal, $lbilled)  = $this->createOrder($cid, $cname, $v, ($no_split) ? '' : ($k));
+                
+                if (!empty($this->errmsg)) {
+                    $this->jerr(implode("\n", $this->errmsg));
+                }
+                
+                $this->transObj->query('COMMIT');
+                $this->transObj = false;
+                
+                $GLOBALS['_DB_DATAOBJECT']['RESULTS']   = array();
+                $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
+                
+                
+                $total += $ltotal;
+                $billed += $lbilled;
+            }
+            
+        }
+        
+         
+        $msg = empty($this->ok_message) ? 'data imported successfully' : $this->ok_message;
+
+        $this->addEvent('MAGENTO', false, $msg);
+        
+        $this->jok($msg . ' TOTAL: '. number_format($total,2) . ' BILLED: ' .number_format($billed, 2) . ' Time:' . (microtime(true) - $this->timer) . ' seconds' );
+       
+    }
+    
+    function createOrder($cust_id, $cust_name, $rows, $suffix = '')
+    {
+        
+        $this->debugLog("creating order $cust_name - $suffix");
+        $customer = DB_DataObject::Factory('custinfo');
+        $customer->get($cust_id);
+        $location_id = DB_DataObject::Factory('location')->defaultByItemsite()->itemsite_location_id;
+        
+        if(empty($rows)){
+            $this->warning[] = "No products sold for " . $cust_name;
+            return;
+        }
+        
+        $order_date = $rows[0]['ORDER DATE'];
+        
+        $prefix = array(
+            'MGCREDITCARD' => 'MGC',
+            'MGPAYPAL' => 'MGP',
+            'MGDEPOSIT' => 'MGD',
+            
+        );
+        
+        if(!empty($suffix)){
+            static $oldvoid = array();
+            $nox = $prefix[$cust_name] . str_replace('-', '', $order_date);
+            if (!in_array($nox, $oldvoid)) {
+                $this->debugLog('void the non-x sales order');
+                
+                $co = DB_DataObject::factory('cohead');
+                if($co->get('cohead_number',$nox)){
+                    $this->voidInvAndShipments($co);
+                    $co->void();
+                }
+                
+                $oldvoid[] = $nox;
+            }
+            $suffix = 'x'.$suffix;
+        }
+        
+        $cohead_number = $prefix[$cust_name] . str_replace('-', '', $order_date) . $suffix;
+        
+        $co = DB_DataObject::factory('cohead');
+        
+        if($co->get('cohead_number',$cohead_number)){
+            
+            $this->voidInvAndShipments($co);
+        
+        } else {
+            
+            $this->debugLog('creating new head');
+            // create cntct if not exists
+            $cntct = array(
+                'cntct_first_name' => $customer->cust_name,
+                'cust_id'  =>        $cust_id,
+                'cntct_active'     => 1,
+                'cntct_name'       => $customer->cust_name
+            );
+            // simple address for customer..
+            $addr = array(
+                'addr_active' => 1,
+                'addr_line1'  => 'Address for ' . $customer->cust_name . ' account'
+            );
+            $cn = $this->checkcntctAndaddr($cntct, $addr);
+
+            if(!$cn->cntct_id){
+                $this->jerr('error occur on getting the contact of ' . $customer->cust_name);
+            }
+            $sr = $this->authUser->salesrep();
+
+            $co = DB_DataObject::factory('cohead');
+
+            $co->setFrom(array(
+                'cohead_cust_id'           => $cust_id,
+                'cohead_number'            => $cohead_number,
+                'cohead_cust_id_cust_name' => $cust_name,
+                'cohead_orderdate'         => $order_date,
+                'cohead_targetdate'        => $order_date,
+                'cohead_location_src'      => $location_id,
+                'cohead_terms_id'          => $customer->cust_terms_id,
+                'cohead_salesrep_id'       => empty($sr->salesrep_id) ? $customer->cust_salesrep_id : $sr->salesrep_id,
+                'cohead_billto_cntct_id'   => $cn->pid(),
+                'cohead_shipto_cntct_id'   => $cn->pid(),
+                'cohead_curr_id'           => $customer->cust_curr_id,
+                'cohead_taxzone_id'        => $customer->cust_taxzone_id
+                
+            ));
+
+            foreach($co->defaults() as $k=>$v) {
+                if (!isset($co->$k)) {
+                    $co->$k = $v;
+                }
+            }
+
+            $co->insert();
+            $oldco = clone($co);
+            $co->updateAddress();
+            $co->fixMisc();
+            $co->update($oldco);
+            
+        }
+        
+        $this->debugLog('adding lines');
+        $freight = 0.0;
+        $total = 0.0;
+        $total_discount = 0.0;
+        $itemtotal = 0.0;
+        $delivery = 0.0;
+        $billitems = array();
+        $invoice_total = 0.0;
+        $toShipment = array();
+        
+        $totaldiscounted_inctax = 0.0;
+        $rounding = 0.0;
+        $aftertax_line_total = 0.0;
+        
+        $this->debugLog("number of items " . count($rows));
+        foreach ($rows  as $r){
+            
+            // do we have the itme??
+            $i = DB_DataObject::factory('item')->lookupSKU($r['ITEM NAME']);
+            if (!$i) {
+                $this->errmsg[] = $r['ITEM NAME'] . ' not found';
+                continue;
+            }
+            
+            // delete the old line numbers..
+            $coitem = DB_DataObject::factory('coitem');
+            if($coitem->get('coitem_linenumber', $r['ORDER NUMBER'])){ // coitem not exist
+               $coitem->delete();    
+            }
+            
+            $coitem = DB_DataObject::factory('coitem');
+            // create the coitem
+            
+            $itemsite = $i->itemsite();
+            if (!$itemsite) {
+                $this->jerr("product {$i->item_number} has not been created correctly - missing itemsite");
+            }
+            
+            $itemtotal += $r['ITEM TOTAL'];
+            
+            $coitem_custprice = round(($r['ITEM TOTAL'] / $r['QUANTITY']) * (10 / 11) ,3);
+            $base_coitem_custprice  = $coitem_custprice;
+            
+            
+            $aftertax_line_total += round($coitem_custprice * $r['QUANTITY'] * 1.1,2 );
+             
+            // $r['DISCOUNT'] is negative number
+            //if(($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) {
+            if(($coitem_custprice == 0.0) || ($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) {
+                $coitem_price  = 0.0;
+                
+            } else {
+                
+                $coitem_price = $coitem_custprice *    ($r['SUBTOTAL'] / ($r['SUBTOTAL'] - $r['DISCOUNT']));
+                $coitem_price = round($coitem_price ,3);
+                
+            }
+            // for rounding tests...
+            
+           
+            $totaldiscounted_inctax +=  ( $r['ITEM TOTAL'] - round($coitem_price * $r['QUANTITY'] * 1.1,2 ));
+             
+            $coitem->setFrom(array(
+                'coitem_cohead_id'    => $co->pid(),
+                'coitem_linenumber'   => $r['ORDER NUMBER'],
+                'coitem_itemsite_id'  => $itemsite->pid(),
+                'coitem_qtyord'       => $r['QUANTITY'],
+                'coitem_price'        => $coitem_price,
+                'coitem_custprice'    => $coitem_custprice, 
+                'coitem_qtyshipped'   => 0,
+                'coitem_location_src' => $co->cohead_location_src,
+                'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                'coitem_scheddate'    => $r['ORDER DATE']
+            ));
+            foreach($coitem->defaults() as $k=>$v) {
+                if (empty($coitem->$k)) {
+                    $coitem->$k = $v;
+                }
+            }
+            $coitem->insert();
+            
+            if(!$coitem->coitem_id){
+                $this->errmsg[] = $r['ITEM NAME'] . ' error occur on insert';
+                continue;
+            }
+           
+            
+            $toShipment[$coitem->pid()] = $coitem;
+            
+            if(substr($r['ORDER NUMBER'],-4,4) == 1){ 
+                $total    +=  $r['TOTAL'] ;
+                $total_discount += $r['DISCOUNT'] ;
+                
+                if ( $r['PAYMENT TYPE'] == 'free' ) {
+                    $r['FREIGHT']  = 0.0;
+                }
+                $freight  +=  ($r['FREIGHT'] * 1.0);
+                $delivery +=  ($r['FREIGHT'] * 10 / 11);
+            }
+            
+            $x = array();
+            $x['cobill_coitem_id'] = $coitem->pid();
+            $x['cobill_qty'] = $coitem->coitem_qtyord;
+            
+            $billitems[] = (object)$x;
+            
+            $invoice_total +=  round($coitem->coitem_qtyord * $coitem->coitem_price,2);
+            
+             
+            
+        }
+        
+        if (!empty($this->errmsg)) {
+            return false;
+        }
+        
+        // last row - create shipment...
+        
+        if(count($toShipment)){
+            $d = array(
+                'curr'    => $co->cohead_curr_id
+            );
+            $this->orderShipments($toShipment,$d);
+            
+        }
+        
+        $this->debugLog('sorting out discounts');
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->get('coitem_cohead_id', $co->pid());
+        if($coitem->find(true)){
+            $coitem->updatePretaxDiscount($this); 
+        }
+        
+        if ($delivery > 0) {
+            $this->debugLog('sorting out delivery');
+            // make the rounding here..
+            $delivery = $freight * (10/11);
+            
+            $i = dB_DataObject::Factory('item');
+            if (!$i->get('item_number', 'Z-DELIVERY CHARGE')) { 
+                $this->jerr("delivery charge not found");
+            }
+            $itemsite = $i->itemsite();
+            
+            // add z-Delivery Charge coz it's taxable
+            $coitem = DB_DataObject::factory('coitem');
+            $coitem->coitem_cohead_id = $co->pid();
+            $coitem->coitem_itemsite_id = $itemsite->pid();
+            $coitem->coitem_linenumber = 9999998;
+            if (!$coitem->find(true)) {
+            
+                    $coitem->setFrom(array(
+                        'coitem_cohead_id'    => $co->pid(),
+                        'coitem_linenumber'   => 9999998, // need a line number..
+                        'coitem_itemsite_id'  => $coitem->coitem_itemsite_id,
+                        'coitem_qtyord'       => 1,
+                        'coitem_price'        => round($delivery,3),
+                        'coitem_custprice'    => round($delivery,3),
+                        'coitem_qtyshipped'   => 0,
+                        'coitem_location_src' => $co->cohead_location_src,
+                        'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                        'coitem_scheddate'    => $order_date
+                    ));
+                
+                foreach($coitem->defaults() as $k=>$v) {
+                    if (empty($coitem->$k)) {
+                        $coitem->$k = $v;
+                    }
+                }
+                $coitem->insert();
+            } else {
+                $co_old = clone($coitem);
+                $coitem->setFrom(array(
+                    'coitem_price'        => round($delivery,3),
+                    'coitem_custprice'    => round($delivery,3),
+                    'coitem_location_src' => $co->cohead_location_src,
+                    'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
+                    'coitem_scheddate'    => $order_date
+                ));
+                $coitem->update($co_old);
+                
+                
+            }
+            // add freigth total to invoice..
+            $invoice_total +=  round($delivery,2) ;
+            
+             
+            $x = array();
+            $x['cobill_coitem_id'] = $coitem->pid();
+            $x['cobill_qty'] = $coitem->coitem_qtyord;
+            
+            $billitems[] = (object)$x;
+            
+            
+        }
+       
+        
+        $i = DB_DataObject::Factory('item');
+        if (!$i->get('item_number', 'Z-LIST-DISCOUNT')) { 
+            $this->jerr("Z-LIST-DISCOUNT not found");
+        }
+        $itemsite = $i->itemsite();
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->coitem_cohead_id = $co->pid();
+        $coitem->coitem_itemsite_id = $itemsite->pid();
+        if($coitem->find(true)){
+            $x = array();
+            $x['cobill_coitem_id'] = $coitem->pid();
+            $x['cobill_qty'] = $coitem->coitem_qtyord;
+            
+            $billitems[] = (object)$x;
+            $invoice_total = $invoice_total + ($coitem->coitem_qtyord * $coitem->coitem_price);
+            
+            $co_old = clone ($co);
+            $co->setFrom(array(
+                'cohead_misc' => $coitem->coitem_qtyord * $coitem->coitem_price * -1,
+                'cohead_misc_descript' => 'DISCOUNT'
+            ));
+            $co->update($co_old);
+        }
+        
+        
+        $cobapply_list = array();
+        // check gift voucher
+        
+        $gift = $itemtotal + $freight - $total + $total_discount;
+        
+        if(false && $gift > 5){ // check credit memo
+            
+            $cmhead = DB_DataObject::factory('cmhead');
+            $cmhead->setFrom(array(
+                'cmhead_number'          => $cmhead->nextNumber(),
+                'cmhead_cust_id'         => $co->cohead_cust_id,
+                'cmhead_billto_cntct_id' => $co->cohead_billto_cntct_id,
+                'cmhead_taxzone_id'      => $co->cohead_taxzone_id,
+                'cmhead_curr_id'         => $co->cohead_curr_id,
+                'cmhead_salesrep_id'     => $co->cohead_salesrep_id,
+                'cmhead_docdate'         => $co->cohead_targetdate,
+                'cmhead_location_id'     => $co->cohead_location_src
+            ));
+            
+            foreach($cmhead->defaults() as $k=>$v) {
+                if (empty($cmhead->$k)) {
+                    $cmhead->$k = $v;
+                }
+            }
+            
+            $cmhead->insert();
+            
+            if(!$cmhead->pid()){
+                $this->jerr('error occur on insert a credit memo');
+            }
+            
+            $i = dB_DataObject::Factory('item');
+            if (!$i->get('item_number', 'Z-DISCOUNT-VOUCHER')) { 
+                $this->jerr("Z-DISCOUNT-VOUCHER not found");
+            }
+            $itemsite = $i->itemsite();
+            
+            $cmitem = DB_DataObject::factory('cmitem');
+            $cmitem->setFrom(array(
+                'cmitem_cmhead_id' => $cmhead->pid(),
+                'cmitem_linenumber' => 999997,
+                'cmitem_itemsite_id' => $itemsite->pid(),
+                'cmitem_qtycredit' => 1,
+                'cmitem_qtyreturned' => 1,
+                'cmitem_unitprice' => $gift,
+                'cmitem_taxtype_id' => $cmitem->sqlValue("gettaxtypeid('Taxable'::text)"),
+                'cmitem_comments' => $i->item_descrip1,
+            ));
+            
+            foreach($cmitem->defaults() as $k=>$v) {
+                if (empty($cmitem->$k)) {
+                    $cmitem->$k = $v;
+                }
+            }
+            $cmitem->insert();
+            
+            if(!$cmitem->pid()){
+                $this->jerr('error occur on insert Z-DISCOUNT-VOUCHER to credit memo');
+            }
+            
+            $cmhead->post($this);
+            
+            $aropen = DB_DataObject::factory('aropen');
+            $aropen->aropen_cust_id = $customer->pid();
+            $aropen->aropen_doctype = 'C';
+            $aropen->aropen_docnumber = $cmhead->cmhead_number;
+            $cobapply_list = $aropen->fetchAll('aropen_id');
+            if(count($cobapply_list) != 1){
+                $this->jerr('error occur on getting aropen');
+            }
+             
+        }
+        
+        $this->debugLog('creating bill');
+        
+        // create the invoice for each magento order
+        $cobmisc = DB_DataObject::factory('cobmisc');
+        
+        $cobmisc->setFrom(array(
+            'cobmisc_cohead_id' => $co->pid(),
+            'cobmisc_invcdate'  => $order_date,
+            'cobmisc_shipdate'  => $order_date
+        ));
+        
+        $cobmisc->cobmisc_taxtype_id = $cobmisc->sqlValue("gettaxtypeid('Taxable'::text)");
+        $cobmisc->fixMisc();
+        
+        $t = $cobmisc->factory('cobmisc');
+        $t->query("SELECT createBillingHeader({$co->pid()}) AS cobmisc_id");
+        $t->fetch();
+        
+        $cobmisc->cobmisc_id = $t->cobmisc_id;
+        $cobmisc->updateItems($billitems);
+        
+        // apply the credit memo..
+        if (!empty($cobapply_list)) {
+           $cobmisc->updateCobApply($this,$cobapply_list);
+        }
+        
+        // post the bill.
+        
+        $t = $cobmisc->factory('cobmisc');
+        $t->get($cobmisc->cobmisc_id);
+        $t->post($this);
+        
+        // fetch again so it should have invoice..
+        $t = $cobmisc->factory('cobmisc');
+        $t->get($cobmisc->cobmisc_id);
+        
+        $invoice = $t->invchead();
+        
+        $aropen = $invoice->aropen();
+        
+        
+        /*
+        if (round($total,2) != round($aropen->aropen_amount,2)) {
+            $this->jerr("TOTAL $total != {$aropen->aropen_amount}" .
+                    print_r(array(
+                        'itemtotal' => $itemtotal,
+                        'aftertax_line_total' => $aftertax_line_total,
+                        
+                        'total_discount' => $total_discount,
+                        'freight' => $freight,
+                        
+                        
+                        'totaldiscounted_inctax' => $totaldiscounted_inctax,
+                        'totaldiscounted_b4tax' => $totaldiscounted_inctax * (10/11),
+                        'freight_b4tax' => $freight * (10/11),
+                        
+                ),true));
+        }
+        */
+        //print_R($aropen);$this->jerr("fixme");
+        
+        return array( $total, $aropen->aropen_amount);
+        
+    }
+    
+    function checkcntctAndaddr($cntct,$addrs)
+    {
+        $cn = DB_DataObject::factory('cntct');
+
+        if(!$cn->get('cntct_first_name', $cntct['cntct_first_name'])){ // contact not exists
+            $cn->setFrom($cntct);
+            $cn->cntct_crmacct_id = $cn->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$cntct['cust_id']})");
+            $cn->genNumber();
+            $cn->insert();
+        }
+
+        if(!$cn->cntct_addr_id){ // addr not exists
+            $addr = DB_DataObject::Factory('addr');
+            $addr->setFrom($addrs);
+            $addr->genNumber();
+            $addr->insert();
+
+            $oldcn = clone($cn);
+            $cn->cntct_addr_id = $addr->pid();
+            $cn->update($oldcn);
+
+        }
+        
+        return $cn;
+    }
+    
+    function checkshiptoinfo($customer, $cntct)
+    {
+        $sh = DB_DataObject::Factory('shiptoinfo');
+        $sh->shipto_cntct_id = $cntct->pid();
+        $sh->shipto_addr_id = $cntct->cntct_addr_id;
+        if ($sh->find(true)) {
+            return $sh->pid();
+        }
+        
+        $sh->setFrom(array(
+            'shipto_cust_id' => $cust_id,
+            'shipto_name' => $cntct->cntct_name,
+            'shipto_salesrep_id'=> $customer->cust_salesrep_id,
+            'shipto_active' => true,
+            'shipto_adefault' => false,
+            'shipto_shipchrg_id' => $customer->cust_shipchrg_id,
+            'shipto_taxzone_id' => $customer->cust_taxzone_id,
+            'shipto_shipform_id' => $customer->cust_shipform_id,
+            'shipto_commission' => 0,
+            'shipto_shipzone_id' => $customer->cust_taxzone_id
+
+        ));
+        $sh->genNum();
+        $sh->insert();
+        
+        return $sh->pid();
+        
+    }
+    
+    function orderShipments($toShipments,$d)
+    {
+        $this->debugLog('creating shipments');
+        
+        $ids = array_keys($toShipments);
+        $c = array_pop($toShipments);
+        
+        $cc = DB_DataObject::factory('coitem');
+        $cc->coitem_cohead_id = $c->coitem_cohead_id;
+        $cc->find();
+        
+        $x = array();
+        $shipitems = array();
+        while ($cc->fetch()){ // this query will take about 6 secs...
+            
+            $itemsite = $cc->itemsite();
+            // skip non-stock items..
+            if (!$itemsite->itemsite_stocked) {
+                continue;
+            }
+            
+            $x['shipitem_orderitem_id'] = $cc->pid();
+            $x['shipitem_qty'] = 0;
+            if(in_array($cc->pid(), $ids)){
+                $x['shipitem_qty'] = $cc->coitem_qtyord;
+            }
+            $shipitems[] = (object)$x;
+        }
+        
+        $sh = DB_DataObject::factory('shiphead');
+        
+        
+        
+        $sh->setFrom(array(
+            'shiphead_shipdate'        => $c->coitem_scheddate,
+            'shiphead_order_id'        => $c->coitem_cohead_id,
+            'shiphead_sfstatus'        => 'N',
+            'shiphead_location_id'     => $c->coitem_location_src,
+            'shiphead_shipto_id'       => $c->coitem_shipto_id,
+            //'shiphead_number'          => $cohead->cohead_number . substr($c->coitem_linenumber, 0, 4),
+            'shiphead_order_type'      => 'SO',
+            'shiphead_freight'         => 0, //$d['freight'],
+            'shiphead_freight_curr_id' => $d['curr'],
+            'shiphead_notes'           => '' // $r['SHIP NOTE']
+        ));
+        $sh->beforeInsert(array('shiphead_number' => 'Automatic'),$this);
+        //$this->jerr("about to create shipment: " . $sh->shiphead_number);
+        
+        $sh->insert();
+        
+        $sh->updateItems($shipitems, $this); 
+        
+        $sh->confirm($this); 
+    }
+    
+    function voidInvAndShipments($co)
+    {
+        $this->debugLog('deelting old invoices / shipments');
+        $invoices  = $co->cobmiscs();
+
+        foreach($invoices as $i) {
+            $i->void($this, true);
+        }
+
+        // do it twice..
+        $invoices  = $co->cobmiscs();
+        foreach($invoices as $i) {
+            $i->void($this,true);
+        }
+        // delete the shipments...
+        $shipheads = $co->shipheads();
+
+        foreach($shipheads  as $s) {
+
+            if (!empty($s->shiphead_shipped) && !empty($s->shiphead_shipdate)) {
+                $res = $s->unconfirm($this,true);
+
+                if ($res !== true) {
+                    $this->jerr("ship unconfirm failed:" . $res);
+                }
+            }
+
+            if (!empty($s->shiphead_shipdate)) { // 395.43042492867 secs...
+                $res = $s->void($this,true);    // void shipitem will take 0.1 sec for each... a little bit long time...
+
+                if ($res !== true) {
+                    $this->jerr("ship voiding failed" . $res)  ;
+                }
+            }
+        }
+    }
+    //B_45 not found
+    //B_12 not found
+    //B_1 not found
+    //B_11 not found
+    
+    // 210203 not found
+    // 212103 not found
+    // Gift Wrapping not found
+    // Gift Wrapping not found
+    // 212204 not found
+    // Gift Wrapping not found
+    
+    
+}
diff --git a/Import/MyCustomers.php b/Import/MyCustomers.php
new file mode 100644 (file)
index 0000000..b7b482f
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_MyCustomers extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('vendinfo');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        $this->importCsv($img->getStoreName());
+    }
+    
+    function importCsv($file)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $data = json_decode(file_get_contents($file), true);
+        if (!$data) {
+            $this->jerr("invalid file");
+        }
+        
+        foreach ($data as $d){
+            $custinfo = DB_DataObject::factory('custinfo');
+            
+            if($custinfo->get('cust_number', $d['cust_number'])){ // exsit.. do update
+                $cntct = $custinfo->cntct();
+                if(!$cntct->cntct_id){
+                    $cntct = $this->addCntct($d, $custinfo->pid());
+                }
+                
+                if(!$cntct->cntct_id){
+                    $this->jerr('error occur on insert a contact for ' . $d['cust_number']);
+                }
+                
+                $oldcust = clone($custinfo);
+                $custinfo->cust_cntct_id = $cntct->pid();
+                $custinfo->update($oldcust);
+                
+                $addr = $cntct->addr();
+                if(!$addr->addr_id){
+                   $addr =  $this->addAddr($d);
+                }
+                
+                if(!$addr->addr_id){
+                    $this->jerr('error occur on insert a address for ' . $d['cust_number']);
+                }
+                
+                $oldcn = clone($cntct);
+                $cntct->cntct_addr_id = $addr->pid();
+                $cntct->update($oldcn);
+                
+                $this->updateShipList($custinfo);
+                
+                continue; 
+            }
+              
+            $custinfo->setFrom(array(
+                'cust_active'            => $d['cust_active'],
+                'cust_salesrep_id'       => $this->salesrep($d['cust_salesrep_id_salesrep_number']),
+                'cust_name'              => $d['cust_name'],
+                'cust_number'            => $d['cust_number'],
+                'cust_terms_id'          => $this->terms($d['cust_terms_id_terms_code']),
+                'cust_taxzone_id'        => $this->taxzone($d['cust_taxzone_id_taxzone_code']),
+                'cust_curr_id'           => $custinfo->sqlValue("getcurrid('{$d['cust_curr_id_curr_abbr']}'::text)"),
+                'cust_creditlmt_curr_id' => $custinfo->sqlValue("getcurrid('{$d['cust_creditlmt_curr_id_curr_abbr']}'::text)")
+            ));
+                
+            foreach($custinfo->defaults() as $k=>$v) {
+                if (!isset($custinfo->$k)) {
+                    $custinfo->$k = $v;
+                }
+            }
+            
+            $custinfo->insert();
+            
+            if(!$custinfo->pid()){
+                $this->jerr("error occur on insert customer " . $d['cust_name']);
+            }
+            
+            $cntct = $this->addCntct($d, $custinfo->pid());
+            
+            if(!$cntct->pid()){
+                $this->jerr("error occur on insert contact for " . $d['cust_name']);
+            }
+            
+            $addr = $this->addAddr($d);
+            
+            if(!$addr->pid()){
+                $this->jerr("error occur on insert address for " . $d['cust_name']);
+            }
+            
+            $oldcn = clone($cntct);
+            $cntct->cntct_addr_id = $addr->pid();
+            $cntct->update($oldcn);
+            
+            $oldcust = clone($custinfo);
+            $custinfo->cust_cntct_id = $cntct->pid();
+            $custinfo->update($oldcust);
+            
+            $this->updateShipList($custinfo);
+            
+        }
+       
+        $this->jok("DONE");
+        
+        exit;
+    }
+    
+    function salesrep($salesrep_number)
+    {
+        $salesrep = DB_DataObject::factory('salesrep');
+        if(!$salesrep->get('salesrep_number', $salesrep_number)){
+            $salesrep->get('salesrep_number', 'ACCOUNTS');
+        }
+        return $salesrep->pid();
+        
+    }
+    
+    function terms($terms_code)
+    {
+        $terms = DB_DataObject::factory('terms');
+        if(!$terms->get('terms_code', $terms_code)){
+            $terms->get('terms_code', 'C.O.D.');
+        }
+        return $terms->pid();
+    }
+    
+    function taxzone($taxzone_code)
+    {
+        $taxzone = DB_DataObject::factory('taxzone');
+        if(!$taxzone->get('taxzone_code', $taxzone_code)){
+            $taxzone->get('taxzone_code', 'NO TAX');
+        }
+        return $taxzone->pid();
+    }
+    
+    function addCntct($d, $cid)
+    {
+        $cntct = DB_DataObject::factory('cntct');
+        $c = array(
+            'cntct_first_name'  => $d['cust_cntct_id_cntct_first_name'],
+            'cntct_last_name'   => $d['cust_cntct_id_cntct_last_name'],
+            'cntct_active'      => $d['cust_cntct_id_cntct_active'],
+            'cntct_phone'       => $d['cust_cntct_id_cntct_phone'],
+            'cntct_phone2'       => $d['cust_cntct_id_cntct_phone2'],
+            'cntct_phone2'       => $d['cust_cntct_id_cntct_phone2'],
+            'cntct_fax'         => $d['cust_cntct_id_cntct_fax'],
+            'cntct_email'       => $d['cust_cntct_id_cntct_email'],
+            'cntct_name'        => $d['cust_cntct_id_cntct_name'],
+            'cntct_crmacct_id'  => $cntct->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$cid})")
+        );
+        $cntct->createFromArray($c);
+        
+        return $cntct;
+    }
+    
+    function addAddr($d)
+    {
+        $addr = DB_DataObject::Factory('addr');
+        $addrs = array(
+            'addr_active'       => $d['cntct_addr_active'],
+            'addr_line1'        => $d['cntct_addr_line1'],
+            'addr_line2'        => $d['cntct_addr_line2'],
+            'addr_line3'        => $d['cntct_addr_line3'],
+            'addr_city'         => $d['cntct_addr_city'],
+            'addr_state'        => $d['cntct_addr_state'],
+            'addr_postalcode'   => $d['cntct_addr_postalcode'],
+            'addr_country'      => $d['cntct_addr_country'],
+            'addr_notes'        => $d['cntct_addr_notes'],
+        );
+
+        $addr->createFromArray($addrs);
+        
+        return $addr;
+    }
+    
+    function updateShipList($custinfo)
+    {
+        $cn = DB_DataObject::factory('cntct');
+        $cn->whereAdd("
+            cntct_crmacct_id = (SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$custinfo->pid()})
+        ");
+        $list = $cn->fetchAll('cntct_id');
+
+        $custinfo->updateShipList($list);
+    }
+        
+}
diff --git a/Import/Products.php b/Import/Products.php
new file mode 100644 (file)
index 0000000..0ae8f21
--- /dev/null
@@ -0,0 +1,295 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_Products extends Pman_Roo
+{
+    
+    /**
+     *  get .. same as roo... 
+     * 
+     */
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    
+    function get()
+    {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        //DB_DataObject::DebugLevel(1);
+        require_once 'File/Convert.php';
+        $fc = new File_Convert('/tmp/sku.csv', 'text/csv');
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    
+    function post( )
+    {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        $this->sessionState(0); // turn off the session..
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        //print_R($fc);exit;
+        //var_dump($csv);exit;
+        $this->importCsv($csv);
+    }
+    function importCsv($csv)
+    {
+       // $this->jerr("this is disabled at present - please email alan the file");
+        
+        ini_set('memory_limit', '1024M');
+        sleep(10); // sleep so the that progress dialog can close..
+        
+        ini_set("auto_detect_line_endings", true);
+
+         
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        $bom = "\xEF\xBB\xBF";
+        for ($i = 0; $i< 3;$i++) {
+            if ($bom[$i] != fgetc($fh)) {
+                fseek($fh,0);
+                break;
+            }
+            
+        }
+        
+        
+        
+        // we need to break this into cols..
+        $cols = false;
+        $rows = array();
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            
+            
+            
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                
+                if (!in_array('ITEM CODE',$cols)) {
+                    $this->jerr('missing ITEM CODE : ' . implode(' , ' , $cols));
+                
+                }
+                continue;
+            }
+            $row = array();
+            foreach($cols as $i=>$k) {
+                
+                if (($k == 'PALLET LOCATION') && !empty($row[$k])) {
+                    if (!strlen(trim($n[$i]))) {
+                        continue;
+                    }
+                    $row[$k] .= ','.trim($n[$i]);
+                    continue;
+                }
+                
+                $row[$k] = trim($n[$i]);
+            }
+            // ignore empty item codes
+            if (empty($row['ITEM CODE']) || !strlen(trim($row['ITEM CODE']))) {
+                continue;
+            }
+            
+            
+            
+            
+            //$row['ITEM CODE'] = strtoupper($row['ITEM CODE']);
+            $rows[] = $row;
+        }
+        
+        
+        
+        fclose($fh);
+        $dupes = array();
+        
+       // print_r($rows);exit;
+        $skipped = array();
+        $missing = array();
+        $nrows = array();
+        foreach($rows as $i => $row) {
+            
+            if (in_array($row['ITEM CODE'], $dupes)) {
+                continue;
+            }
+            
+            $i = DB_DataObject::factory('item')->lookupSKU($row['ITEM CODE']);
+            
+            if (!$i) {
+                
+                
+                
+                
+                if (empty($row['NEW DESCRIPTION'])) {
+                    $skipped[] = strtoupper($row['ITEM CODE']). '(missing NEW DESCRIPTION)';
+                    continue;
+                    
+                }
+                if (empty($row['NONPRODUCT']) &&
+                    
+            
+                  ( empty($row['CUR'])
+                  || !isset($row['NEW UNIT PRICE'])
+                  || !strlen(trim($row['NEW UNIT PRICE']))
+                ))  {
+                    
+                    $skipped[] = strtoupper($row['ITEM CODE']). '(missing price)';
+                    continue;
+                    
+                    //$this->jerr('for new items, NEW DESCRIPTION, CUR (currency) and NEW UNIT PRICE are needed.'. print_R($row,true));
+                }
+              
+            }
+            $dupes[]  = $row['ITEM CODE'];
+            $nrows[] = $row;
+        }
+        
+        
+        $rows = $nrows;
+       //print_r($rows);exit;
+        
+        $pc= DB_DataObject::factory('prodcat');
+        if (!$pc->get('prodcat_code', 'NONPRODUCT')) {
+            $this->jerr("product category NONPRODUCT missing");
+        }
+        $nonproduct = $pc; 
+        $pc= DB_DataObject::factory('prodcat');
+        if (!$pc->get('prodcat_code', 'PRODUCT')) {
+            $this->jerr("product category PRODUCT missing");
+        }       
+        $product = $pc;
+        //print_r($rows); exit;
+        $added = 0;
+        $updated = 0;
+        
+        foreach($rows as $i => $row) {
+            // verify data...
+            
+            $row['ITEM CODE'] = strtoupper($row['ITEM CODE']);
+            $skip = false;
+            
+            $opts = array();
+            $row['item_type'] = 'P';
+            $row['item_prodcat_id'] = $product->pid();
+            if (!empty($row['NONPRODUCT'])) {
+                
+                
+                $opts = array(
+                        'item_type'=> 'R', // reference item..
+                        'item_prodcat_id' => $nonproduct->pid()
+                );
+                foreach($opts as $k=>$v) {
+                    $row[$k] = $v;
+                }
+                
+            }
+            
+            $i = DB_DataObject::factory('item')->lookupSKU($row['ITEM CODE']);
+            if (!$i) {
+                $i = DB_Dataobject::Factory('item');
+                $i = $i->createNew($this,$row['ITEM CODE'],$row['NEW DESCRIPTION'] , $opts);
+                $added++;
+                
+            } else {
+                
+                $updated++;
+            }
+            $doupdate = false;
+            
+            $ii = clone($i);
+            if (!empty($row['NEW DESCRIPTION']) ) {
+                $i->item_descrip1 = $row['NEW DESCRIPTION'];
+                $doupdate = true;
+            }
+            if (!empty($row['NEW DESCRIPTION2']) ) {
+                $i->item_descrip2 = $row['NEW DESCRIPTION2'];
+                $doupdate = true;
+            }
+              if (!empty($row['NEW BARCODE']) ) {
+                $i->item_upccode= $row['NEW BARCODE'];
+                $doupdate = true;
+            }
+            
+            if ($i->item_type != $row['item_type']) {
+                $i->item_type = $row['item_type'];
+                $doupdate = true;
+            }
+            
+            if ($i->item_prodcat_id != $row['item_prodcat_id']) {
+                $i->item_prodcat_id = $row['item_prodcat_id'];
+                $doupdate = true;
+            }
+            //print_r($row);exit;
+            if ($doupdate) {
+                $i->update($ii);
+            }
+        
+            
+            
+            $is = DB_DataObject::Factory('itemsite');
+            $is = $is->createOrFetchFromItem($this, $i);
+            $is->fixItemsite($i);
+            
+            
+            if ($row['item_type'] == 'P') {
+                // update prices if found. -- and if a product
+                if (   !empty($row['CUR'])
+                      && isset($row['NEW UNIT PRICE'])
+                      && strlen(trim($row['NEW UNIT PRICE']))) {
+                    $i->updateItemCost($this, $row['CUR'], $row['NEW UNIT PRICE'], date('Y-m-d'));
+                }
+            }    
+            if (!empty($row['ITEM_CHAR_PRODUCTGROUP'])) {
+                $i->updateCharAss('PRODUCTGROUP', $row['ITEM_CHAR_PRODUCTGROUP']);
+            }
+            
+            if (!empty($row['ITEM_CHAR_BRAND'])) {
+                $i->updateCharAss('BRAND', $row['ITEM_CHAR_BRAND']);
+            }
+            if (!empty($row['ITEM_CHAR_PICKFACE_LOCATION'])) {
+                $i->updateCharAss('PICKFACE_LOCATION', $row['ITEM_CHAR_PICKFACE_LOCATION']);
+            }
+            if (!empty($row['PALLET LOCATION'])) {
+                $i->updateCharAss('PALLET_LOCATION', $row['PALLET LOCATION']);
+            }
+        }
+        $this->addEvent('PRODUCTIMPORT', false, 'Import succeeded');
+        
+        $this->jok( array(
+                'inserted' => $added,
+                'updated'  => $updated,
+                'skipped' => $skipped ? implode('\n', $skipped) : false,
+            )); 
+        
+         
+         
+    
+    }
+    
+}
diff --git a/Import/PurchaseOrder.php b/Import/PurchaseOrder.php
new file mode 100644 (file)
index 0000000..662ad0d
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_PurchaseOrder extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('poitem');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $pohead_id = $_REQUEST['pohead_id'];
+        
+        $req = array('ITEM CODE', 'ITEM DESCRIPTION', 'DUE DATE', 'LINE NUMBER', 'ORDERED', 'UNIT PRICE');
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        
+        // check pohead
+        $pohead = DB_DataObject::factory('pohead');
+        if(!$pohead->get($pohead_id)){
+            $this->jerr('error occur on finding pohead');
+        }
+        
+        // check poitem linenumber
+        $max_num = 0;
+        $poitem = DB_DataObject::factory('poitem');
+        $poitem->selectAdd();
+        $poitem->selectAdd("
+            MAX(poitem_linenumber) as max_num
+        ");
+        $poitem->poitem_pohead_id = $pohead->pid();
+        $poitem->find(true);
+        if(!empty($poitem->max_num)){
+            $max_num = $poitem->max_num;
+        }
+        
+        foreach($rows as $i => $row){
+            /* 
+             * check item and itemsite and itemsrc, 
+             * throw exception while the item or itemsite or itemsrc is not exist for the time being
+             * 
+             * we might need to new the item in the further
+             */
+            $item = DB_DataObject::factory('item');
+            if(!$item->get('item_number', $row['ITEM CODE'])){
+                $this->jerr('item ' . $row['ITEM CODE'] . ' does not exist');
+            }
+            $itemsite = DB_DataObject::factory('itemsite');
+            if(!$itemsite->get('itemsite_item_id', $item->pid())){
+                $this->jerr($row['ITEM CODE'] . ' does not exist in item site');
+            }
+            $itemsrc = DB_DataObject::factory('itemsrc');
+            if(!$itemsrc->get('itemsrc_item_id', $item->pid())){
+                $this->jerr($row['ITEM CODE'] . ' does not exist in item src');
+            }
+            
+            // create poitem 
+            $poitem = DB_DataObject::factory('poitem');
+            $poitem->setFrom(array(
+                'poitem_status' => $pohead->pohead_status,
+                'poitem_pohead_id' => $pohead->pid(),
+                'poitem_linenumber' => $max_num + ($i + 1),
+                'poitem_duedate' => $row['DUE DATE'],
+                'poitem_itemsite_id' => $itemsite->pid(),
+                'poitem_qty_ordered' => $row['ORDERED'],
+                'poitem_unitprice' => $row['UNIT PRICE'],
+                'poitem_itemsrc_id' => $itemsrc->pid()
+            ));
+            
+            foreach($poitem->defaults() as $k => $v){
+                if (!isset($poitem->$k)) {
+                    $poitem->$k = $v;
+                }
+            }
+            
+            $poitem->insert();
+            
+            if(!$poitem->pid()){
+                $this->jerr('error occur on insert poitem ' . $row['ITEM CODE']);
+            }
+            
+        }
+        
+        $this->jok('DONE');
+        
+        exit;
+    }
+}
diff --git a/Import/SalesOrder.php b/Import/SalesOrder.php
new file mode 100644 (file)
index 0000000..3ece9e9
--- /dev/null
@@ -0,0 +1,239 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_SalesOrder extends Pman_Roo
+{
+    
+    /**
+     *  get .. same as roo... 
+     * 
+     */
+    
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    
+    function get()
+    {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        $this->jerr("INVALID");
+        //DB_DataObject::DebugLevel(1);
+        require_once 'File/Convert.php';
+        $fc = new File_Convert('/tmp/sku.csv', 'text/csv');
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    
+    function post( )
+    {
+        
+        $this->sessionState(0); // turn off the session..
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        if (empty($_REQUEST['onid'])) {
+            $this->jerr('no order found');
+            
+        }
+        
+         
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        //print_R($fc);exit;
+        //var_dump($csv);exit;
+        $this->importCsv($csv);
+    }
+    function importCsv($csv)
+    {
+        
+        ini_set("auto_detect_line_endings", true);
+
+        $req = array('ITEM CODE', 'FROM', 'QTY', 'SALE PRICE');
+        
+        
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        $bom = "\xEF\xBB\xBF";
+        for ($i = 0; $i< 3;$i++) {
+            if ($bom[$i] != fgetc($fh)) {
+                fseek($fh,0);
+                break;
+            }
+            
+        }
+        
+        
+        
+        // we need to break this into cols..
+        $cols = false;
+        $rows = array();
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+             
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $k = ($k == 'CUST PRICE') ? 'SALE PRICE' : $k;
+                    $k = ($k == 'SALES PRICE') ? 'SALE PRICE' : $k;
+                    
+                    
+                    $cols[] = strtoupper(trim($k));
+                }
+                if (empty($cols)) {
+                    continue;
+                }
+                
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                        
+                    }
+                }
+                continue;
+            }
+            $row = array();
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+         
+        if (empty($cols)) {
+            $this->jerr("could not find a row with Item code / from, qty and sale price");
+        }
+        fclose($fh);
+        
+        
+        $cohead = DB_DataObject::Factory('cohead');
+        if (!$cohead->get($_REQUEST['onid'])) {
+            $this->jerr("order is not valid");
+        }
+        
+        // get the pricelist - just in case they did not fill in the prices..
+        
+        $cust = $cohead->cust();
+        $ipshead = $cust->priceList();
+        
+         
+        
+        //DB_DataObject::debugLevel(1);
+        $missing = array();
+        
+        foreach($rows as $row)
+        {
+            if (!strlen(trim(implode('', array_values($row))))) {
+                continue;
+            }
+            if (!strlen(trim($row['ITEM CODE']))) {
+                $missing[]  = implode('', array_values($row));
+            }
+            
+            
+            $item = DB_DataObject::factory('item')->lookupSKU($row['ITEM CODE']);
+            if (!$item) {
+                $missing[] = $row['ITEM CODE'];
+                continue;
+            }
+            if (!empty($missing)) {
+                continue;
+            }
+            
+            $itemsite = $item->itemsite();
+            
+            if (empty($row['SALE PRICE']) && !strlen($row['SALE PRICE'])) {
+                if (!$ipshead) {
+                    $this-jerr("customer does not have a price list set and The SALE PRICE column is empty.");
+                }
+                $row['SALE PRICE'] = $ipshead->itemPrice($item);
+            }
+            
+            $citem = DB_DataObject::Factory('coitem');
+            $citem->coitem_cohead_id =  $cohead->pid();
+            $citem->setFrom($citem->defaults());
+            $citem->setFrom(array(
+                
+                'coitem_itemsite_id' => $itemsite->pid(),
+                'coitem_location_src' => $this->location($row['FROM']),
+                'coitem_qtyord' => $row['QTY'],
+                'coitem_price' => $row['SALE PRICE'],
+                'coitem_custprice' => $row['SALE PRICE'],
+                // custprice????
+            ));
+            $citem->coitem_shipto_id = $cohead->cohead_shipto_id;
+            $citem->coitem_linenumber = $this->nextline($cohead);
+            $citem->insert();
+            
+        }
+        if (!empty($missing)) {
+            $this->jerr("missing these codes : " . implode("\n", $missing));
+        }
+        
+        $this->jok("IMPORTED");
+         
+    
+    }
+    
+    function itemsite($code) {
+        $t = DB_DataObject::Factory('itemsite');
+        $t->query("
+                  SELECT itemsite_id FROM itemsite LEFT JOIN item ON itemsite_item_id = item_id
+                  WHERE item_number = '{$t->escape($code)}'
+                  LIMIT 1;
+                  ");
+        if (!$t->fetch() || !$t->itemsite_id) {
+            $this->jerr("item not found " . $code);
+        }
+        return $t->itemsite_id;
+    }
+    function location($loc) {
+        $l = DB_DataObject::Factory('location');
+        if (!$l->get('location_name', $loc)) {
+            $this->jerr("could not find location $loc");
+        }
+        return $l->pid();
+    }
+    
+    function nextline($cohead)
+    {
+        static $line = false;
+        if ($line !== false) {
+            $line++;
+            return $line;
+        }
+        $t = DB_DataObject::Factory('coitem');
+        $t->selecTAdd();
+        $t->coitem_cohead_id = $cohead->pid();
+        $t->selectAdd('MAX(coitem_linenumber) as coitem_linenumber');
+        if (!$t->find(true)) {
+            $line = 1;
+            return $line;
+        }
+        $line = $t->coitem_linenumber +1;
+        return $line;
+    }
+        
+        
+        
+         
+}
diff --git a/Import/Transfer.php b/Import/Transfer.php
new file mode 100644 (file)
index 0000000..a94f3ce
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+
+require_once 'Pman/Core/ExcelToJson.php';
+
+class Pman_Xtuple_Import_Transfer extends Pman_Core_ExcelToJson
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        parent::post();
+    }
+    
+    function importCsv($csv)
+    {
+        $ret = parent::importCsv($csv);
+       
+        $data = $ret['data'];
+        
+        $ret['data'] =$ret['extra'];
+        
+        // can not handle extra data.. .as image calls back with result.data...
+        
+        
+        $lc = DB_DataObject::factory('location');
+        if(!empty($ret['extra']['From']) && $lc->get('location_name', $ret['extra']['From'])){
+            $ret['data']['invhist_transfer_from'] = $lc->pid();
+            $ret['data']['invhist_transfer_from_location_name'] = $lc->location_name;
+        }
+        
+        
+        $lt = DB_DataObject::factory('location');
+        if(!empty($ret['extra']['To']) && $lt->get('location_name', $ret['extra']['To'])){
+            $ret['data']['invhist_transfer_to'] = $lt->pid();
+            $ret['data']['invhist_transfer_to_location_name'] = $lt->location_name;
+        }
+        
+        $ourdb = substr($lt->database(), -2);
+        
+        $ltc = $lt->customer()->char('INTERNALCOMPANY');
+        
+        $ret['data']['isInter'] = 0;
+        if(strlen($ltc) && $ourdb != $ltc){
+            $ret['data']['isInter'] = 1;
+        }
+        
+        $errmsg = array();
+        
+        foreach ($data as $r){
+            $itemsite = DB_DataObject::factory('itemsite');
+            $itemsite->autoJoin();
+            $itemsite->whereAdd("UPPER(join_itemsite_item_id_item_id.item_number) = UPPER('{$itemsite->escape(trim($r['ITEM CODE']))}')");
+            if(!$itemsite->find(true)){
+                $errmsg[] = $r['ITEM CODE'];
+                continue;
+            }
+            
+            $ret['data']['items'][] = array(
+                'itemsite_item_id' => $itemsite->itemsite_item_id,
+                'itemsite_id' => $itemsite->pid(),
+                'itemsite_item_id_item_number' => trim($r['ITEM CODE']),
+                'itemsite_item_id_item_descrip1' => !empty($r['DESCRIPTION']) ? $r['DESCRIPTION'] : $itemsite->itemsite_item_id_item_descrip1,
+                'itemsite_qty' => $r['QUANTITY'],
+                'unit_price' => (strlen($ltc) && $ourdb != $ltc) ? $r['UNIT PRICE'] : ''
+            );
+        }
+        
+        if(count($errmsg)){
+            $this->jerr("MISSING \n" . implode("\n", $errmsg));
+        }
+        
+        return $ret;
+        
+    }
+    
+}
diff --git a/Import/Vendors.php b/Import/Vendors.php
new file mode 100644 (file)
index 0000000..04616ff
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Import_Vendors extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function post()
+    {
+        $this->transObj = DB_DataObject::Factory('vendinfo');
+        
+        $this->transObj->query('BEGIN');
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+        
+        $fh = fopen($csv, 'r');
+        if (!$fh) {
+            $this->jerr("invalid file");
+        }
+        
+        $req = array(
+            'ACTIVE STATUS', 'SUPPLIER', 'BALANCE', 'BALANCE TOTAL', 'COMPANY', 'MR, MRS',
+            'FIRST NAME', 'M.I.', 'LAST NAME', 'ADDRESS 1', 'ADDRESS 2', 'ADDRESS 3', 'ADDRESS 4',
+            'ADDRESS 5', 'CONTACT', 'PHONE', 'FAX', 'ALT. PHONE', 'ALT. CONTACT', 'EMAIL', 'PRINT ON CHEQUE AS',
+            'ACCOUNT NO.', 'SUPPLIER TYPE', 'TERMS', 'CREDIT LIMIT', 'TAX ID', 'NOTE'
+        );
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!$cols) {
+                
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = strtoupper(trim($k));
+                }
+               // print_r($cols);exit;
+                if (empty($cols)) {
+                    continue;
+                }
+                foreach($req as $r) {
+                    if (!in_array($r,$cols)) {
+                        $cols = false;
+                        break;
+                    }
+                }
+                continue;
+            }
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            $rows[] = $row;
+        }
+        
+        if (empty($cols)) {
+            $this->jerr("could not find a row with " . implode(' / ', $req));
+        }
+        
+        fclose($fh);
+        $tz = DB_DataObject::Factory('taxzone');
+        $tz->whereAdd("taxzone_code != 'NO TAX'");
+        if (!$tz->find(true)) {
+            $this->jerr("could not find tax zone for taxable");
+        }
+        
+        foreach ($rows as $row){
+            if(empty($row['SUPPLIER'])){
+                continue;
+            }
+            $vend = DB_DataObject::factory('vendinfo');
+            if($vend->get('vend_name',$row['SUPPLIER'])){
+                continue;
+            }
+            $vend->setFrom(array(
+                'vend_name'         => $row['SUPPLIER'],
+                'vend_active'       => $row['ACTIVE STATUS'] == 'Active' ? TRUE : FALSE,
+                'vend_comments'     => $row['NOTE'],
+                'vend_number'       => str_replace(' ', '', strtoupper($row['SUPPLIER'])),
+                'vend_terms_id'     => $this->terms($row['TERMS']),
+                'vend_taxzone_id'   => $tz->pid(),
+                'vend_vendtype_id'  => $vend->sqlValue("getvendtypeid('NORMAL'::text)"), // default set to NORMAL
+                'vend_accnt_id'     => -1
+//                'vend_addr_id'      => ''
+            ));
+            $vend->insert();
+            
+            if(!$vend->pid()){
+                $this->jerr("error occur on insert vendor " . $row['SUPPLIER']);
+            }
+        }
+        
+        $this->jok("DONE");
+        
+        
+        exit;
+    }
+    
+    function terms($terms_code)
+    {
+        $terms = DB_DataObject::factory('terms');
+        if(!$terms->get('terms_code', $terms_code)){
+            $terms->get('terms_code', 'C.O.D.');
+        }
+        return $terms->pid();
+    }
+}
diff --git a/Kingdee.php b/Kingdee.php
new file mode 100644 (file)
index 0000000..4c03b6a
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Kingdee extends Pman_Roo 
+{
+    
+    function getAuth() {
+        if(HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+
+    function fetchSchema($type)
+    {
+        $headers = array();
+        
+        // read header file
+        
+        require_once 'File/Convert.php';
+        
+        $fc = new File_Convert("Pman/Xtuple/Kingdee/Schema/{$type}_Header.csv", 'text/csv');
+        $content = $fc->convert('text/csv');
+        
+        $fh = fopen($content, 'r');
+        
+        if (!$fh) {
+            $this->jerr("invalid {$type}_Header file");
+        }
+        
+        $count = 1;
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            foreach($n as $k) {
+                if(empty($k)){
+                    continue;
+                }
+                $headers['Page' . $count][] = array(
+                                            'header' => trim($k),
+                                            'dataIndex' => preg_replace(array('/\s/','/\&|\.|\/|\-|\(|\)/'), array('_', ''), strtolower(trim($k))),
+                                            'width' => 75
+                                        );
+            }
+            
+            $count++;
+        }
+        
+        fclose($fh);
+        
+        // read schema file
+        
+        $fc = new File_Convert("Pman/Xtuple/Kingdee/Schema/{$type}_Schema.csv", 'text/csv');
+        $content = $fc->convert('text/csv');
+        
+        $fh = fopen($content, 'r');
+        
+        if (!$fh) {
+            $this->jerr("invalid {$type}_Schema file");
+        }
+        
+        $cols = false;
+        $rows = array();
+        
+        while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
+            if (!strlen(implode('', $n))) {
+                continue;
+            }
+            if (!$cols) {
+                $cols = array();
+                foreach($n as $k) {
+                    $cols[] = trim($k);
+                    if($k == 'FPage'){
+                        $headers['t_Schema'][] = array(
+                            'header' => trim($k),
+                            'dataIndex' => trim($k),
+                            'width' => 75
+                        );
+                        continue;
+                    }
+                    $headers['t_Schema'][] = array(
+                        'header' => trim($k),
+                        'dataIndex' => trim($k),
+                        'dataFormat' => 'string',
+                        'width' => 75
+                    );
+                }
+                
+                if (empty($cols)) {
+                    continue;
+                }
+                continue;
+            }
+            
+            foreach($cols as $i=>$k) {
+                $row[$k] = $n[$i];
+            }
+            
+            $rows[] = $row;
+            
+        }
+        
+        fclose($fh);
+        
+        $sheets = array();
+        
+        foreach ($headers as $k => $v){
+            $sheets[$k] = array(
+                'workbook' => $k,
+                'cols' => $v
+            );
+        }
+        
+        return array('SHEETS' => $sheets, 'SCHEMA' => $rows);
+    }
+}
diff --git a/Kingdee/Account.php b/Kingdee/Account.php
new file mode 100644 (file)
index 0000000..7641eb4
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+
+require_once 'Pman/Roo.php';
+require_once 'Pman/Xtuple/Kingdee.php';
+
+class Pman_Xtuple_Kingdee_Account extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get()
+    {   
+        $Kingdee = new Pman_Xtuple_Kingdee();
+        
+        $result = $Kingdee->fetchSchema('Account');
+        
+        $data['Page1'] = $this->fetchData();
+        $data['Page2'] = array(); // seems we do not have this
+        
+        $data['t_Schema'] = $result['SCHEMA'];
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $result['SHEETS'],
+        ));
+        
+        $x->send('Account.xls');
+        
+    }
+    
+    function fetchData()
+    {
+        /*
+         *  check the alternative code 
+         *  if an account has transactions and there is not a alt code for it - then display an error
+         */
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->checkAlternativeCode($this, true);
+        
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->accnt_avtive = 1;
+        $accnt->autoJoin();
+        $accnt->_join .= "
+            LEFT JOIN
+                bankaccnt
+            ON
+                bankaccnt_accnt_id = accnt_id
+        ";
+        $accnt->selectAdd();
+        $accnt->selectAdd("
+            accnt_code_alt AS ac_code,
+            CASE WHEN (accnt_descrip_alt IS NOT NULL AND accnt_descrip_alt != '') THEN
+                accnt_descrip_alt
+            ELSE
+                accnt_descrip
+            END AS account_name,
+            
+            '' AS mnemonic_code,
+            'Current Assets' AS account_category_fname,
+            CASE WHEN accnt_type = 'A' THEN
+                -1
+            ELSE
+                1
+            END AS balance_direction,
+            curr_name AS accounting_in_foreign_currency_fnumber,
+            'FALSE' AS adjust_eop_exchange_rate,
+            'FALSE' AS transaction_accounting,
+            'FALSE' AS qtyamt_accounting,
+            '' AS uom_group_fname,
+            '*' AS uom_fname,
+            '' AS uom_fgroupname,
+            'FALSE' AS cash_account,
+            CASE WHEN bankaccnt_id IS NULL THEN
+                'FALSE'
+            ELSE
+                'TRUE'
+            END AS bank_account,
+            CASE WHEN bankaccnt_id IS NULL THEN
+                'FALSE'
+            ELSE
+                'TRUE'
+            END AS daily_journal,
+            'FALSE' AS cash_flow_account,
+            'FASLE' AS account_int,
+            0 AS daily_rate,
+            0 AS accounting_item,
+            0 AS account_system_controlled,
+            'FALSE' AS budget_account,
+            '*' AS cash_flow_item_fname,
+            '*' AS cash_flow_item_fnumber,
+            '*' AS accompanying_item_fname,
+            '*' AS accompanying_item_fnumber,
+            'FALSE' AS disable
+            
+        ");
+        $accnt->whereAdd("
+            accnt_code_alt IS NOT NULL
+            AND
+            accnt_code_alt != ''
+        ");
+        
+        return $accnt->fetchAll();
+    }
+}
diff --git a/Kingdee/Currency.php b/Kingdee/Currency.php
new file mode 100644 (file)
index 0000000..760f1ef
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+require_once 'Pman/Roo.php';
+require_once 'Pman/Xtuple/Kingdee.php';
+
+class Pman_Xtuple_Kingdee_Currency extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get()
+    {   
+        $Kingdee = new Pman_Xtuple_Kingdee();
+        
+        $result = $Kingdee->fetchSchema('Currency');
+        
+        $data['Page1'] = $this->fetchData();
+        
+        $data['t_Schema'] = $result['SCHEMA'];
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $result['SHEETS'],
+        ));
+        
+        $x->send('Currency.xls');
+        
+    }
+    
+    function fetchData()
+    {
+        $curr_rate = DB_DataObject::factory('curr_rate');
+        $curr_rate->autoJoin();
+        $curr_rate->selectAdd();
+        $curr_rate->selectAdd("
+            curr_name as code,
+            curr_name as name,
+            curr_rate AS exchange_rate,
+            4 AS decimal_places,
+            '*' AS exchange_rate_calculation_method,
+            0 AS fixed_exchange_rate,
+            'FALSE' AS disable
+        ");
+        return $curr_rate->fetchAll();
+    }
+}
diff --git a/Kingdee/Rate.php b/Kingdee/Rate.php
new file mode 100644 (file)
index 0000000..9e21e4c
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+
+require_once 'Pman/Roo.php';
+require_once 'Pman/Xtuple/Kingdee.php';
+
+class Pman_Xtuple_Kingdee_Rate extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get()
+    {   
+        $Kingdee = new Pman_Xtuple_Kingdee();
+        
+        $result = $Kingdee->fetchSchema('Rate');
+       
+        $data = $this->fetchData();
+        
+        $data['t_Schema'] = $result['SCHEMA'];
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $result['SHEETS'],
+        ));
+        
+        $x->send('Exchange Rate System.xls');
+        
+    }
+    
+    function fetchData()
+    {
+        $page1 = array(
+            array(
+                'isn' => 1,
+                'code' => '01',
+                'name' => '公司汇率',
+                'details_yn' => 0,
+                'parent_isn' => 0,
+                'exchange_rate_precision' => 6,
+                'remarks' => ''
+            ),
+            array(
+                'isn' => 4,
+                'code' => '04',
+                'name' => '预算汇率',
+                'details_yn' => 0,
+                'parent_isn' => 0,
+                'exchange_rate_precision' => 6,
+                'remarks' => ''
+            ),
+            array(
+                'isn' => 101,
+                'code' => '01.Native',
+                'name' => '01.Native',
+                'details_yn' => 1,
+                'parent_isn' => 1,
+                'exchange_rate_precision' => 6,
+                'remarks' => ''
+            ),
+            array(
+                'isn' => 104,
+                'code' => '04.Native',
+                'name' => '04.Native',
+                'details_yn' => 1,
+                'parent_isn' => 4,
+                'exchange_rate_precision' => 6,
+                'remarks' => ''
+            )
+        );
+        
+        
+        $curr_rate = DB_DataObject::factory('curr_rate');
+        $curr_rate->autoJoin();
+        $curr_rate->whereAdd("join_curr_id_curr_id.curr_base = false");
+        $curr_rate->selectAdd("
+            ((row_number() OVER()) + 1000 ) AS isn,
+            ('01.' || curr_name || '.' || replace(startOfTime()::text,'-','')) AS code,
+            ('公司汇率.' || curr_name || '.19700101') AS name,
+            1 AS details_yn,
+            1 AS parent_isn,
+            0 AS exchange_rate_precision,
+            '' AS remarks
+        ");
+        
+        $rates = $curr_rate->fetchAll();
+        
+        $data = array();
+        $data['Page1'] = array_merge($page1, $rates);
+        
+        
+        $page2 = array(
+            array(
+                'name' => '01.Native',
+                'code' => '01.Native',
+                'isn' => '101',
+                'currency_code_fndname' => 'RMB',
+                'exchange_rate' => 1,
+                'effective_date' => '1970-01-01',
+                'expiry_date' => '2100-01-01',
+                'exrate_type_fndname' => '01',
+                'exrate_type_dspname' => '公司汇率',
+                'approver_fndname' => '',
+                'approval_date' => ''
+            ),
+            array(
+                'name' => '04.Native',
+                'code' => '04.Native',
+                'isn' => '104',
+                'currency_code_fndname' => 'RMB',
+                'exchange_rate' => 1,
+                'effective_date' => '1970-01-01',
+                'expiry_date' => '2100-01-01',
+                'exrate_type_fndname' => '01',
+                'exrate_type_dspname' => '预算汇率',
+                'approver_fndname' => '',
+                'approval_date' => ''
+            )
+        );
+        
+        foreach ($rates as $r){
+            $page2[] = array(
+                'name' => $r->name,
+                'code' => $r->code,
+                'isn' => $r->isn,
+                'currency_code_fndname' => $r->curr_id_curr_name,
+                'exchange_rate' => $r->curr_rate,
+                'effective_date' => $r->curr_effective,
+                'expiry_date' => $r->curr_expires,
+                'exrate_type_fndname' => '01',
+                'exrate_type_dspname' => '公司汇率',
+                'approver_fndname' => '',
+                'approval_date' => ''
+            );
+        }
+        
+        $data['Page2'] = $page2;
+        
+        return $data;
+        
+    }
+}
diff --git a/Kingdee/Schema/Account_Header.csv b/Kingdee/Schema/Account_Header.csv
new file mode 100644 (file)
index 0000000..5706705
--- /dev/null
@@ -0,0 +1,2 @@
+A/C Code,Account Name,Mnemonic Code,Account Category_FName,Balance Direction,Accounting in Foreign Currency_FNumber,Adjust EoP Exchange Rate,Transaction Accounting,Qty-Amt Accounting,UoM Group_FName,UoM_FName,UoM_FGroupName,Cash Account,Bank Account,Daily Journal,Cash Flow Account,Account Int.,Daily Rate,Accounting Item,Account System Controlled ,Budget Account,Cash Flow Item_FName,Cash Flow Item_FNumber,Accompanying Item_FName,Accompanying Item_FNumber,Disable
+A/C Code,Account Name,Accounting Item Code,Accounting Item Name,,,,,,,,,,,,,,,,,,,,,,
diff --git a/Kingdee/Schema/Account_Schema.csv b/Kingdee/Schema/Account_Schema.csv
new file mode 100644 (file)
index 0000000..944eddd
--- /dev/null
@@ -0,0 +1,32 @@
+FType,FKey,FFieldName,FCaption,FValueType,FNeedSave,FColIndex,FSrcTableName,FSrcFieldName,FExpFieldName,FImpFieldName,FDefaultVal,FSearch,FItemPageName,FTrueType,FPrecision,FSearchName,FIsShownList,FViewMask,FPage
+ClassInfo,ClassType,,BaseData,,,,,,,,,,,,,,,,
+ClassInfo,ClassTypeID,, 105,,,,,,,,,,,,,,,,
+PageInfo,Page1,,Page1,,,,,,,,,,,,,,,,
+FieldInfo,FNumber,FNumber,A/C Code, Varchar(40),,1,,,,,,0,,,0,0,0,0,1
+FieldInfo,FName,FName,Account Name, Varchar(160),,2,,,,,,0,,,0,0,0,0,1
+FieldInfo,FHelperCode,FHelperCode,Mnemonic Code, Varchar(40),,3,,,,,,0,,,0,0,0,0,1
+FieldInfo,FGroupID,FGroupID,Account Category,nvarchar(255),,4,t_AcctGroup,FGroupID,FName,FName,,0,,,0,0,0,0,1
+FieldInfo,FDC,FDC,Balance Direction," Decimal(28,10)",,5,,,,,,0,,,0,0,0,0,1
+FieldInfo,FCurrencyID,FCurrencyID,Accounting in Foreign Currency,nvarchar(255),,6,t_Currency,FCurrencyID,FNumber,FNumber,,0,,,0,0,0,0,1
+FieldInfo,FAdjustRate,FAdjustRate,Adjust EoP Exchange Rate, bit,,7,,,,,,0,,,0,0,0,0,1
+FieldInfo,FContact,FContact,Transaction Accounting, bit,,8,,,,,,0,,,0,0,0,0,1
+FieldInfo,FQuantities,FQuantities,Qty-Amt Accounting, bit,,9,,,,,,0,,,0,0,0,0,1
+FieldInfo,FUnitGroupID,FUnitGroupID,UoM Group,nvarchar(255),,10,vwUnitGroup,FItemID,FName,FName,,0,,,0,0,0,0,1
+FieldInfo,FMeasureUnitID,FMeasureUnitID,UoM,nvarchar(255),,11,t_MeasureUnit,FMeasureUnitID,FName+FGroupName,FName+FGroupName,,0,,,0,0,0,0,1
+FieldInfo,FIsCash,FIsCash,Cash Account, bit,,12,,,,,,0,,,0,0,0,0,1
+FieldInfo,FIsBank,FIsBank,Bank Account, bit,,13,,,,,,0,,,0,0,0,0,1
+FieldInfo,FJournal,FJournal,Daily Journal, bit,,14,,,,,,0,,,0,0,0,0,1
+FieldInfo,FIsCashFlow,FIsCashFlow,Cash Flow Account, bit,,15,,,,,,0,,,0,0,0,0,1
+FieldInfo,FAcctint,FAcctint,Account Int., bit,,16,,,,,,0,,,0,0,0,0,1
+FieldInfo,FintRate,FintRate,Daily Rate,"decimal(28,10)",,17,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDetailID,FDetailID,Accounting Item," Decimal(28,10)",,18,,,,,,0,,,0,0,0,0,1
+FieldInfo,FControlSystem,FControlSystem,Account System Controlled," Decimal(28,10)",,19,,,,,,0,,,0,0,0,0,1
+FieldInfo,FIsBudget,FIsBudget,Budget Account, bit,,20,,,,,,0,,,0,0,0,0,1
+FieldInfo,FCFItemID,FCFItemID,Cash Flow Item,nvarchar(255),,21,t_Item,FItemID,FName+FNumber,FNumber,,0,,,0,0,0,0,1
+FieldInfo,FSubCFItemID,FSubCFItemID,Accompanying Item,nvarchar(255),,22,t_Item,FItemID,FName+FNumber,FNumber,,0,,,0,0,0,0,1
+FieldInfo,FDelete,FDelete,Disable, bit,,23,,,,,,0,,,0,0,0,0,1
+PageInfo,Page2,,Page2,,,,,,,,,,,,,,,,
+FieldInfo,FAccountFNumber,FAccountFNumber,A/C Code, Varchar(128),,1,,,,,,0,,,0,0,0,2,2
+FieldInfo,FAccountFName,FAccountFName,Account Name, Varchar(128),,2,,,,,,0,,,0,0,0,2,2
+FieldInfo,FItemClassNumber,FItemClassNumber,Accounting Item Code, Varchar(255),,3,,,,,,0,,,0,0,0,0,2
+FieldInfo,FItemClassName,FItemClassName,Accounting Item Name, Varchar(255),,4,,,,,,0,,,0,0,0,0,2
diff --git a/Kingdee/Schema/Currency_Header.csv b/Kingdee/Schema/Currency_Header.csv
new file mode 100644 (file)
index 0000000..599e4c7
--- /dev/null
@@ -0,0 +1 @@
+Code,Name,Exchange Rate,Decimal Places,Exchange Rate Calculation Method,Fixed Exchange Rate,Disable
diff --git a/Kingdee/Schema/Currency_Schema.csv b/Kingdee/Schema/Currency_Schema.csv
new file mode 100644 (file)
index 0000000..c7c13ac
--- /dev/null
@@ -0,0 +1,11 @@
+FType,FKey,FFieldName,FCaption,FValueType,FNeedSave,FColIndex,FSrcTableName,FSrcFieldName,FExpFieldName,FImpFieldName,FDefaultVal,FSearch,FItemPageName,FTrueType,FPrecision,FSearchName,FIsShownList,FViewMask,FPage
+ClassInfo,ClassType,,BaseData,,,,,,,,,,,,,,,,
+ClassInfo,ClassTypeID,,120,,,,,,,,,,,,,,,,
+PageInfo,Page1,,Page1,,,,,,,,,,,,,,,,
+FieldInfo,FNumber,FNumber,Code, Varchar(10),,1,,,,,,0,,,0,0,0,0,1
+FieldInfo,FName,FName,Name, Varchar(40),,2,,,,,,0,,,0,0,0,0,1
+FieldInfo,FExchangeRate,FExchangeRate,Exchange Rate,"decimal(28,10)",,3,,,,,,0,,,0,0,0,0,1
+FieldInfo,FScale,FScale,Decimal Places," Decimal(28,10)",,4,,,,,,0,,,0,0,0,0,1
+FieldInfo,FOperator,FOperator,Exchange Rate Calculation Method, Varchar(10),,5,,,,,,0,,,0,0,0,0,1
+FieldInfo,FFixRate,FFixRate,Fixed Exchange Rate," Decimal(28,10)",,6,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDeleted,FDeleted,Disable, bit,,7,,,,,,0,,,0,0,0,0,1
diff --git a/Kingdee/Schema/Rate_Header.csv b/Kingdee/Schema/Rate_Header.csv
new file mode 100644 (file)
index 0000000..93e2537
--- /dev/null
@@ -0,0 +1,2 @@
+ISN,Code,Name,Details (Y/N),Parent ISN,Exchange Rate Precision,Remarks,,,,
+Name,Code,ISN,Currency Code_FNDName,Exchange Rate,Effective Date,Expiry Date,Ex.Rate Type_FNDName,Ex.Rate Type_DSPName,Approver_FNDName,Approval Date
diff --git a/Kingdee/Schema/Rate_Schema.csv b/Kingdee/Schema/Rate_Schema.csv
new file mode 100644 (file)
index 0000000..465581e
--- /dev/null
@@ -0,0 +1,22 @@
+FType,FKey,FFieldName,FCaption,FValueType,FNeedSave,FColIndex,FSrcTableName,FSrcFieldName,FExpFieldName,FImpFieldName,FDefaultVal,FSearch,FItemPageName,FTrueType,FPrecision,FSearchName,FIsShownList,FViewMask,FPage
+ClassInfo,ClassType,,BosBill,,,,,,,,,,,,,,,,
+ClassInfo,ClassTypeID,,1014002,,,,,,,,,,,,,,,,
+PageInfo,Page1,,Page1,,,,,,,,,,,,,,,,
+FieldInfo,FID,FID,ISN," Decimal(28,10)",,1,,,,,,0,,,0,0,0,0,1
+FieldInfo,FNumber,FNumber,Code, Varchar(255),,2,,,,,,0,,,0,0,0,0,1
+FieldInfo,FName,FName,Name, Varchar(255),,3,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDetail,FDetail,Details (Y/N)," Decimal(28,10)",,4,,,,,,0,,,0,0,0,0,1
+FieldInfo,FParentID,FParentID,Parent ISN," Decimal(28,10)",,6,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDigits,FDigits,Exchange Rate Precision," Decimal(28,10)",,8,,,,,,0,,,0,0,0,0,1
+FieldInfo,FRemark,FRemark,Remarks, Varchar(255),,9,,,,,,0,,,0,0,0,0,1
+PageInfo,Page2,,Page2,,,,,,,,,,,,,,,,
+FieldInfo,FParentName,FParentName,Name, Varchar(255),,1,,,,,,0,,,0,0,0,0,2
+FieldInfo,FParentNumber,FParentNumber,Code, Varchar(255),,2,,,,,,0,,,0,0,0,0,2
+FieldInfo,FID2,FID2,ISN," Decimal(28,10)",,3,,,,,,0,,,0,0,0,0,2
+FieldInfo,FBase,FBase,Currency Code,nvarchar(255),,4,t_Currency,FCurrencyID,FNDName,FNDName,,0,,,0,0,0,0,2
+FieldInfo,FExchangeRate,FExchangeRate,Exchange Rate," Decimal(28,10)",,6,,,,,,0,,,0,0,0,0,2
+FieldInfo,FBegDate,FBegDate,Effective Date, varchar(30),,7,,,,,,0,,,0,0,0,0,2
+FieldInfo,FEndDate,FEndDate,Expiry Date, varchar(30),,8,,,,,,0,,,0,0,0,0,2
+FieldInfo,FExchangeRateType,FExchangeRateType,Ex.Rate Type,nvarchar(255),,9,v_BASE_ExRateType,FID,FNDName+DSPName,FNDName,,0,,,0,0,0,0,2
+FieldInfo,FChkUserID,FChkUserID,Approver,nvarchar(255),,10,t_User,FUserID,FNDName,FNDName,,0,,,0,0,0,0,2
+FieldInfo,FChkDate,FChkDate,Approval Date, varchar(30),,11,,,,,,0,,,0,0,0,0,2
diff --git a/Kingdee/Schema/VoucherGroup_Header.csv b/Kingdee/Schema/VoucherGroup_Header.csv
new file mode 100644 (file)
index 0000000..54b9a18
--- /dev/null
@@ -0,0 +1 @@
+Name,Accounts must be contained in Credit Entries,Essential to Debit and Credit,Accounts not permitted in Debit Entries,Accounts not Permitted in Credit Entries,Accounts must be contained in Debit Entries,Impossible for Debit and Credit,Limit Multi-debit & Multi-credit,Default,Disable
diff --git a/Kingdee/Schema/VoucherGroup_Schema.csv b/Kingdee/Schema/VoucherGroup_Schema.csv
new file mode 100644 (file)
index 0000000..94ec8e0
--- /dev/null
@@ -0,0 +1,14 @@
+FType,FKey,FFieldName,FCaption,FValueType,FNeedSave,FColIndex,FSrcTableName,FSrcFieldName,FExpFieldName,FImpFieldName,FDefaultVal,FSearch,FItemPageName,FTrueType,FPrecision,FSearchName,FIsShownList,FViewMask,FPage
+ClassInfo,ClassType,,BaseData,,,,,,,,,,,,,,,,
+ClassInfo,ClassTypeID,,3,,,,,,,,,,,,,,,,
+PageInfo,Page1,,Page1,,,,,,,,,,,,,,,,
+FieldInfo,FName,FName,Name, Varchar(160),,1,,,,,,0,,,0,0,0,0,1
+FieldInfo,FCRange,FCRange,Accounts must be contained in Credit Entries, Varchar(50),,2,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDCRange,FDCRange,Essential to Debit and Credit, Varchar(50),,3,,,,,,0,,,0,0,0,0,1
+FieldInfo,FNDRange,FNDRange,Accounts not permitted in Debit Entries, Varchar(50),,4,,,,,,0,,,0,0,0,0,1
+FieldInfo,FNCRange,FNCRange,Accounts not Permitted in Credit Entries, Varchar(50),,5,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDRange,FDRange,Accounts must be contained in Debit Entries, Varchar(50),,6,,,,,,0,,,0,0,0,0,1
+FieldInfo,FNDCRange,FNDCRange,Impossible for Debit and Credit, Varchar(50),,7,,,,,,0,,,0,0,0,0,1
+FieldInfo,FLimitMulti,FLimitMulti,Limit Multi-debit & Multi-credit, bit,,8,,,,,,0,,,0,0,0,0,1
+FieldInfo,FStandard,FStandard,Default, bit,,9,,,,,,0,,,0,0,0,0,1
+FieldInfo,FDeleted,FDeleted,Disable, bit,,10,,,,,,0,,,0,0,0,0,1
diff --git a/Kingdee/Schema/Voucher_Header.csv b/Kingdee/Schema/Voucher_Header.csv
new file mode 100644 (file)
index 0000000..ddb3aaa
--- /dev/null
@@ -0,0 +1 @@
+Voucher Date,FY,Fiscal Period,Voucher Category,Voucher No.,A/C Code,Account Name,Currency Code,Currency Name,Amount (Original Currency),Debit,Credit,Created by,Check,Authorize,Cashier,Handler,Settlement Method,Settlement No.,Voucher Description,Qty,Operation(O),Unit Price,Ref. Info,Trans. Dt.,Transaction No.,Attachments,S/N,System Module,Business Description,Ex.Rate Type,Exchange Rate,Entry S/N,Accounting Item,Post,System-generated Voucher,Cash Flow
diff --git a/Kingdee/Schema/Voucher_Schema.csv b/Kingdee/Schema/Voucher_Schema.csv
new file mode 100644 (file)
index 0000000..1636781
--- /dev/null
@@ -0,0 +1,41 @@
+FType,FKey,FFieldName,FCaption,FValueType,FNeedSave,FColIndex,FSrcTableName,FSrcFieldName,FExpFieldName,FImpFieldName,FDefaultVal,FSearch,FItemPageName,FTrueType,FPrecision,FSearchName,FIsShownList,FViewMask,FPage
+ClassInfo,ClassType,,VoucherData,,,,,,,,,,,,,,,,
+ClassInfo,ClassTypeID,,123,,,,,,,,,,,,,,,,
+PageInfo,Page1,,Page1,,,,,,,,,,,,,,,,
+FieldInfo,FDate,FDate,Voucher Date, DateTime,,1,,,FDate,FDate,,0,,,0,0,0,0,1
+FieldInfo,FYear,FYear,FY," Decimal(28,10)",,2,,,FYear,FYear,,0,,,0,0,0,0,1
+FieldInfo,FPeriod,FPeriod,Fiscal Period," Decimal(28,10)",,3,,,FPeriod,FPeriod,,0,,,0,0,0,0,1
+FieldInfo,FGroupID,FGroupID,Voucher Category, Varchar(80),,4,,,FGroupID,FGroupID,,0,,,0,0,0,0,1
+FieldInfo,FNumber,FNumber,Voucher No.," Decimal(28,10)",,5,,,FNumber,FNumber,,0,,,0,0,0,0,1
+FieldInfo,FAccountNum,FAccountNum,A/C Code, Varchar(40),,7,,,FAccountNum,FAccountNum,,0,,,0,0,0,0,1
+FieldInfo,FAccountName,FAccountName,Account Name, Varchar(255),,8,,,FAccountName,FAccountName,,0,,,0,0,0,0,1
+FieldInfo,FCurrencyNum,FCurrencyNum,Currency Code, Varchar(10),,9,,,FCurrencyNum,FCurrencyNum,,0,,,0,0,0,0,1
+FieldInfo,FCurrencyName,FCurrencyName,Currency Name, Varchar(40),,10,,,FCurrencyName,FCurrencyName,,0,,,0,0,0,0,1
+FieldInfo,FAmountFor,FAmountFor,Amount (Original Currency)," Decimal(28,10)",,11,,,FAmountFor,FAmountFor,,0,,,0,0,0,0,1
+FieldInfo,FDebit,FDebit,Debit," Decimal(28,10)",,12,,,FDebit,FDebit,,0,,,0,0,0,0,1
+FieldInfo,FCredit,FCredit,Credit," Decimal(28,10)",,13,,,FCredit,FCredit,,0,,,0,0,0,0,1
+FieldInfo,FPreparerID,FPreparerID,Created by, Varchar(255),,14,,,FPreparerID,FPreparerID,,0,,,0,0,0,0,1
+FieldInfo,FCheckerID,FCheckerID,Check, Varchar(255),,15,,,FCheckerID,FCheckerID,,0,,,0,0,0,0,1
+FieldInfo,FApproveID,FApproveID,Authorize, Varchar(255),,17,,,FApproveID,FApproveID,,0,,,0,0,0,0,1
+FieldInfo,FCashierID,FCashierID,Cashier, Varchar(255),,18,,,FCashierID,FCashierID,,0,,,0,0,0,0,1
+FieldInfo,FHandler,FHandler,Handler, Varchar(50),,19,,,FHandler,FHandler,,0,,,0,0,0,0,1
+FieldInfo,FSettleTypeID,FSettleTypeID,Settlement Method, Varchar(80),,20,,,FSettleTypeID,FSettleTypeID,,0,,,0,0,0,0,1
+FieldInfo,FSettleNo,FSettleNo,Settlement No., Varchar(255),,21,,,FSettleNo,FSettleNo,,0,,,0,0,0,0,1
+FieldInfo,FExplanation,FExplanation,Voucher Description, Varchar(255),,22,,,FExplanation,FExplanation,,0,,,0,0,0,0,1
+FieldInfo,FQuantity,FQuantity,Qty, Varchar(10),,23,,,FQuantity,FQuantity,,0,,,0,0,0,0,1
+FieldInfo,FMeasureUnitID,FMeasureUnitID,Operation(O), Varchar(255),,24,,,FMeasureUnitID,FMeasureUnitID,,0,,,0,0,0,0,1
+FieldInfo,FUnitPrice,FUnitPrice,Unit Price, Varchar(10),,25,,,FUnitPrice,FUnitPrice,,0,,,0,0,0,0,1
+FieldInfo,FReference,FReference,Ref. Info, Varchar(255),,26,,,FReference,FReference,,0,,,0,0,0,0,1
+FieldInfo,FTransDate,FTransDate,Trans. Dt., DateTime,,27,,,FTransDate,FTransDate,,0,,,0,0,0,0,1
+FieldInfo,FTransNo,FTransNo,Transaction No., Varchar(255),,28,,,FTransNo,FTransNo,,0,,,0,0,0,0,1
+FieldInfo,FAttachments,FAttachments,Attachments," Decimal(28,10)",,29,,,FAttachments,FAttachments,,0,,,0,0,0,0,1
+FieldInfo,FSerialNum,FSerialNum,S/N," Decimal(28,10)",,30,,,FSerialNum,FSerialNum,,0,,,0,0,0,0,1
+FieldInfo,FObjectName,FObjectName,System Module, Varchar(100),,31,,,FObjectName,FObjectName,,0,,,0,0,0,0,1
+FieldInfo,FParameter,FParameter,Business Description, Varchar(100),,32,,,FParameter,FParameter,,0,,,0,0,0,0,1
+FieldInfo,FExchangeRateType,FExchangeRateType,Ex.Rate Type, Varchar(80),,33,,,FExchangeRateType,FExchangeRateType,,0,,,0,0,0,0,1
+FieldInfo,FExchangeRate,FExchangeRate,Exchange Rate, Varchar(10),,34,,,FExchangeRate,FExchangeRate,,0,,,0,0,0,0,1
+FieldInfo,FEntryID,FEntryID,Entry S/N," Decimal(28,10)",,35,,,FEntryID,FEntryID,,0,,,0,0,0,0,1
+FieldInfo,FItem,FItem,Accounting Item,Text,,36,,,FItem,FItem,,0,,,0,0,0,0,1
+FieldInfo,FPosted,FPosted,Post," Decimal(28,10)",,37,,,FPosted,FPosted,,0,,,0,0,0,0,1
+FieldInfo,FInternalInd,FInternalInd,System-generated Voucher, Varchar(10),,38,,,FInternalInd,FInternalInd,,0,,,0,0,0,0,1
+FieldInfo,FCashFlow,FCashFlow,Cash Flow,Text,,39,,,FCashFlow,FCashFlow,,0,,,0,0,0,0,1
diff --git a/Kingdee/Voucher.php b/Kingdee/Voucher.php
new file mode 100644 (file)
index 0000000..41fc673
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+require_once 'Pman/Roo.php';
+require_once 'Pman/Xtuple/Kingdee.php';
+
+class Pman_Xtuple_Kingdee_Voucher extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get()
+    {
+//        if(empty($_REQUEST['_as_of'])){
+//            $this->jerr('Missing argument - date');
+//        }
+        
+        ini_set('memory_limit', '1024M'); 
+        
+        $Kingdee = new Pman_Xtuple_Kingdee();
+        
+        $result = $Kingdee->fetchSchema('Voucher');
+        
+//        $data['Page1'] = $this->fetchData($_REQUEST['_as_of']);
+        $data['Page1'] = $this->fetchData();
+        
+        $data['t_Schema'] = $result['SCHEMA'];
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $result['SHEETS'],
+        ));
+        
+        $x->send('Voucher.xls');
+        
+    }
+    
+    function fetchData()
+    {
+        /*
+         *  check the alternative code 
+         *  if an account has transactions and there is not a alt code for it - then display an error
+         */
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->checkAlternativeCode($this, true);
+        
+        $gltrans = DB_DataObject::factory('gltrans');
+        $gltrans->_join = "
+            LEFT JOIN
+                accnt
+            ON
+                accnt_id = gltrans_accnt_id
+        ";
+        
+//        $gltrans->whereAdd("gltrans_date >= '{$dt}'::date AND gltrans_date < '$dt'::date + INTERVAL '1 MONTH'");
+        $gltrans->gltrans_deleted = 0;
+        
+        $gltrans->selectAdd();
+        
+        $gltrans->selectAdd("
+            gltrans_date AS voucher_date,
+            extract(year from gltrans_date) AS fy,
+            extract(month from gltrans_date) AS fiscal_period,
+            'Transfer' AS voucher_category,
+            gltrans_sequence AS voucher_no,
+            accnt_code_alt ac_code,
+            CASE WHEN (accnt_descrip_alt IS NOT NULL AND accnt_descrip_alt != '') THEN
+                accnt_descrip_alt
+            ELSE
+                accnt_descrip
+            END AS account_name,
+            
+            (SELECT curr_name FROM curr_symbol WHERE curr_id = basecurrid()) AS currency_code,
+            (SELECT curr_name FROM curr_symbol WHERE curr_id = basecurrid()) AS currency_name,
+            ABS(gltrans_amount) AS amount_original_currency,
+            CASE WHEN gltrans_amount > 0 THEN
+                ABS(gltrans_amount)
+            ELSE
+                0
+            END AS debit,
+            CASE WHEN gltrans_amount > 0 THEN
+                0
+            ELSE
+                ABS(gltrans_amount)
+            END AS credit,
+            gltrans_username AS created_by,
+            'NONE' AS check,
+            'NONE' AS authorize,
+            'NONE' AS cashier,
+            '' AS handler,
+            '*' AS settlement_method,
+            '' AS settlement_no,
+            gltrans_docnumber || ' ' || gltrans_notes AS voucher_description,
+            0 AS qty,
+            '*' AS operationo,
+            0 AS unit_price,
+            '' AS ref_info,
+            gltrans_date AS trans_dt,
+            '' AS transaction_no,
+            0 AS attachments,
+            gltrans_sequence AS sn,
+            '' AS system_module,
+            '' AS business_description,
+            '公司汇率' AS exrate_type,
+            1 AS exchange_rate,
+            (
+                rank() OVER (PARTITION BY gltrans_sequence ORDER BY gltrans_id ASC) - 1
+            ) AS entry_sn,
+            '' AS accounting_item,
+            0 AS post,
+            '' AS systemgenerated_voucher,
+            '' AS cash_flow
+            
+        ");
+        $gltrans->orderBy("gltrans_date,gltrans_sequence,gltrans_id ASC");
+        
+        return $gltrans->fetchAll();
+        
+    }
+}
diff --git a/Kingdee/VoucherGroup.php b/Kingdee/VoucherGroup.php
new file mode 100644 (file)
index 0000000..a7d749e
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+require_once 'Pman/Roo.php';
+require_once 'Pman/Xtuple/Kingdee.php';
+
+class Pman_Xtuple_Kingdee_VoucherGroup extends Pman_Roo
+{
+    function getAuth()
+    {
+        if (HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+    
+    function get()
+    {   
+        $Kingdee = new Pman_Xtuple_Kingdee();
+        
+        $result = $Kingdee->fetchSchema('VoucherGroup');
+        
+        $data['Page1'] = $this->fetchData();
+        
+        $data['t_Schema'] = $result['SCHEMA'];
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        
+        $x = new Pman_Core_SimpleExcel($data, array(
+            'workbooks' => $result['SHEETS'],
+        ));
+        
+        $x->send('VoucherGroup.xls');
+        
+    }
+    
+    function fetchData()
+    {
+        // not sure this part
+        // add the fake date for testing
+        
+        $data = array();
+        
+        $data[] = array(
+            'name' => 'Transfer',
+            'accounts_must_be_contained_in_credit_entries' => '',
+            'essential_to_debit_and_credit' => '',
+            'accounts_not_permitted_in_debit_entries' => '',
+            'accounts_not_permitted_in_credit_entries' => '',
+            'accounts_must_be_contained_in_debit_entries' => '',
+            'impossible_for_debit_and_credit' => '',
+            'limit_multidebit__multicredit' => 'FALSE',
+            'default' => 'FALSE',
+            'disable' => 'FALSE'
+        );
+        
+        return $data;
+    }
+}
diff --git a/Migrate.php b/Migrate.php
new file mode 100644 (file)
index 0000000..1a97611
--- /dev/null
@@ -0,0 +1,892 @@
+<?php
+/**
+ *
+ * migration script runner..
+ * xx.php Xtuple/Migrate
+ *
+ * This is the controller that runs all the table migrations.
+ *
+ * it' calls it'self.. to try and reduce memrory
+ *
+ * Caching is a bit of a nightmare..
+ *  - Usage scenarios
+ *    a) run the whole thing   Xtuple/Migrate
+ *    b) run a specific year/table combo    Xtuple/Migrate -t Netsuite_XXX -y 2010
+ *
+ *    
+ *
+ * 
+ *
+ */
+require_once 'Pman.php';
+
+class Pman_Xtuple_Migrate extends Pman
+{
+    static $cli_desc = "Migrate Netsuite json files to xtuple";
+    
+    static $cli_opts = array(
+        'debug' => array(
+            'desc' => 'Turn on debugging (see DataObjects debugLevel )',
+            'default' => 0,
+            'short' => 'v',
+            'min' => 1,
+            'max' => 1,
+            
+        ),
+        
+        'source' => array(
+            'desc' => 'Source directory for json files.',
+            'short' => 'f',
+            'default' => '',
+            'min' => 1,
+            'max' => 1,
+        ),
+         'no-cache' => array(
+            'desc' => 'Do not cache.',
+            'short' => 'n',
+            'default' => 0,
+            'min' => 1,
+            'max' => 1,
+        ),
+        'list-order' => array(
+            'desc' => 'List Order.',
+            'short' => 'l',
+            'default' => 0,
+            'min' => 1,
+            'max' => 1,
+        ),
+         'table' => array(
+            'desc' => 'Only a specific table, eg. -t Netsuite_SalesOrder',
+            'short' => 't',
+            
+            'max' => 1,
+        ),
+         'year' => array(
+            'desc' => 'Only a specific year, eg. -y 2009',
+            'short' => 'y',
+            'default' => 2009,
+            'min' => 1,
+            'max' => 1,
+        ),
+         'mapped' => array(
+            'desc' => "Get a mapped value or 'ALL' to show everything",
+            'short' => 'm',
+            'default' => 0,
+            'min' => 1,
+            'max' => 1,
+        ),
+          
+         'where' => array(
+            'desc' => "Import only items matching this condition, eg. --where='ItemFulfillment_id=123'",
+            'short' => 'w',
+            'default' => '',
+            'min' => 1,
+            'max' => 1,
+        ),
+          
+        'print' => array(
+            'desc' => "print_r the data for import (matching -w)",
+            'short' => 'p',
+            'default' => 0,
+            'min' => 0,
+            'max' => 1,
+        ),
+          
+         
+    );
+    
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("run form cli only");
+        }
+        
+    }
+    var $map = array();
+    
+    var $tables = array();
+    
+    
+    var $opts = array();
+    
+    function initOpts($opts)
+    {
+        $this->opts = $opts;
+        
+        //print_R($opts);
+        
+        if (empty($this->opts['source'])) {
+            $this->opts['source'] = __DIR__.'/data';
+        }
+         
+         
+        $sd = strtoupper(substr( HTML_FlexyFramework::get()->database, -2));
+        $this->department = $sd;
+        $os = $this->opts['source'] ;
+        $this->opts['source'] .= '/'. $sd;
+        
+        //print_R($this->opts);exit;
+        
+        if (!is_dir($this->opts['source'])) {
+            if (file_exists($os)) {
+                $this->opts['source']  = $os;
+            } else {
+            
+            
+                die("--source must be a directory {$this->opts['source']}\n");
+            }
+        }
+        
+        
+          
+    }
+    var $department = 'UNKNOWN';
+    function cachedir()
+    {
+        $uinfo = posix_getpwuid( posix_getuid () ); 
+        $user = $uinfo['name'];
+        
+        $cd = ini_get('session.save_path') ."/xtuple{$this->department}-{$user}";
+        if (!file_exists($cd)) {
+            mkdir($cd, 0700, true);
+        }
+        return $cd;
+
+        
+    }
+    
+    
+    function get($path, $opts)
+    {
+        ini_set('memory_limit', -1); // unlimited!
+        
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+   
+        
+        $this->initOpts($opts);
+        $cd = $this->cachedir();
+        
+        if (!empty($opts['mapped']) && !empty($opts['table'])) {
+            require_once 'Pman/Xtuple/Migration/Base.php';
+            $b = new Pman_Xtuple_Migration_Base($this);
+            echo "Mapped value: ";
+            $this->map(preg_replace('/^Netsuite_/i', '',$opts['table']));
+            print_r(
+                    $opts['mapped'] == 'ALL' ?
+                        $this->map[preg_replace('/^Netsuite_/i', '',$opts['table'])] :
+                        $b->mapped(
+                            preg_replace('/^Netsuite_/i', '',$opts['table']),
+                            $opts['mapped']
+                        )
+            );
+            echo "\n";
+            exit;
+        } 
+
+        $this->buildDeps(); 
+         
+        $nocache = $this->opts['no-cache'];
+       // print_R($this->deps); exit;
+        // push salesorderitem up the list..
+        $this->deps['Netsuite_Invoice'][] = 'Netsuite_SalesOrderItem';
+        //$this->deps['Netsuite_Invoice'][] = 'Netsuite_SalesOrder';
+        $this->deps['Netsuite_Rates'] = array('Netsuite_Currency');
+        $this->deps['Netsuite_VendorBill'] = array('Netsuite_Rates');
+        $this->deps['Netsuite_PurchaseOrder'] = array('Netsuite_Rates');
+        $this->deps['Netsuite_ItemReceipt'] = array('Netsuite_Rates');
+        $this->deps['Netsuite_JournalEntry'] = array('Netsuite_Rates');
+        $this->deps['Netsuite_VendorPayment'][]  = 'Netsuite_VendorBill';
+        $this->deps['Netsuite_CustomerPayment'][]  = 'Netsuite_CustomerRefund';
+        $this->deps['Netsuite_CustomerRefund'][]  = 'Netsuite_CreditMemo';
+
+        // delay inventory transfer?
+        $this->deps['Netsuite_InventoryTransfer'][]  = 'Netsuite_InventoryItemLocations';
+      //   $this->deps['Netsuite_InventoryTransfer'][]  = 'Netsuite_VendorBill';
+        // bump up customer payment
+        //$this->deps['Netsuite_VendorBill'][]  = 'Netsuite_CustomerPayment';
+        $this->deps['Netsuite_Check'][]  = 'Netsuite_VendorBill';
+        $this->deps['Netsuite_VendorReturnAuthorization'][]  = 'Netsuite_VendorBill';
+        $this->deps['Netsuite_Check'][]  = 'Netsuite_VendorBill';
+        $this->deps['Netsuite_VendorCredit'][]  = 'Netsuite_VendorBill';
+        
+        $this->deps['Netsuite_Transfer'] = array( 'Netsuite_JournalEntry');
+        $this->tables[] = 'Netsuite_Transfer';
+        
+        $this->deps['Netsuite_Deposit'] = array( 'Netsuite_JournalEntry');
+        $this->tables[] = 'Netsuite_Deposit';
+        
+        
+        $this->deps['Netsuite_InventoryTransfer'][] = 'Netsuite_ItemReceipt';
+        
+         $this->deps['Netsuite_InventoryAdjustment'][] = 'Netsuite_ItemReceipt';
+        
+        // locations have to have customers.
+        $this->deps['Netsuite_Location'][]  = 'Netsuite_Customer';
+        $this->deps['Netsuite_InventoryItem'][]  = 'Netsuite_Location';
+        $this->deps['Netsuite_ItemReceipt'][]  =  'Netsuite_InventoryItem';
+        $this->deps['Netsuite_PurchaseOrder'][]  = 'Netsuite_InventoryItem';
+       $this->deps['Netsuite_VendorBill'][]  = 'Netsuite_InventoryItem';
+
+        
+        
+        //$this->deps['Netsuite_VendorBill'][]  = 'Netsuite_Location';
+
+        // remove me later...- when elliot has finished it.
+        //$this->deps['Netsuite_ExpenseReport'][]  = 'Netsuite_CustomerPayment';
+        
+        //$this->deps['Netsuite_CreditMemo'] = array('Netsuite_InventoryItem');
+             
+        array_unshift($this->tables, 'Netsuite_Rates');
+        $this->tables = $this->sortDeps($this->tables);
+
+       /// append Netsuite_ if doesn't already exist
+        if (empty($this->opts['table'])) {
+            // nothing
+        } else  if(is_string($this->opts['table'])) {
+            $this->opts['table'] = (strrpos($this->opts['table'], 'Netsuite_') !== false) ?
+                                    $this->opts['table'] : 'Netsuite_'.$this->opts['table'];
+        } else if (is_array($this->opts['table'])) {
+            foreach($this->opts['table'] as &$t) {
+                $t = (strrpos($t, 'Netsuite_') !== false) ? $t : 'Netsuite_'.$t;
+            }
+        }
+        
+        if (!empty($this->opts['table']) && !in_array( $this->opts['table'], $this->tables)) {
+                die("Invalid table ! - {$this->opts['table']}\n");
+            
+        }
+        
+        
+        //print_R($this->tables);
+        
+        if ($this->opts['list-order']) {
+            echo implode("\n", $this->tables) ."\n";exit;
+        }
+        
+        
+        /// make sure all our accounting periods are open...
+        
+        $per = DB_DataObject::Factory('period');
+        $per->query('UPDATE period set period_closed=false');
+        
+        
+        // remove invalid taxzones..
+        
+        $per->query("delete from taxass where taxass_taxzone_id = (
+                    SELECT taxzone_id FROM taxzone where taxzone_descrip='State Sales Tax Authority'
+            )");
+
+        $per->query("delete from taxzone where taxzone_descrip='State Sales Tax Authority'");
+        
+        $wkey = false;
+        if (!empty($this->opts['where'])) {
+            
+            if (empty($this->opts['table'])) {
+                die("you must specify table if using --where\n");
+            }
+            
+            list($wkey, $wval) = explode('=', $this->opts['where']);
+        }
+        
+        $y = $this->opts['year'];
+        
+        
+        $done = array();
+        foreach($this->tables as $tbl) {
+            
+            $n = preg_replace('/^Netsuite_/i', '', $tbl);
+            
+            // skip these tables
+            if ($n == 'TransactionApply') {
+                // we actually use it for all the transaction based tables,
+                // and our dump code now merges it into the parent transactions.
+                continue;
+            }
+          
+            
+            
+            
+            
+            // should we use map() for this?
+            $f =  $this->opts['source'] ."/{$tbl}.sql.json";
+            $all = file_exists($f.'.all') ;
+            $f = $all ? $f.'.all' : $f.'.'.$y;
+            $yy = $all ? 'all' : $y;
+            echo "Migrating $tbl from $f\n";
+            
+            
+            if (empty($this->opts['table'])) {
+                
+                
+              
+                
+                $export_run = false;
+                
+                
+                foreach (array( 2008,2009,2010,2011,2012) as $yr) {
+                    $f =  $this->opts['source'] ."/{$tbl}.sql.json";
+                    $cyr = $all ? 'all' : $yr;
+                    $f = $all ? $f.'.all' : $f.'.'.$yr;
+                    $cache = $cd ."/" .md5($f) . "-{$tbl}-{$cyr}.sql.cache";
+                     
+                    $sourcetime = file_exists($f) ? filemtime($f)  : 0;
+                    
+                    $is_other = false;
+                    if ($n == 'Transfer' || $n == 'Deposit') {
+                       // no checks done..
+                    } else {
+                    
+                        
+                        if (!$sourcetime && !$is_other) {
+                            echo "SKIP FILE - does not exists : $f\n";
+                            continue;
+                            
+                        }
+                        
+                        $migtime = file_exists(dirname(__FILE__) ."/Migration/{$n}.php") ?
+                                filemtime(dirname(__FILE__) ."/Migration/{$n}.php") : 0;
+                        $cachetime = file_exists($cache) && filesize($cache) ? filemtime($cache) : 0;
+                        
+                        print_R(array( $f=> $sourcetime, 'PHP'=>$migtime,$cache => $cachetime));
+                        if ($cachetime >= $sourcetime && $cachetime  >= $migtime) {
+                            echo "SKIP FILE UP TO DATE? $tbl : $yr \n";
+                            continue;
+                        }
+                        if (!$migtime) {
+                            echo "SKIP TABLE - No convertor exists $tbl : $yr \n";
+                            continue;
+                        }
+                   
+                    
+                        if (!$export_run) {
+                            
+                            $this->runExport($tbl);
+                            
+                            $export_run = true;
+                            
+                        }
+                    }
+                    
+                    echo "RUNNING AS CACHE MISSING / OUT OF DATE: $cache \n";
+                    $cmd = implode(' ', array(
+                        '/usr/bin/php', // php
+                        $_SERVER['SCRIPT_NAME'], // hk.php
+                        'Xtuple/Migrate',
+                        '-t ' . $tbl,
+                        '-y ' . $yr,
+                        '-f ' . $this->opts['source']
+                    ));
+                    echo "\n\n-------------------------\n$cmd\n-----------------\n\n";
+                    $ret = 0;
+                    passthru( $cmd , $ret );
+                    $ret = (int) $ret;
+                    if ($ret !== 4  ) {
+                        var_dump($ret);
+                        die("FAILED ");
+                        
+                    }
+                    if ($all) {
+                        break;
+                    }
+                }
+                continue;
+                  
+            }
+            
+            
+            
+            
+            $cache = $cd ."/" .md5($f) . "-{$tbl}-{$yy}.sql.cache";
+            
+            
+            if ($n == 'Transfer' || $n == 'Deposit') {
+                if (!empty($this->opts['table']) &&  $this->opts['table'] != $tbl) {
+                    continue;
+                    
+                }
+                if (file_exists($cache)) {
+                //    continue;
+                }
+                //DB_DataObject::DebugLevel(1);
+                $cl = $this->factory($n);
+                $cl->postMigrate();
+                touch($cache);
+                
+                echo  "Completed ". $this->opts['table'] . "\n";
+                exit(4);
+                continue;
+                
+                
+                
+            }
+            
+            
+            
+            if (!file_exists($f)) {
+                $this->updateReport($n, "Skipped -  no dump exists ");
+                echo "Skip $n - no dump exists $f \n";
+                echo "creating empty cache $cache\n";
+                $done[] = $tbl;
+                file_put_contents($cache, serialize(array()));
+
+                 if (!empty($this->opts['table']) && $this->opts['table'] == $tbl) {
+                    echo "Completed ". $this->opts['table'] . "\n";
+                    exit(4);
+                }
+
+                continue;
+            }
+             //var_dump($this->opts);
+            
+            if ($this->opts['debug']) {
+                
+                DB_DataObject::debugLevel( $this->opts['debug'] );
+            }
+            
+            $cl = $this->factory($n);
+            
+            if (!$cl) {
+                $this->updateReport($n, "Skipped -  no migration tool exists");
+                if (!empty($this->opts['table']) && $this->opts['table'] == $tbl) {
+                    echo "Skipped -  no migration tool exists ". $this->opts['table'] . "\n";
+                    exit(4);
+                }
+                continue;
+            }
+            
+            $doimport = empty($this->opts['table']) || $this->opts['table'] == $tbl;
+            
+            $usecache = !$nocache;
+            if (!empty($this->opts['table'])) {
+                if ($this->opts['table'] == $tbl) {
+                    $usecache = false;
+                }
+            }
+            
+            
+            
+            $sourcetime = filemtime($f); 
+            $migtime = filemtime(dirname(__FILE__) ."/Migration/{$n}.php");
+            $cachetime = file_exists($cache) && filesize($cache) ? filemtime($cache) : 0;
+            
+            
+            if ($usecache && $cachetime >= $sourcetime && $cachetime  >= $migtime) {
+                // use cache..
+                
+                $this->map($n);
+                //$doimport ?  $cl->validateUsed((array)json_decode($data[1])) : false;
+                $done[] = $tbl;
+                
+                $this->updateReport($n, false);
+                
+                
+                echo "Migrating $tbl - using cache : $cache \n";
+                continue;
+            }
+            
+            
+            if ($nocache &&  $cachetime < $sourcetime) {
+                echo "Migrating $tbl - cache to old, or does not exist\n";
+            }
+            if ($nocache && $cachetime  < $migtime) {
+                echo "Migrating $tbl - migration code was updated\n";
+            }
+
+        
+            // finally do the migration..
+            
+           
+            $cl->validateOutputSupport();
+            
+            $data = file($f);
+
+            $missing_dep  = false;
+            foreach( $this->deps[$tbl] as $dep) {
+                if (in_array($dep, $done)) {
+                    continue;
+                }
+                echo "Checking for dep $dep\n";
+                if ($this->map(preg_replace('/^Netsuite_/', '', $dep))) {
+                    continue;
+                }
+                $missing_dep = $dep;
+                break;
+                
+            }
+            
+            
+            
+            
+            if ($missing_dep !== false) {
+                echo "Skip $n - dependant table $missing_dep has not been done yet.\n";
+                $this->updateReport($n, "Skip dependant table $missing_dep has not been done yet.");
+                
+                if (!empty($this->opts['table']) && $this->opts['table'] == $tbl) {
+                    echo "Failed  ". $this->opts['table'] . "\n";
+                    exit(3); // error condtion..
+                }
+                exit(3);
+                continue;
+            }
+            if (!$doimport ) {
+                echo "Skip $n - no specified by --table .\n";
+                $this->updateReport($n, false);
+                if (!empty($this->opts['table']) && $this->opts['table'] == $tbl) {
+                    echo  "Completed ". $this->opts['table'] . "\n";
+                    exit(4);
+                }
+                
+                continue;
+            }
+            
+            
+            
+            
+            $cl->validateUsed((array)json_decode($data[1]));
+            $def = false;
+            $this->map[$n] = array();
+            $total = count($data);
+            echo "Migrating $total Records\n";
+            $last = 0;
+            foreach($data as $i=> $l) {
+                
+                
+                if (empty($cl->def)) { // first line is default.s
+                    $cl->def = $l;
+                    continue;
+                }
+                // print out some progress.
+                if ($i % 500 == 0) {
+                    echo floor(($i/$total) * 100)."%\n";
+                }
+                
+                $row = (array)json_decode($l);
+                
+                // testing a single entry..
+                if ($wkey) {
+                    if (!isset($row[$wkey])) {
+                        die("--where condition is invalid, key '$wkey' does not exist\n");
+                    }
+                    if ($row[$wkey] != $wval) {
+                        continue;
+                    }
+                    if (!empty($opts['print'])) {
+                        print_R($row);
+                    }
+                    //DB_DataObject::debugLevel(1);
+                    
+                }
+                
+                
+                 
+                $add = $cl->migrate($row);
+                if ($wkey) {
+                    echo "Migrate return\n";
+                    var_dump($add);
+                }
+                // rates does not have an id col.
+                if ($add !== false )  {
+                    //echo "SAVEMAP  {$row['id']} :  $add \n";
+                    $cl->saveMap(isset($row['id']) ? $row['id'] : $i, $add);
+                }
+                
+                // free up some memory..
+                $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
+                $GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array();
+        
+        
+                
+            }
+            
+            
+            //var_Dump($n);
+            // works ok here..
+            //print_R(array_keys($this->map));
+            echo "Migrating $tbl - ". count(array_keys($this->map[$n])) . " Records added\n";
+            
+            
+            
+            $cl->postMigrate();
+            
+            if ($wkey) {
+                die("ONLY RUNNING IN TESTING MODE with
+                    --where condition exiting before any damage is done..\n");
+            }
+            
+            
+            $str = $cl->resultsToString();
+            
+            $this->updateReport($n, $cl->resultsToString());
+            
+            
+            
+            if ($str !== false) {
+                file_put_contents($cd ."/{$tbl}-{$yy}.results.txt", $str);
+                echo "RESULTS IN {$cd}/{$tbl}-{$yy}.results.txt\n";
+            }
+            // sorting is pretty irrelivant, and screws things up horriably anyway.
+            //ksort($this->map[$n],SORT_STRING);
+            //var_dump($this->map[$n][3263]);
+            
+            
+            file_put_contents($cache, serialize($this->map[$n]));
+            echo "CACHED DATA IN php -r 'print_r(unserialize(file_get_contents(\"{$cache}\")));'\n";
+            touch($cache, max($sourcetime, $migtime, filemtime($cache)));
+            $done[] = $tbl;
+             
+            if (!empty($this->opts['table']) && $this->opts['table'] == $tbl) {
+                
+                //print_r($this->map[$n]);
+            
+                //var_dump($this->map[$n][3263]);
+            
+                echo  "Completed ". $this->opts['table'] . "\n";
+                exit(4);
+            }
+            die("\nRun again - to import more\n");
+        }
+        die("DONE");
+        //die("DONE\n");
+        
+    }
+    
+    function updateReport($n, $res)
+    {
+        $cd = $this->cachedir();
+        
+        $f = $this->opts['source'] ."/Netsuite_{$n}.sql.json";
+        
+        // we need to update individual reports, and a 'merged one'..
+        
+        if ($res !== false) {
+            file_put_contents( "{$cd}/" .md5($f) . "-Netsuite_{$n}.results.txt", $res);
+        } else {
+            $res = file_exists("{$cd}/" .md5($f) . "-Netsuite_{$n}.results.txt") ?
+                file_get_contents("{$cd}/" .md5($f) . "-Netsuite_{$n}.results.txt") :
+                "No results available";
+        }
+        
+        static $latest = false;
+        if (!$latest) {
+            $latest = "{$cd}/latest.results.txt";
+            file_put_contents($latest, "Import Report - " . date("Y-m-d H:i:s"). "\n\n");
+        }
+        $fh = fopen($latest, 'a');
+        
+        fwrite($fh, "RESULTS FOR: $n:\n");
+        fwrite($fh, "$res\n\n");
+        fclose($fh);
+        
+        
+        
+        
+    }
+    
+    function buildDeps()
+    {
+        $deps = array();
+        
+        
+        
+        $ini = parse_ini_file(dirname(__FILE__).'/Migration/netsuite.links.ini', true);
+        
+        foreach($ini as $tbl => $maps) {
+             if (!in_array($tbl, $this->tables)) {
+                $this->tables[] = $tbl;
+                $deps[$tbl] = array();
+            }
+            
+            foreach($maps as $col=>$to) {
+                $kv = explode(':', $to);
+                
+                if (!in_array($kv[0], $this->tables)) {
+                    $this->tables[] = $kv[0];
+                    $deps[$kv[0]] = array();
+                }
+                
+                if (in_array($kv[0], $deps[$tbl])) {
+                    continue;
+                }
+                $deps[$tbl][] = $kv[0];
+            }
+            
+        }
+        
+        
+        $this->deps = $deps;
+        
+        
+    }
+    /**
+     *
+     * has the map been loaded..
+     */
+    var $loaded = array();
+    
+    function map($n)
+    {
+        
+        if (isset($this->loaded[$n])) {
+            return true;
+        }
+        $this->loaded[$n] = true;
+        
+        echo "RESET MAP FOR $n\n";
+        $this->map[$n] = array();
+        $cd = $this->cachedir();
+        
+        $years = array('all', 2008,2009,2010,2011,2012);
+        
+        $tbl = 'Netsuite_'. $n;
+        // make sure teh map is loaded for a class..
+        $ret = false;
+        foreach($years as $yy) {
+        
+        
+            $f =  $this->opts['source'] ."/{$tbl}.sql.json.". $yy;
+            
+            $cache = $cd ."/" .md5($f) . "-{$tbl}-{$yy}.sql.cache";
+            
+            if (!file_exists($cache) || !filesize($cache)) {
+                echo "NO CACHE $cache\n";
+                continue;
+            }
+             
+            $ret = true;
+            echo "LOADED CACHE $cache\n";
+            $this->map[$n] +=   unserialize(file_get_contents($cache));
+            if ($yy == 'all') {
+                break; 
+            }
+        }
+        if (!$ret) {
+            unset($this->map[$n]);
+        }
+        return $ret;
+    }
+    
+    function sortDeps($ar)
+    {
+        // this could be done by usort, but we need to build a reverse dependancy list as well.
+        
+        // loop through an array,
+        // if we can add an item - add it, otherwise push it to the end..
+        
+        $ret = array();
+        $done = array();
+        for($i = 0  ; $i < count($ar); $i++ )
+        {
+            $ltest = array();
+            while (true)
+            {
+                $t = $ar[$i];
+                if (isset($ltest[$t])) {
+                    echo "DEPENDANCIE FAILED FOR $t";
+                    exit;
+                    
+                }
+                // no dependancies.. it can be added..
+                if (empty($this->deps[$t])) {
+                    $done[$t] = true;
+                    break;
+                }
+                
+                // have all the dependancies been added..
+                $missing = false;
+                foreach($this->deps[$t] as $dep) {
+                    if (!isset($done[$dep])) {
+                        $missing = true;
+                        break;
+                    }
+                }
+                if (!$missing) {
+                    $done[$t] = true;
+                    break;
+                }
+                // a dependancy is missing..
+                // move this element to the end..
+                
+                unset($ar[$i]);
+                $ar = array_values($ar); // renumber...
+                $ar[] = $t;
+                $ltest[$t] = true;
+                // try ataing.. 
+            }
+             
+            
+            
+        }
+        return $ar;
+         
+    }  
+     
+    
+    function factory($n)
+    {
+        $parts = explode('/', $n);
+        $n = $parts[0];
+        $cf = dirname(__FILE__) ."/Migration/{$n}.php";
+        $cn = "Pman_Xtuple_Migration_{$n}";
+        
+        if (!file_exists($cf)) {
+            echo "Skip $n - no file '$cf' exists yet\n";
+            return false;
+        }
+        require_once $cf;
+        if (!class_exists($cn)) {
+            echo "SKIP class does not exist in file: $cn\n";
+            return false;
+        }
+        $cl = new $cn($this, isset($parts[1]) ? $parts[1] : false);
+         
+        return $cl;
+        
+    }
+    
+    function onPearError($err)
+    {
+        
+        $out = $err->toString();
+        
+        
+        //print_R($bt); exit;
+        $ret = array();
+        foreach($err->backtrace as $b) {
+            $ret[] = $b['file'] . '(' . $b['line'] . ')@' .   @$bt['class'] . '::' . @$bt['function'];  
+        }
+        //convert the huge backtrace into something that is readable..
+        $out .= "\n" . implode("\n",  $ret);
+     
+        
+        echo $out;
+        
+        echo "\n-- FAILED --\n";
+        exit(3);
+        
+        
+        
+    }
+    function runExport($tbl)
+    {
+        echo "RUNNING EXPORT to ensure data is up-to-date: $tbl \n";
+        $country = strtoupper($this->department);
+        // this is in Pman.Xtuple.Migrate directory now..
+        $cmd = implode(' ', array(
+            '/usr/bin/php', // php
+            __DIR__  . '/../web.Netsuite/index.php',
+            'Netsuite/Dump',
+            '-t ' . $tbl,
+            '-c ' . $country
+        ));
+        echo "\n\n-------------------------\n$cmd\n-----------------\n\n";
+        //exit;
+        //$ret = 0;
+        passthru( $cmd , $ret );
+        
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/Period.php b/Period.php
new file mode 100644 (file)
index 0000000..16760db
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * -- Create Period
+ * 
+ *
+ */
+require_once 'Pman.php';
+class Pman_Xtuple_Period extends Pman
+{
+    static $cli_desc = "Create Period";
+    
+    static $cli_opts = array(
+        'create' => array(
+            'desc' => 'which year you want to create',
+            'short' => 'c',
+            'default' => '',
+            'min' => 1,
+            'max' => 1,
+            
+        )
+    );
+    
+    function getAuth() {
+        
+        
+        $ff = HTML_FlexyFramework::get();
+        if (!empty($ff->cli)) {
+            $this->cli = true;
+            return true;
+        }
+        die("NOT ALLOWED");
+    }
+    
+    function get($args, $opts)
+    {
+        if(!empty($opts['create'])){
+            $period = DB_DataObject::factory('period');
+            $period->createPeriod($opts['create']);
+            die("DONE!");
+        }
+        
+        die("Nothing to do, Missing parameters! \n");
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleAddress.bjs b/Pman.Dialog.XtupleAddress.bjs
new file mode 100644 (file)
index 0000000..da09ac3
--- /dev/null
@@ -0,0 +1,257 @@
+{
+    "id": "roo-file-271",
+    "name": "Pman.Dialog.XtupleAddress",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleAddress.bjs",
+    "items": [
+        {
+            ".builderCfg": "{\"cols\":[{\"table\":\"addr\",\"column\":\"addr_id\",\"columnshort\":\"addr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\",\"display\":\"addr_id\"},{\"table\":\"addr\",\"column\":\"addr_active\",\"columnshort\":\"addr_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_line1\",\"columnshort\":\"addr_line1\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_line2\",\"columnshort\":\"addr_line2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_line3\",\"columnshort\":\"addr_line3\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_city\",\"columnshort\":\"addr_city\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_state\",\"columnshort\":\"addr_state\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_postalcode\",\"columnshort\":\"addr_postalcode\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_country\",\"columnshort\":\"addr_country\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_notes\",\"columnshort\":\"addr_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"addr_number\",\"columnshort\":\"addr_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"addr_id\"],\"table\":\"addr\",\"xtype\":\"LayoutDialog\",\"|xns\":\"Roo\"}",
+            "closable": false,
+            "collapsible": false,
+            "height": 400,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit Address",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "Toolbar",
+                            "*prop": "toolbar",
+                            "items": [
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function()\n{\n    var id = _this.form.findField('addr_id').getValue() *1;\n    if (!id) {\n        Roo.MessageBox.alert(\"Error\", \"You can not delete this, you have not created it yet\");\n        return;\n    }\n    \n    \n    Roo.MessageBox.confirm(\"Confirm\", \"You will only be able to delete this if it is not referenced anywhere<BR>\"+\n            \", are you sure you want to try that?\",\n            function (res) {\n                if(res!='yes') {\n                    return;\n                \n                }\n                new Pman.Request({\n                    method: 'POST',\n                    url: baseURL+ '/Roo/addr',\n                    params : {\n                        _delete : id\n                    },\n                    success : function() {\n                        _this.callback({ addr_id : 0, addr_line1 : '' });\n                        _this.dialog.hide();\n                    }\n                });\n        });\n        \n    \n    \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Delete",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if (_this.data.addr_id) { \n            this.load({ method: 'GET', params: { '_id' : _this.data.addr_id }});\n        }\n       return;\n    }\n    if (action.type == 'load') {\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n             _this.form.setValues(action.result.data);\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/addr.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "keyup": "function (_self, e)\n{\n    _this.form.findField('addr_number').sync();\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "fieldLabel": "Line 1",
+                                    "name": "addr_line1",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Line 2",
+                                    "name": "addr_line2",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Line 3",
+                                    "name": "addr_line3",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "City",
+                                    "name": "addr_city",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "displayField": "addr_state",
+                                    "editable": true,
+                                    "emptyText": "State",
+                                    "fieldLabel": "State",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "addr_state",
+                                    "qtip": "Select State",
+                                    "queryParam": "query[addr_state]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_state}</b></div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "addr_state",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n   // o.params.state_country_id_country_name = _this.form.findField('addr_country').getValue();\n    //if (!o.params.state_country_id_country_name.length) {\n    //    Roo.MessageBox.alert(\"Select Country First\");\n//        return false;\n  //  }\n  \n   o.params._distinct = 'addr_state';\n   o.params._columns = 'addr_state';\n   o.params.limit = 999;\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'addr_state' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/addr.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "addr_state",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[ 'addr_state' ]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "displayField": "country_name",
+                                    "editable": true,
+                                    "emptyText": "Country",
+                                    "fieldLabel": "Country",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "addr_country",
+                                    "qtip": "Select Country",
+                                    "queryParam": "query[country_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{country_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "country_name",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.limit = 999;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'country_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/country.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "country_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{'name':'country_id','type':'int'},'county_name']",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "fieldLabel": "postalcode",
+                                    "name": "addr_postalcode",
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Unique#",
+                                    "name": "addr_number",
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|sync": "function() {\n    if (_this.form.findField('addr_id') * 1 > 0 ) {\n        return;\n    }\n    this.setValue('C' + _this.form.findField('customer_id').getValue() + '-' + \n        _this.form.findField('addr_line1').getValue()\n    );\n        \n}\n",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "notes",
+                                    "name": "addr_notes",
+                                    "width": 300,
+                                    "xtype": "TextArea",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "customer_id",
+                                    "width": 100,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "addr_id",
+                                    "width": 100,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n \n    _this.form.doAction('submit');\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleAddress.js b/Pman.Dialog.XtupleAddress.js
new file mode 100644 (file)
index 0000000..3045536
--- /dev/null
@@ -0,0 +1,355 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleAddress = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 400,
+            modal : true,
+            resizable : false,
+            title : "Edit Address",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if (_this.data.addr_id) { 
+                                            this.load({ method: 'GET', params: { '_id' : _this.data.addr_id }});
+                                        }
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                             _this.form.setValues(action.result.data);
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/addr.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        keyup : function (_self, e)
+                                        {
+                                            _this.form.findField('addr_number').sync();
+                                        }
+                                    },
+                                    allowBlank : false,
+                                    fieldLabel : 'Line 1',
+                                    name : 'addr_line1',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Line 2',
+                                    name : 'addr_line2',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Line 3',
+                                    name : 'addr_line3',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'City',
+                                    name : 'addr_city',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    displayField : 'addr_state',
+                                    editable : true,
+                                    emptyText : "State",
+                                    fieldLabel : 'State',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'addr_state',
+                                    qtip : "Select State",
+                                    queryParam : 'query[addr_state]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_state}</b></div>',
+                                    triggerAction : 'all',
+                                    typeAhead : false,
+                                    valueField : 'addr_state',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                
+                                               // o.params.state_country_id_country_name = _this.form.findField('addr_country').getValue();
+                                                //if (!o.params.state_country_id_country_name.length) {
+                                                //    Roo.MessageBox.alert("Select Country First");
+                                            //        return false;
+                                              //  }
+                                              
+                                               o.params._distinct = 'addr_state';
+                                               o.params._columns = 'addr_state';
+                                               o.params.limit = 999;
+                                                // set more here
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'addr_state' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/addr.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'addr_state',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [ 'addr_state' ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    displayField : 'country_name',
+                                    editable : true,
+                                    emptyText : "Country",
+                                    fieldLabel : 'Country',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'addr_country',
+                                    qtip : "Select Country",
+                                    queryParam : 'query[country_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{country_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : false,
+                                    valueField : 'country_name',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                                o.params.limit = 999;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'country_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/country.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'country_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{'name':'country_id','type':'int'},'county_name']
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'postalcode',
+                                    name : 'addr_postalcode',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Unique#',
+                                    name : 'addr_number',
+                                    width : 150,
+                                    sync : function() {
+                                        if (_this.form.findField('addr_id') * 1 > 0 ) {
+                                            return;
+                                        }
+                                        this.setValue('C' + _this.form.findField('customer_id').getValue() + '-' + 
+                                            _this.form.findField('addr_line1').getValue()
+                                        );
+                                            
+                                    }
+                                },
+                                {
+                                    xtype: 'TextArea',
+                                    xns: Roo.form,
+                                    fieldLabel : 'notes',
+                                    name : 'addr_notes',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'customer_id',
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'addr_id',
+                                    width : 100
+                                }
+                            ]
+                        }
+                    ],
+                    toolbar : {
+                        xtype: 'Toolbar',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'Fill',
+                                xns: Roo.Toolbar
+                            },
+                            {
+                                xtype: 'Button',
+                                xns: Roo.Toolbar,
+                                listeners : {
+                                    click : function()
+                                    {
+                                        var id = _this.form.findField('addr_id').getValue() *1;
+                                        if (!id) {
+                                            Roo.MessageBox.alert("Error", "You can not delete this, you have not created it yet");
+                                            return;
+                                        }
+                                        
+                                        
+                                        Roo.MessageBox.confirm("Confirm", "You will only be able to delete this if it is not referenced anywhere<BR>"+
+                                                ", are you sure you want to try that?",
+                                                function (res) {
+                                                    if(res!='yes') {
+                                                        return;
+                                                    
+                                                    }
+                                                    new Pman.Request({
+                                                        method: 'POST',
+                                                        url: baseURL+ '/Roo/addr',
+                                                        params : {
+                                                            _delete : id
+                                                        },
+                                                        success : function() {
+                                                            _this.callback({ addr_id : 0, addr_line1 : '' });
+                                                            _this.dialog.hide();
+                                                        }
+                                                    });
+                                            });
+                                            
+                                        
+                                        
+                                    }
+                                },
+                                cls : 'x-btn-text-icon',
+                                text : "Delete",
+                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                         
+                            _this.form.doAction('submit');
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleAdjustmentGroup.bjs b/Pman.Dialog.XtupleAdjustmentGroup.bjs
new file mode 100644 (file)
index 0000000..5ae2dde
--- /dev/null
@@ -0,0 +1,486 @@
+{
+    "id": "roo-file-275",
+    "name": "Pman.Dialog.XtupleAdjustmentGroup",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleAdjustmentGroup.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 500,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create Inventory Adjustment Group",
+            "width": 600,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "*prop": "center",
+                    "tabPosition": "top",
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "center",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "*prop": "north",
+                                    "height": 150,
+                                    "split": true,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "region": "north",
+                                    "xtype": "ContentPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        _this.grid.ds.removeAll();\n        _this.saveBtn.show();\n        if(_this.data.invadjgrp_id){\n       \n            this.load({ method: 'GET', params: { '_id' : _this.data.invadjgrp_id }});\n        }\n       return;\n    }\n    if (action.type == 'load') {\n        _this.data = action.result.data;\n        if(_this.data.invadjgrp_posted){\n            _this.saveBtn.hide();\n        }\n\n        _this.grid.ds.load({});\n        return;\n    }\n    if (action.type =='submit') {\n        \n    \n        if (!_this.grid.ds.getCount()  && this.findField('invadjgrp_id').getValue()*1 < 1) {\n        \n        \n        \n            this.load({ method: 'GET', params: { '_id' : action.result.data.invadjgrp_id }});\n            return;\n        \n        }\n\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                                            },
+                                            "method": "POST",
+                                            "style": "margin:10px;",
+                                            "xtype": "Form",
+                                            "|url": "baseURL + '/Roo/Invadjgrp.php'",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "legend": "Inventory Adjustment Group Detail",
+                                                    "style": "width:520px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Name",
+                                                            "name": "invadjgrp_name",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Date",
+                                                            "format": "Y-m-d",
+                                                            "name": "invadjgrp_transdate",
+                                                            "useIso": true,
+                                                            "width": 200,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "location_name",
+                                                            "editable": false,
+                                                            "emptyText": "Select Location",
+                                                            "fieldLabel": "Location",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "invadjgrp_location_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "invadjgrp_location_id_location_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select Location",
+                                                            "queryParam": "query[location_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> {location_descrip} </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "location_id",
+                                                            "width": 200,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    \n    o.params = o.params || {};\n    o.params.location_netable = 1;\n    o.params._notinternalcompany = 1;\n    o.params.location_restrict = 0;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'curr_id' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "location_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[\n    {\"name\":\"location_id\",\"type\":\"int\"},\n    {\"name\":\"location_name\",\"type\":\"string\"}\n]",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": true,
+                                                            "fieldLabel": "Comments",
+                                                            "name": "invadjgrp_comments",
+                                                            "width": 400,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "name": "invadjgrp_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "adjustments",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "invadj",
+                                    "title": "Invadj",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                                "beforeedit": "function (e)\n{\n    if(_this.data.invadjgrp_posted){\n        Roo.MessageBox.alert('Error', 'This group has been posted');\n        return false;\n    }\n    \n    if(e.record.data.invadj_posted){\n        Roo.MessageBox.alert('Error', 'Can not update the posted adjustment');\n        return false;\n    }\n    \n    if(e.field != 'invadj_itemsite_id_item_number'){\n        var itemsite_id = e.record.data.invadj_itemsite_id * 1\n        if(isNaN(itemsite_id) || itemsite_id < 1){\n            Roo.MessageBox.alert('Error', 'Please select a item first');\n            return false;\n        }\n    }\n}",
+                                                "afteredit": "function (e)\n{\n    if (e.originalValue == e.value) {\n        return;\n    }\n    \n    switch(e.field) {\n        case 'invadj_qty_by' :\n            e.record.set('invadj_qty_after', parseInt(e.record.data.invadj_qty_before * 1 + e.value * 1));\n            break;\n        \n        case 'invadj_qty_after' :\n            e.record.set('invadj_qty_by', parseInt(e.value * 1 - e.record.data.invadj_qty_before * 1));\n            break;\n        \n        case 'invadj_itemsite_id_item_number' :\n            e.record.set('invadj_qty_after', parseInt(e.record.data.invadj_qty_before * 1 + e.record.data.invadj_qty_by * 1));\n            break;\n    \n    }\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "invadj_itemsite_id_item_number",
+                                            "clicksToEdit": 1,
+                                            "loadMask": true,
+                                            "xtype": "EditorGrid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "tabend": "function (_self)\n{\n    _this.addItemBtn.fireEvent('click', _this.addItemBtn);\n}"
+                                                    },
+                                                    "*prop": "sm",
+                                                    "xtype": "CellSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var group = _this.form.findField('invadjgrp_id').getValue() * 1;\n    \n    if(!group || group < 1){\n        Roo.MessageBox.alert('Error', 'Please save the group first!');\n        return;\n    }\n    \n    if(_this.data.invadjgrp_posted){\n        Roo.MessageBox.alert('Error', 'This group has been posted');\n        return;\n    }\n    \n    var nr = _this.grid.ds.reader.newRow({\n        invadj_itemsite_id_item_number : '',\n        invadj_itemsite_id : 0,\n        invadj_qty_before : 0,\n        invadj_qty_by : 0,\n        invadj_qty_after : 0\n        \n   });\n\n    _this.grid.stopEditing();\n    _this.grid.ds.insert(_this.grid.ds.getCount(), nr); \n    _this.grid.startEditing(_this.grid.ds.getCount()-1, 0); // type..\n   \n}\n",
+                                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function ()\n{\n    _this.grid.stopEditing();\n    \n    if(_this.data.invadjgrp_posted){\n        Roo.MessageBox.alert('Error', 'This group has been posted');\n        return;\n    }\n    \n    var s = _this.grid.getSelectionModel().getSelectedCell();\n    \n    if(!s){\n        Roo.MessageBox.alert('Error', 'Please select a adjustment to delete');\n        return;\n    }\n    \n    var i = _this.grid.ds.getAt(s[0]);\n    \n    if(i.data.invadj_posted){\n        Roo.MessageBox.alert('Error', 'Can not delete the posted adjustment');\n        return;\n    }\n    \n     _this.grid.ds.remove(i);\n     \n\n    i = _this.grid.ds.getAt(s[0]);\n    if (i) {\n        _this.grid.selModel.select(s[0], s[1]);\n        return;\n    }\n    var ln = s[0]-1;\n    if (ln < 0) {\n      return;\n    } // nothing left to select..\n    _this.grid.selModel.select(s[0]-1, s[1]);\n    \n    \n   \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Delete",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Upload",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Menu",
+                                                                    "*prop": "menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    var group = _this.form.findField('invadjgrp_id').getValue() * 1;\n    \n    if(!group || group < 1){\n        Roo.MessageBox.alert('Error', 'Please save the group first!');\n        return;\n    }\n    if(_this.data.invadjgrp_posted){\n        Roo.MessageBox.alert('Error', 'This group has been posted');\n        return;\n    }\n    \n    var rn = _this.grid.ds.getCount();\n    \n    var addRow = function(r) {\n        if(r.invadj_itemsite_id * 1 < 1 || r.qty * 1 == 0){\n            return;\n        }\n        \n        var nr = _this.grid.ds.reader.newRow({\n            invadj_itemsite_id_item_number : r.item_number,\n            invadj_itemsite_id : r.itemsite_id,\n            invadj_qty_before : r.balance * 1,\n            invadj_qty_by : r.qty * 1,\n            invadj_qty_after : r.balance * 1 + r.qty * 1\n            \n       });\n        _this.grid.ds.insert(rn++, nr); \n    \n    \n    }\n    \n    Pman.Dialog.Image.show(\n       {\n            timeout : 90000,\n            _url : baseURL+'/Xtuple/Import/InvAdjustment?' + Roo.urlEncode({'invadjgrp_id' : group})\n        \n       },\n       function (r) {\n\n            Roo.each(r, addRow);\n            \n            Roo.MessageBox.alert(\"Notice\", 'UPLOADED');\n       }\n    );\n}"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Upload Inventory Adjustments (eg. increases or decreases)",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    var group = _this.form.findField('invadjgrp_id').getValue() * 1;\n    \n    if(!group || group < 1){\n        Roo.MessageBox.alert('Error', 'Please save the group first!');\n        return;\n    }\n    if(_this.data.invadjgrp_posted){\n        Roo.MessageBox.alert('Error', 'This group has been posted');\n        return;\n    }\n    \n    var rn = _this.grid.ds.getCount();\n    \n    var addRow = function(r) {\n        if(r.invadj_itemsite_id * 1 < 1 || (r.qty * 1 - r.balance * 1) == 0){\n            return;\n        }\n        \n        var nr = _this.grid.ds.reader.newRow({\n            invadj_itemsite_id_item_number : r.item_number,\n            invadj_itemsite_id : r.itemsite_id,\n            invadj_qty_before : r.balance * 1,\n            invadj_qty_by : r.qty * 1 - r.balance * 1,\n            invadj_qty_after : r.qty * 1\n            \n       });\n        _this.grid.ds.insert(rn++, nr); \n    \n    \n    }\n    \n    Pman.Dialog.Image.show(\n       {\n            timeout : 90000,\n            _url : baseURL+'/Xtuple/Import/InvAdjustment?' + Roo.urlEncode({'invadjgrp_id' : group})\n        \n       },\n       function (r) {\n\n            Roo.each(r, addRow);\n            \n            Roo.MessageBox.alert(\"Notice\", 'UPLOADED');\n       }\n    );\n}"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Upload Inventory Stock take Results",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function ()\n{\n    new Pman.Download({\n        grid : _this.grid\n    });\n    Roo.MessageBox.alert(\"Downloading\", \"File is downloading\");\n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Download",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o){\n    \n    o.params = o.params || {};\n    var group = _this.form.findField('invadjgrp_id').getValue() * 1;\n\n    if(!group || group < 1){\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    o.params.invadj_invadjgrp_id = group;\n\n    o.params._with_detail = 1;    \n    o.params.limit = 99999;\n}\n"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'invadj_itemsite_id_item_number', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "timeout": 90000,
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/Invadj.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "invadj_id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\n    {\n        'name': 'invadj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invadj_qty_by',\n        'type': 'int'\n    }\n]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invadj_id",
+                                                    "header": "Ref#",
+                                                    "hidden": true,
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invadj_itemsite_id_item_number",
+                                                    "header": "Code",
+                                                    "width": 200,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.grid",
+                                                            "xtype": "GridEditor",
+                                                            "*prop": "editor",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "beforeselect": "function (combo, record, index)\n{\n    var ar = _this.grid.activeEditor.record;\n\n    ar.set('invadj_itemsite_id_item_number', record.data.itemsite_item_id_item_number);\n    ar.set('invadj_itemsite_id', record.data.itemsite_id);\n    ar.set('invadj_qty_before', record.data.balance_atdate);\n\n  \n}"
+                                                                    },
+                                                                    "*prop": "field",
+                                                                    "allowBlank": false,
+                                                                    "displayField": "itemsite_item_id_item_number",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select item",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "invadj_itemsite_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "invadj_itemsite_id_item_number",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select item",
+                                                                    "queryParam": "query[number]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b>  {itemsite_item_id_item_descrip1} ({balance_atdate})</div>",
+                                                                    "triggerAction": "all",
+                                                                    "valueField": "itemsite_id",
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n    o.params._location = _this.form.findField('invadjgrp_location_id').getValue();\n    \n    var dt = _this.form.findField('invadjgrp_transdate').getValue();\n    \n    o.params._atdate = (typeof(dt) == 'string') ? dt : dt.format('Y-m-d');\n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'itemsite_item_id_item_number' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "item_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[{\"name\":\"item_id\",\"type\":\"int\"},\"item_number\"]",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invadj_qty_before",
+                                                    "header": "Qty Before",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invadj_qty_by",
+                                                    "header": "Qty",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.grid",
+                                                            "xtype": "GridEditor",
+                                                            "*prop": "editor",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "field",
+                                                                    "allowDecimals": false,
+                                                                    "decimalPrecision": 0,
+                                                                    "style": "text-align:right",
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invadj_qty_after",
+                                                    "header": "Qty After",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.grid",
+                                                            "xtype": "GridEditor",
+                                                            "*prop": "editor",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "field",
+                                                                    "allowDecimals": false,
+                                                                    "decimalPrecision": 0,
+                                                                    "style": "text-align:right",
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    var items = [];\n    var ar = [];\n    var err = [];\n    \n   _this.grid.ds.each(function (r) {\n        if(r.data.invadj_qty_by * 1 == 0){\n            return;\n        }\n        if(items.indexOf(r.data.invadj_itemsite_id * 1) != -1){\n            err.push(r.data.invadj_itemsite_id_item_number);\n            return;\n        }\n        \n        items.push(r.data.invadj_itemsite_id * 1);\n        \n        ar.push({\n            invadj_id : r.data.invadj_id * 1,\n            invadj_itemsite_id : r.data.invadj_itemsite_id * 1,\n            invadj_qty_by : r.data.invadj_qty_by * 1\n        })\n   });\n   \n   if(err.length){\n        Roo.MessageBox.alert(\"Error\", \"Duplicate Item found : <br/>\" + err.join(\"<br/>\"));\n        return;\n   }\n   \n   _this.form.findField('adjustments').setValue(Roo.encode(ar));\n   _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleAdjustmentGroup.js b/Pman.Dialog.XtupleAdjustmentGroup.js
new file mode 100644 (file)
index 0000000..50044c7
--- /dev/null
@@ -0,0 +1,800 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleAdjustmentGroup = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 500,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create Inventory Adjustment Group",
+            width : 600,
+            items : [
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'center',
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'ContentPanel',
+                                xns: Roo,
+                                region : 'north',
+                                items : [
+                                    {
+                                        xtype: 'Form',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            actioncomplete : function(_self,action)
+                                            {
+                                                if (action.type == 'setdata') {
+                                                    _this.grid.ds.removeAll();
+                                                    _this.saveBtn.show();
+                                                    if(_this.data.invadjgrp_id){
+                                                   
+                                                        this.load({ method: 'GET', params: { '_id' : _this.data.invadjgrp_id }});
+                                                    }
+                                                   return;
+                                                }
+                                                if (action.type == 'load') {
+                                                    _this.data = action.result.data;
+                                                    if(_this.data.invadjgrp_posted){
+                                                        _this.saveBtn.hide();
+                                                    }
+                                            
+                                                    _this.grid.ds.load({});
+                                                    return;
+                                                }
+                                                if (action.type =='submit') {
+                                                    
+                                                
+                                                    if (!_this.grid.ds.getCount()  && this.findField('invadjgrp_id').getValue()*1 < 1) {
+                                                    
+                                                    
+                                                    
+                                                        this.load({ method: 'GET', params: { '_id' : action.result.data.invadjgrp_id }});
+                                                        return;
+                                                    
+                                                    }
+                                            
+                                                    _this.dialog.hide();
+                                                
+                                                     if (_this.callback) {
+                                                        _this.callback.call(_this, _this.form.getValues());
+                                                     }
+                                                     _this.form.reset();
+                                                     return;
+                                                }
+                                            },
+                                            rendered : function (form)
+                                            {
+                                                _this.form= form;
+                                            }
+                                        },
+                                        method : 'POST',
+                                        style : 'margin:10px;',
+                                        url : baseURL + '/Roo/Invadjgrp.php',
+                                        items : [
+                                            {
+                                                xtype: 'FieldSet',
+                                                xns: Roo.form,
+                                                legend : "Inventory Adjustment Group Detail",
+                                                style : 'width:520px',
+                                                items : [
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        fieldLabel : 'Name',
+                                                        name : 'invadjgrp_name',
+                                                        width : 200
+                                                    },
+                                                    {
+                                                        xtype: 'DateField',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        fieldLabel : 'Date',
+                                                        format : 'Y-m-d',
+                                                        name : 'invadjgrp_transdate',
+                                                        useIso : true,
+                                                        width : 200
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        displayField : 'location_name',
+                                                        editable : false,
+                                                        emptyText : "Select Location",
+                                                        fieldLabel : 'Location',
+                                                        forceSelection : true,
+                                                        hiddenName : 'invadjgrp_location_id',
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        name : 'invadjgrp_location_id_location_name',
+                                                        pageSize : 20,
+                                                        qtip : "Select Location",
+                                                        queryParam : 'query[location_name]',
+                                                        selectOnFocus : true,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> {location_descrip} </div>',
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        valueField : 'location_id',
+                                                        width : 200,
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    
+                                                                    o.params = o.params || {};
+                                                                    o.params.location_netable = 1;
+                                                                    o.params._notinternalcompany = 1;
+                                                                    o.params.location_restrict = 0;
+                                                                }
+                                                            },
+                                                            remoteSort : true,
+                                                            sortInfo : { direction : 'ASC', field: 'curr_id' },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/location.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'location_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [
+                                                                    {"name":"location_id","type":"int"},
+                                                                    {"name":"location_name","type":"string"}
+                                                                ]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        allowBlank : true,
+                                                        fieldLabel : 'Comments',
+                                                        name : 'invadjgrp_comments',
+                                                        width : 400
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'invadjgrp_id'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'adjustments'
+                                            }
+                                        ]
+                                    }
+                                ]
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.panel = this;
+                                        if (_this.grid) {
+                                            _this.grid.ds.load({});
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'invadj',
+                                title : "Invadj",
+                                grid : {
+                                    xtype: 'EditorGrid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.grid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.panel.active) {
+                                               this.ds.load({});
+                                            }
+                                        },
+                                        beforeedit : function (e)
+                                        {
+                                            if(_this.data.invadjgrp_posted){
+                                                Roo.MessageBox.alert('Error', 'This group has been posted');
+                                                return false;
+                                            }
+                                            
+                                            if(e.record.data.invadj_posted){
+                                                Roo.MessageBox.alert('Error', 'Can not update the posted adjustment');
+                                                return false;
+                                            }
+                                            
+                                            if(e.field != 'invadj_itemsite_id_item_number'){
+                                                var itemsite_id = e.record.data.invadj_itemsite_id * 1
+                                                if(isNaN(itemsite_id) || itemsite_id < 1){
+                                                    Roo.MessageBox.alert('Error', 'Please select a item first');
+                                                    return false;
+                                                }
+                                            }
+                                        },
+                                        afteredit : function (e)
+                                        {
+                                            if (e.originalValue == e.value) {
+                                                return;
+                                            }
+                                            
+                                            switch(e.field) {
+                                                case 'invadj_qty_by' :
+                                                    e.record.set('invadj_qty_after', parseInt(e.record.data.invadj_qty_before * 1 + e.value * 1));
+                                                    break;
+                                                
+                                                case 'invadj_qty_after' :
+                                                    e.record.set('invadj_qty_by', parseInt(e.value * 1 - e.record.data.invadj_qty_before * 1));
+                                                    break;
+                                                
+                                                case 'invadj_itemsite_id_item_number' :
+                                                    e.record.set('invadj_qty_after', parseInt(e.record.data.invadj_qty_before * 1 + e.record.data.invadj_qty_by * 1));
+                                                    break;
+                                            
+                                            }
+                                        }
+                                    },
+                                    autoExpandColumn : 'invadj_itemsite_id_item_number',
+                                    clicksToEdit : 1,
+                                    loadMask : true,
+                                    sm : {
+                                        xtype: 'CellSelectionModel',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            tabend : function (_self)
+                                            {
+                                                _this.addItemBtn.fireEvent('click', _this.addItemBtn);
+                                            }
+                                        }
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var group = _this.form.findField('invadjgrp_id').getValue() * 1;
+                                                        
+                                                        if(!group || group < 1){
+                                                            Roo.MessageBox.alert('Error', 'Please save the group first!');
+                                                            return;
+                                                        }
+                                                        
+                                                        if(_this.data.invadjgrp_posted){
+                                                            Roo.MessageBox.alert('Error', 'This group has been posted');
+                                                            return;
+                                                        }
+                                                        
+                                                        var nr = _this.grid.ds.reader.newRow({
+                                                            invadj_itemsite_id_item_number : '',
+                                                            invadj_itemsite_id : 0,
+                                                            invadj_qty_before : 0,
+                                                            invadj_qty_by : 0,
+                                                            invadj_qty_after : 0
+                                                            
+                                                       });
+                                                    
+                                                        _this.grid.stopEditing();
+                                                        _this.grid.ds.insert(_this.grid.ds.getCount(), nr); 
+                                                        _this.grid.startEditing(_this.grid.ds.getCount()-1, 0); // type..
+                                                       
+                                                    },
+                                                    render : function (_self)
+                                                    {
+                                                        _this.addItemBtn = _self;
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                        _this.grid.stopEditing();
+                                                        
+                                                        if(_this.data.invadjgrp_posted){
+                                                            Roo.MessageBox.alert('Error', 'This group has been posted');
+                                                            return;
+                                                        }
+                                                        
+                                                        var s = _this.grid.getSelectionModel().getSelectedCell();
+                                                        
+                                                        if(!s){
+                                                            Roo.MessageBox.alert('Error', 'Please select a adjustment to delete');
+                                                            return;
+                                                        }
+                                                        
+                                                        var i = _this.grid.ds.getAt(s[0]);
+                                                        
+                                                        if(i.data.invadj_posted){
+                                                            Roo.MessageBox.alert('Error', 'Can not delete the posted adjustment');
+                                                            return;
+                                                        }
+                                                        
+                                                         _this.grid.ds.remove(i);
+                                                         
+                                                    
+                                                        i = _this.grid.ds.getAt(s[0]);
+                                                        if (i) {
+                                                            _this.grid.selModel.select(s[0], s[1]);
+                                                            return;
+                                                        }
+                                                        var ln = s[0]-1;
+                                                        if (ln < 0) {
+                                                          return;
+                                                        } // nothing left to select..
+                                                        _this.grid.selModel.select(s[0]-1, s[1]);
+                                                        
+                                                        
+                                                       
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Delete",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                cls : 'x-btn-text-icon',
+                                                text : "Upload",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif',
+                                                menu : {
+                                                    xtype: 'Menu',
+                                                    xns: Roo.menu,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    var group = _this.form.findField('invadjgrp_id').getValue() * 1;
+                                                                    
+                                                                    if(!group || group < 1){
+                                                                        Roo.MessageBox.alert('Error', 'Please save the group first!');
+                                                                        return;
+                                                                    }
+                                                                    if(_this.data.invadjgrp_posted){
+                                                                        Roo.MessageBox.alert('Error', 'This group has been posted');
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    var rn = _this.grid.ds.getCount();
+                                                                    
+                                                                    var addRow = function(r) {
+                                                                        if(r.invadj_itemsite_id * 1 < 1 || r.qty * 1 == 0){
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var nr = _this.grid.ds.reader.newRow({
+                                                                            invadj_itemsite_id_item_number : r.item_number,
+                                                                            invadj_itemsite_id : r.itemsite_id,
+                                                                            invadj_qty_before : r.balance * 1,
+                                                                            invadj_qty_by : r.qty * 1,
+                                                                            invadj_qty_after : r.balance * 1 + r.qty * 1
+                                                                            
+                                                                       });
+                                                                        _this.grid.ds.insert(rn++, nr); 
+                                                                    
+                                                                    
+                                                                    }
+                                                                    
+                                                                    Pman.Dialog.Image.show(
+                                                                       {
+                                                                            timeout : 90000,
+                                                                            _url : baseURL+'/Xtuple/Import/InvAdjustment?' + Roo.urlEncode({'invadjgrp_id' : group})
+                                                                        
+                                                                       },
+                                                                       function (r) {
+                                                                
+                                                                            Roo.each(r, addRow);
+                                                                            
+                                                                            Roo.MessageBox.alert("Notice", 'UPLOADED');
+                                                                       }
+                                                                    );
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Upload Inventory Adjustments (eg. increases or decreases)",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    var group = _this.form.findField('invadjgrp_id').getValue() * 1;
+                                                                    
+                                                                    if(!group || group < 1){
+                                                                        Roo.MessageBox.alert('Error', 'Please save the group first!');
+                                                                        return;
+                                                                    }
+                                                                    if(_this.data.invadjgrp_posted){
+                                                                        Roo.MessageBox.alert('Error', 'This group has been posted');
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    var rn = _this.grid.ds.getCount();
+                                                                    
+                                                                    var addRow = function(r) {
+                                                                        if(r.invadj_itemsite_id * 1 < 1 || (r.qty * 1 - r.balance * 1) == 0){
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var nr = _this.grid.ds.reader.newRow({
+                                                                            invadj_itemsite_id_item_number : r.item_number,
+                                                                            invadj_itemsite_id : r.itemsite_id,
+                                                                            invadj_qty_before : r.balance * 1,
+                                                                            invadj_qty_by : r.qty * 1 - r.balance * 1,
+                                                                            invadj_qty_after : r.qty * 1
+                                                                            
+                                                                       });
+                                                                        _this.grid.ds.insert(rn++, nr); 
+                                                                    
+                                                                    
+                                                                    }
+                                                                    
+                                                                    Pman.Dialog.Image.show(
+                                                                       {
+                                                                            timeout : 90000,
+                                                                            _url : baseURL+'/Xtuple/Import/InvAdjustment?' + Roo.urlEncode({'invadjgrp_id' : group})
+                                                                        
+                                                                       },
+                                                                       function (r) {
+                                                                
+                                                                            Roo.each(r, addRow);
+                                                                            
+                                                                            Roo.MessageBox.alert("Notice", 'UPLOADED');
+                                                                       }
+                                                                    );
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Upload Inventory Stock take Results",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        }
+                                                    ]
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                        new Pman.Download({
+                                                            grid : _this.grid
+                                                        });
+                                                        Roo.MessageBox.alert("Downloading", "File is downloading");
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Download",
+                                                icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                                            }
+                                        ]
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                
+                                                o.params = o.params || {};
+                                                var group = _this.form.findField('invadjgrp_id').getValue() * 1;
+                                            
+                                                if(!group || group < 1){
+                                                    _this.grid.ds.removeAll();
+                                                    return false;
+                                                }
+                                                o.params.invadj_invadjgrp_id = group;
+                                            
+                                                o.params._with_detail = 1;    
+                                                o.params.limit = 99999;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'invadj_itemsite_id_item_number', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            timeout : 90000,
+                                            url : baseURL + '/Roo/Invadj.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'invadj_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {
+                                                    'name': 'invadj_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invadj_qty_by',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invadj_id',
+                                            header : 'Ref#',
+                                            hidden : true,
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invadj_itemsite_id_item_number',
+                                            header : 'Code',
+                                            width : 200,
+                                            renderer : function(v) { return String.format('{0}', v); },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        beforeselect : function (combo, record, index)
+                                                        {
+                                                            var ar = _this.grid.activeEditor.record;
+                                                        
+                                                            ar.set('invadj_itemsite_id_item_number', record.data.itemsite_item_id_item_number);
+                                                            ar.set('invadj_itemsite_id', record.data.itemsite_id);
+                                                            ar.set('invadj_qty_before', record.data.balance_atdate);
+                                                        
+                                                          
+                                                        }
+                                                    },
+                                                    allowBlank : false,
+                                                    displayField : 'itemsite_item_id_item_number',
+                                                    editable : true,
+                                                    emptyText : "Select item",
+                                                    forceSelection : true,
+                                                    hiddenName : 'invadj_itemsite_id',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'invadj_itemsite_id_item_number',
+                                                    pageSize : 20,
+                                                    qtip : "Select item",
+                                                    queryParam : 'query[number]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b>  {itemsite_item_id_item_descrip1} ({balance_atdate})</div>',
+                                                    triggerAction : 'all',
+                                                    valueField : 'itemsite_id',
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                
+                                                                o.params._location = _this.form.findField('invadjgrp_location_id').getValue();
+                                                                
+                                                                var dt = _this.form.findField('invadjgrp_transdate').getValue();
+                                                                
+                                                                o.params._atdate = (typeof(dt) == 'string') ? dt : dt.format('Y-m-d');
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'itemsite_item_id_item_number' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/itemsite.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'item_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"item_id","type":"int"},"item_number"]
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invadj_qty_before',
+                                            header : 'Qty Before',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invadj_qty_by',
+                                            header : 'Qty',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'NumberField',
+                                                    xns: Roo.form,
+                                                    allowDecimals : false,
+                                                    decimalPrecision : 0,
+                                                    style : 'text-align:right'
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invadj_qty_after',
+                                            header : 'Qty After',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'NumberField',
+                                                    xns: Roo.form,
+                                                    allowDecimals : false,
+                                                    decimalPrecision : 0,
+                                                    style : 'text-align:right'
+                                                }
+                                            }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        north : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            height : 150,
+                            split : true
+                        },
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        }
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                tabPosition : 'top'
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            var items = [];
+                            var ar = [];
+                            var err = [];
+                            
+                           _this.grid.ds.each(function (r) {
+                                if(r.data.invadj_qty_by * 1 == 0){
+                                    return;
+                                }
+                                if(items.indexOf(r.data.invadj_itemsite_id * 1) != -1){
+                                    err.push(r.data.invadj_itemsite_id_item_number);
+                                    return;
+                                }
+                                
+                                items.push(r.data.invadj_itemsite_id * 1);
+                                
+                                ar.push({
+                                    invadj_id : r.data.invadj_id * 1,
+                                    invadj_itemsite_id : r.data.invadj_itemsite_id * 1,
+                                    invadj_qty_by : r.data.invadj_qty_by * 1
+                                })
+                           });
+                           
+                           if(err.length){
+                                Roo.MessageBox.alert("Error", "Duplicate Item found : <br/>" + err.join("<br/>"));
+                                return;
+                           }
+                           
+                           _this.form.findField('adjustments').setValue(Roo.encode(ar));
+                           _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleContact.bjs b/Pman.Dialog.XtupleContact.bjs
new file mode 100644 (file)
index 0000000..d7960de
--- /dev/null
@@ -0,0 +1,412 @@
+{
+    "id": "roo-file-2",
+    "name": "Pman.Dialog.XtupleContact",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleContact.bjs",
+    "items": [
+        {
+            ".builderCfg": "{\"cols\":[{\"table\":\"cntct\",\"column\":\"cntct_id\",\"columnshort\":\"cntct_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\",\"display\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_addr_id\",\"columnshort\":\"cntct_addr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"addr_id\",\"deps\":[{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_active\",\"columnshort\":\"addr_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line1\",\"columnshort\":\"addr_line1\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line2\",\"columnshort\":\"addr_line2\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line3\",\"columnshort\":\"addr_line3\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_city\",\"columnshort\":\"addr_city\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_state\",\"columnshort\":\"addr_state\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_postalcode\",\"columnshort\":\"addr_postalcode\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_country\",\"columnshort\":\"addr_country\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_notes\",\"columnshort\":\"addr_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_number\",\"columnshort\":\"addr_number\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\",\"display\":\"cntct_addr_id_addr_line1\"},{\"table\":\"cntct\",\"column\":\"cntct_first_name\",\"columnshort\":\"cntct_first_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_last_name\",\"columnshort\":\"cntct_last_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_honorific\",\"columnshort\":\"cntct_honorific\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_initials\",\"columnshort\":\"cntct_initials\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_active\",\"columnshort\":\"cntct_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_fax\",\"columnshort\":\"cntct_fax\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_email\",\"columnshort\":\"cntct_email\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_webaddr\",\"columnshort\":\"cntct_webaddr\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_notes\",\"columnshort\":\"cntct_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_title\",\"columnshort\":\"cntct_title\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_number\",\"columnshort\":\"cntct_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_middle\",\"columnshort\":\"cntct_middle\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_suffix\",\"columnshort\":\"cntct_suffix\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"cntct_addr_id_addr_line1\"],\"table\":\"cntct\",\"xtype\":\"LayoutDialog\",\"|xns\":\"Roo\"}",
+            "closable": false,
+            "collapsible": false,
+            "height": 450,
+            "modal": true,
+            "resizable": false,
+            "title": "Contact Details",
+            "width": 800,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if (_this.data.cntct_id) {\n            this.load({ method: 'GET', params: { '_id' : _this.data.cntct_id }});\n            return;\n        } \n        // we need to fetch crmct id..\n        new Pman.Request({\n            method : 'GET',\n            url : baseURL + '/Roo/crmacct',\n            params : {\n                crmacct_cust_id : _this.data.customer_id\n            },\n            success : function(r) {\n//                Roo.log(r);\n                try {\n                    _this.form.findField('cntct_crmacct_id').setValue(r.data[0].crmacct_id);\n                } catch(e) {\n                    Roo.MessageBox.alert(\"Error\", \"Sorry, we failed got get some data from the server, please cancel and try again\");\n                }\n            }\n        });\n\n    }\n    if (action.type == 'load') {\n        _this.form.findField('cntct_name').sync();\n          _this.form.findField('addr_view').sync();\n    \n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n         _this.form.setValues(action.result.data);\n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cntct.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "legend": "Details",
+                                    "style": "width:750px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "labelAlign": "right",
+                                            "labelWidth": 70,
+                                            "width": 800,
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "blur": "function (_self)\n{\n _this.form.findField('cntct_name').sync();\n}"
+                                                    },
+                                                    "allowBlank": true,
+                                                    "displayField": "hnfc_code",
+                                                    "editable": false,
+                                                    "emptyText": "Title",
+                                                    "fieldLabel": "Name",
+                                                    "hiddenName": "cntct_honorific",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "cntct_honorific",
+                                                    "qtip": "Select title",
+                                                    "queryParam": "query[addr_line1]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{hnfc_code}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "hnfc_code",
+                                                    "width": 60,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "|xns": "Roo.data",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'addr_line1' }",
+                                                            "xtype": "Store",
+                                                            "remoteSort": true,
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                            },
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/hnfc.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "hnfc_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{'name':'hnfc_id','type':'int'},'hnfc_code']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "hideLabels": true,
+                                                    "labelAlign": "top",
+                                                    "width": 700,
+                                                    "xtype": "Row",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "keyup": "function (_self, e)\n{\n       _this.form.findField('cntct_name').sync();\n}"
+                                                            },
+                                                            "fieldLabel": "first_name",
+                                                            "name": "cntct_first_name",
+                                                            "qtip": "First name",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "keyup": "function (_self, e)\n{\n       _this.form.findField('cntct_name').sync();\n}"
+                                                            },
+                                                            "fieldLabel": "initials",
+                                                            "name": "cntct_initials",
+                                                            "qtip": "Initials",
+                                                            "width": 40,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "keyup": "function (_self, e)\n{\n       _this.form.findField('cntct_name').sync();\n}"
+                                                            },
+                                                            "fieldLabel": "last_name",
+                                                            "name": "cntct_last_name",
+                                                            "qtip": "Last name",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelAlign": "right",
+                                            "labelWidth": 70,
+                                            "width": 900,
+                                            "xtype": "Column",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelAlign": "right",
+                                                    "labelWidth": 70,
+                                                    "width": 900,
+                                                    "xtype": "Row",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "qtip": "Job Title",
+                                                            "fieldLabel": "Job Title",
+                                                            "name": "cntct_title",
+                                                            "width": 335,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Unique#",
+                                                            "name": "cntct_number",
+                                                            "width": 100,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "labelAlign": "right",
+                                    "labelWidth": 70,
+                                    "legend": "Contact",
+                                    "style": "width:300px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "fieldLabel": "Phone",
+                                            "name": "cntct_phone",
+                                            "width": 200,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Mobile",
+                                            "name": "cntct_phone2",
+                                            "width": 200,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Fax",
+                                            "name": "cntct_fax",
+                                            "width": 200,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "legend": "Online",
+                                    "style": "width:400px; margin-left:10px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "fieldLabel": "Email",
+                                            "name": "cntct_email",
+                                            "vtype": "email",
+                                            "width": 250,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Website",
+                                            "name": "cntct_webaddr",
+                                            "vtype": "url",
+                                            "width": 250,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "hideLabels": true,
+                                    "legend": "Notes",
+                                    "style": "width:300px; clear: both;",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "fieldLabel": "notes",
+                                            "height": 100,
+                                            "name": "cntct_notes",
+                                            "width": 290,
+                                            "xtype": "TextArea",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "hideLabels": true,
+                                    "legend": "Address",
+                                    "style": "width:400px; margin-left:10px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "add": "function (combo)\n{\n   Pman.Dialog.XtupleAddress.show({\n        addr_id : '',\n        customer_id : _this.form.findField('customer_id').getValue()\n   \n   }, function(d) {\n               Roo.log(d);\n        if (!d) {\n            return;\n        }\n        var s = {};\n        for (var k in d) {\n            s['cntct_addr_id_' + k] = d[k];\n        }\n\n        s.cntct_addr_id = d.addr_id;\n        Roo.log(s);                \n        _this.form.setValues(s);\n        // if d contains a value.. use it..\n        _this.form.findField('addr_view').sync();\n   \n   \n   });\n}",
+                                                "edit": "function (combo, record)\n{\n  Pman.Dialog.XtupleAddress.show({\n        addr_id : this.getValue(),\n        customer_id : _this.form.findField('customer_id').getValue()\n   \n   }, function(d) {\n   \n       // Roo.log(d);\n        if (!d) {\n            return;\n        }\n        var s = {};\n        for (var k in d) {\n            s['cntct_addr_id_' + k] = d[k];\n        }\n        s.cntct_addr_id = d.addr_id;\n        Roo.log(s);\n        _this.form.setValues(s);\n            _this.form.findField('addr_view').sync();\n        // if d contains a value.. use it..\n   \n   });\n}",
+                                                "select": "function (combo, record, index)\n{\n    var s = {};\n    for (var k in record.data) {\n        s['cntct_addr_id_' + k] = record.data[k];\n    }\n\n    _this.form.setValues(s);\n    _this.form.findField('addr_view').sync();\n}"
+                                            },
+                                            "allowBlank": false,
+                                            "alwaysQuery": true,
+                                            "displayField": "addr_line1",
+                                            "editable": false,
+                                            "emptyText": "Select address",
+                                            "fieldLabel": "addr",
+                                            "forceSelection": true,
+                                            "hiddenName": "cntct_addr_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "cntct_addr_id_addr_line1",
+                                            "pageSize": 20,
+                                            "qtip": "Select addr",
+                                            "queryParam": "query[addr_line1]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>#{addr_id} - {addr_line1}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "addr_id",
+                                            "width": 380,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params._customer_id = _this.form.findField('customer_id').getValue();\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'addr_line1' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/addr.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "addr_id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[{'name':'addr_id','type':'int'},'addr_line1']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "fieldLabel": "notes",
+                                            "height": 80,
+                                            "name": "addr_view",
+                                            "width": 380,
+                                            "xtype": "TextArea",
+                                            "|sync": "function() {\n    var vals= _this.form.getFieldValues();\n    var lines = [];\n    if (vals.cntct_addr_id * 1 < 1) {\n        this.setValue(\"No address set, this will cause an error\");\n        return;\n    }\n    for (var i in vals) {\n        if (i.match(/^cntct_addr_id_addr/) && vals[i].length) {\n            lines.push(vals[i]);\n        }\n    }\n    this.setValue(lines.join(\"\\n\"));\n}\n",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "cntct_name",
+                                    "xtype": "Hidden",
+                                    "|readName": "function() {\n    var ar = [ 'honorific', 'first_name', 'initials', 'last_name' ];\n    var out = [];\n    Roo.each(ar, function (n) {\n        var v = _this.form.findField('cntct_' + n).getValue();\n        if (v.trim().length) {\n            out.push(v.trim());\n        }\n    });\n    return out.join(' ');\n}\n",
+                                    "|sync": "function() {\n    var dname = this.readName();\n    if (!dname.length && this.getValue().length) {\n        _this.form.findField('cntct_first_name').setValue(this.getValue());\n \n          \n    } else {\n    \n        this.setValue(dname);\n    }\n    _this.dialog.setTitle(\"Contact Details - \" + this.getValue());\n    if (_this.form.findField('cntct_id').getValue() * 1 < 1) {\n        var cn = 'C' +    _this.form.findField('customer_id').getValue()  + '-';\n        _this.form.findField('cntct_number').setValue(cn + this.getValue());\n    }\n    \n    \n}\n",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id_addr_line2",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id_addr_line3",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id_addr_city",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id_addr_state",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id_addr_country",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "customer_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_crmacct_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form",
+                                    "name": "cntct_id"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     var id=    _this.form.findField('cntct_crmacct_id').getValue();\n    if (!id) {\n        Roo.MessageBox.alert(\"Error\", \"Sorry, Something failed, please cancel and try re-creatating\");\n        return;\n    }\n     \n \n    _this.form.doAction('submit');\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleContact.js b/Pman.Dialog.XtupleContact.js
new file mode 100644 (file)
index 0000000..653918e
--- /dev/null
@@ -0,0 +1,590 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleContact = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 450,
+            modal : true,
+            resizable : false,
+            title : "Contact Details",
+            width : 800,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if (_this.data.cntct_id) {
+                                            this.load({ method: 'GET', params: { '_id' : _this.data.cntct_id }});
+                                            return;
+                                        } 
+                                        // we need to fetch crmct id..
+                                        new Pman.Request({
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/crmacct',
+                                            params : {
+                                                crmacct_cust_id : _this.data.customer_id
+                                            },
+                                            success : function(r) {
+                                //                Roo.log(r);
+                                                try {
+                                                    _this.form.findField('cntct_crmacct_id').setValue(r.data[0].crmacct_id);
+                                                } catch(e) {
+                                                    Roo.MessageBox.alert("Error", "Sorry, we failed got get some data from the server, please cancel and try again");
+                                                }
+                                            }
+                                        });
+                                
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.form.findField('cntct_name').sync();
+                                          _this.form.findField('addr_view').sync();
+                                    
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                         _this.form.setValues(action.result.data);
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/cntct.php',
+                            items : [
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Details",
+                                    style : 'width:750px',
+                                    items : [
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            labelAlign : 'right',
+                                            labelWidth : 70,
+                                            width : 800,
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        blur : function (_self)
+                                                        {
+                                                         _this.form.findField('cntct_name').sync();
+                                                        }
+                                                    },
+                                                    allowBlank : true,
+                                                    displayField : 'hnfc_code',
+                                                    editable : false,
+                                                    emptyText : "Title",
+                                                    fieldLabel : 'Name',
+                                                    hiddenName : 'cntct_honorific',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'cntct_honorific',
+                                                    qtip : "Select title",
+                                                    queryParam : 'query[addr_line1]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{hnfc_code}</b> </div>',
+                                                    triggerAction : 'all',
+                                                    typeAhead : true,
+                                                    valueField : 'hnfc_code',
+                                                    width : 60,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        sortInfo : { direction : 'ASC', field: 'addr_line1' },
+                                                        remoteSort : true,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                // set more here
+                                                            }
+                                                        },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/hnfc.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'hnfc_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{'name':'hnfc_id','type':'int'},'hnfc_code']
+                                                        }
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Row',
+                                                    xns: Roo.form,
+                                                    hideLabels : true,
+                                                    labelAlign : 'top',
+                                                    width : 700,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                keyup : function (_self, e)
+                                                                {
+                                                                       _this.form.findField('cntct_name').sync();
+                                                                }
+                                                            },
+                                                            fieldLabel : 'first_name',
+                                                            name : 'cntct_first_name',
+                                                            qtip : "First name",
+                                                            width : 200
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                keyup : function (_self, e)
+                                                                {
+                                                                       _this.form.findField('cntct_name').sync();
+                                                                }
+                                                            },
+                                                            fieldLabel : 'initials',
+                                                            name : 'cntct_initials',
+                                                            qtip : "Initials",
+                                                            width : 40
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                keyup : function (_self, e)
+                                                                {
+                                                                       _this.form.findField('cntct_name').sync();
+                                                                }
+                                                            },
+                                                            fieldLabel : 'last_name',
+                                                            name : 'cntct_last_name',
+                                                            qtip : "Last name",
+                                                            width : 200
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Column',
+                                            xns: Roo.form,
+                                            labelAlign : 'right',
+                                            labelWidth : 70,
+                                            width : 900,
+                                            items : [
+                                                {
+                                                    xtype: 'Row',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'right',
+                                                    labelWidth : 70,
+                                                    width : 900,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            qtip : "Job Title",
+                                                            fieldLabel : 'Job Title',
+                                                            name : 'cntct_title',
+                                                            width : 335
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Unique#',
+                                                            name : 'cntct_number',
+                                                            width : 100
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    labelAlign : 'right',
+                                    labelWidth : 70,
+                                    legend : "Contact",
+                                    style : 'width:300px',
+                                    items : [
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Phone',
+                                            name : 'cntct_phone',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Mobile',
+                                            name : 'cntct_phone2',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Fax',
+                                            name : 'cntct_fax',
+                                            width : 200
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Online",
+                                    style : 'width:400px; margin-left:10px',
+                                    items : [
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Email',
+                                            name : 'cntct_email',
+                                            vtype : 'email',
+                                            width : 250
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Website',
+                                            name : 'cntct_webaddr',
+                                            vtype : 'url',
+                                            width : 250
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    hideLabels : true,
+                                    legend : "Notes",
+                                    style : 'width:300px; clear: both;',
+                                    items : [
+                                        {
+                                            xtype: 'TextArea',
+                                            xns: Roo.form,
+                                            fieldLabel : 'notes',
+                                            height : 100,
+                                            name : 'cntct_notes',
+                                            width : 290
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    hideLabels : true,
+                                    legend : "Address",
+                                    style : 'width:400px; margin-left:10px',
+                                    items : [
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                add : function (combo)
+                                                {
+                                                   Pman.Dialog.XtupleAddress.show({
+                                                        addr_id : '',
+                                                        customer_id : _this.form.findField('customer_id').getValue()
+                                                   
+                                                   }, function(d) {
+                                                               Roo.log(d);
+                                                        if (!d) {
+                                                            return;
+                                                        }
+                                                        var s = {};
+                                                        for (var k in d) {
+                                                            s['cntct_addr_id_' + k] = d[k];
+                                                        }
+                                                
+                                                        s.cntct_addr_id = d.addr_id;
+                                                        Roo.log(s);                
+                                                        _this.form.setValues(s);
+                                                        // if d contains a value.. use it..
+                                                        _this.form.findField('addr_view').sync();
+                                                   
+                                                   
+                                                   });
+                                                },
+                                                edit : function (combo, record)
+                                                {
+                                                  Pman.Dialog.XtupleAddress.show({
+                                                        addr_id : this.getValue(),
+                                                        customer_id : _this.form.findField('customer_id').getValue()
+                                                   
+                                                   }, function(d) {
+                                                   
+                                                       // Roo.log(d);
+                                                        if (!d) {
+                                                            return;
+                                                        }
+                                                        var s = {};
+                                                        for (var k in d) {
+                                                            s['cntct_addr_id_' + k] = d[k];
+                                                        }
+                                                        s.cntct_addr_id = d.addr_id;
+                                                        Roo.log(s);
+                                                        _this.form.setValues(s);
+                                                            _this.form.findField('addr_view').sync();
+                                                        // if d contains a value.. use it..
+                                                   
+                                                   });
+                                                },
+                                                select : function (combo, record, index)
+                                                {
+                                                    var s = {};
+                                                    for (var k in record.data) {
+                                                        s['cntct_addr_id_' + k] = record.data[k];
+                                                    }
+                                                
+                                                    _this.form.setValues(s);
+                                                    _this.form.findField('addr_view').sync();
+                                                }
+                                            },
+                                            allowBlank : false,
+                                            alwaysQuery : true,
+                                            displayField : 'addr_line1',
+                                            editable : false,
+                                            emptyText : "Select address",
+                                            fieldLabel : 'addr',
+                                            forceSelection : true,
+                                            hiddenName : 'cntct_addr_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'cntct_addr_id_addr_line1',
+                                            pageSize : 20,
+                                            qtip : "Select addr",
+                                            queryParam : 'query[addr_line1]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>#{addr_id} - {addr_line1}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'addr_id',
+                                            width : 380,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        o.params._customer_id = _this.form.findField('customer_id').getValue();
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'addr_line1' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/addr.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'addr_id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{'name':'addr_id','type':'int'},'addr_line1']
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'TextArea',
+                                            xns: Roo.form,
+                                            fieldLabel : 'notes',
+                                            height : 80,
+                                            name : 'addr_view',
+                                            width : 380,
+                                            sync : function() {
+                                                var vals= _this.form.getFieldValues();
+                                                var lines = [];
+                                                if (vals.cntct_addr_id * 1 < 1) {
+                                                    this.setValue("No address set, this will cause an error");
+                                                    return;
+                                                }
+                                                for (var i in vals) {
+                                                    if (i.match(/^cntct_addr_id_addr/) && vals[i].length) {
+                                                        lines.push(vals[i]);
+                                                    }
+                                                }
+                                                this.setValue(lines.join("\n"));
+                                            }
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_name',
+                                    readName : function() {
+                                        var ar = [ 'honorific', 'first_name', 'initials', 'last_name' ];
+                                        var out = [];
+                                        Roo.each(ar, function (n) {
+                                            var v = _this.form.findField('cntct_' + n).getValue();
+                                            if (v.trim().length) {
+                                                out.push(v.trim());
+                                            }
+                                        });
+                                        return out.join(' ');
+                                    },
+                                    sync : function() {
+                                        var dname = this.readName();
+                                        if (!dname.length && this.getValue().length) {
+                                            _this.form.findField('cntct_first_name').setValue(this.getValue());
+                                     
+                                              
+                                        } else {
+                                        
+                                            this.setValue(dname);
+                                        }
+                                        _this.dialog.setTitle("Contact Details - " + this.getValue());
+                                        if (_this.form.findField('cntct_id').getValue() * 1 < 1) {
+                                            var cn = 'C' +    _this.form.findField('customer_id').getValue()  + '-';
+                                            _this.form.findField('cntct_number').setValue(cn + this.getValue());
+                                        }
+                                        
+                                        
+                                    }
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id_addr_line2'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id_addr_line3'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id_addr_city'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id_addr_state'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id_addr_country'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'customer_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_crmacct_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             var id=    _this.form.findField('cntct_crmacct_id').getValue();
+                            if (!id) {
+                                Roo.MessageBox.alert("Error", "Sorry, Something failed, please cancel and try re-creatating");
+                                return;
+                            }
+                             
+                         
+                            _this.form.doAction('submit');
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleCreditMemo.bjs b/Pman.Dialog.XtupleCreditMemo.bjs
new file mode 100644 (file)
index 0000000..9c03a47
--- /dev/null
@@ -0,0 +1,1427 @@
+{
+    "id": "roo-file-3",
+    "name": "Pman.Dialog.XtupleCreditMemo",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleCreditMemo.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|show": "function () {\n       this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            ".builderCfg": "{\"cols\":[{\"table\":\"cohead\",\"column\":\"cohead_number\",\"columnshort\":\"cohead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"},{\"table\":\"cohead\",\"column\":\"cohead_cust_id\",\"columnshort\":\"cohead_cust_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"cust_id\",\"deps\":[{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_active\",\"columnshort\":\"cust_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_custtype_id\",\"columnshort\":\"cust_custtype_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_salesrep_id\",\"columnshort\":\"cust_salesrep_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_commprcnt\",\"columnshort\":\"cust_commprcnt\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_creditlmt\",\"columnshort\":\"cust_creditlmt\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_creditrating\",\"columnshort\":\"cust_creditrating\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_financecharge\",\"columnshort\":\"cust_financecharge\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_backorder\",\"columnshort\":\"cust_backorder\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_partialship\",\"columnshort\":\"cust_partialship\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_terms_id\",\"columnshort\":\"cust_terms_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_discntprcnt\",\"columnshort\":\"cust_discntprcnt\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_balmethod\",\"columnshort\":\"cust_balmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ffshipto\",\"columnshort\":\"cust_ffshipto\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_shipform_id\",\"columnshort\":\"cust_shipform_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_shipvia\",\"columnshort\":\"cust_shipvia\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_blanketpos\",\"columnshort\":\"cust_blanketpos\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_shipchrg_id\",\"columnshort\":\"cust_shipchrg_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_creditstatus\",\"columnshort\":\"cust_creditstatus\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_comments\",\"columnshort\":\"cust_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ffbillto\",\"columnshort\":\"cust_ffbillto\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_usespos\",\"columnshort\":\"cust_usespos\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_number\",\"columnshort\":\"cust_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_dateadded\",\"columnshort\":\"cust_dateadded\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_exported\",\"columnshort\":\"cust_exported\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_emaildelivery\",\"columnshort\":\"cust_emaildelivery\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ediemail\",\"columnshort\":\"cust_ediemail\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_edisubject\",\"columnshort\":\"cust_edisubject\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_edifilename\",\"columnshort\":\"cust_edifilename\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ediemailbody\",\"columnshort\":\"cust_ediemailbody\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_autoupdatestatus\",\"columnshort\":\"cust_autoupdatestatus\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_autoholdorders\",\"columnshort\":\"cust_autoholdorders\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_edicc\",\"columnshort\":\"cust_edicc\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ediprofile_id\",\"columnshort\":\"cust_ediprofile_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_preferred_warehous_id\",\"columnshort\":\"cust_preferred_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_curr_id\",\"columnshort\":\"cust_curr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_creditlmt_curr_id\",\"columnshort\":\"cust_creditlmt_curr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_cntct_id\",\"columnshort\":\"cust_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_corrcntct_id\",\"columnshort\":\"cust_corrcntct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soemaildelivery\",\"columnshort\":\"cust_soemaildelivery\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soediemail\",\"columnshort\":\"cust_soediemail\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soedisubject\",\"columnshort\":\"cust_soedisubject\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soedifilename\",\"columnshort\":\"cust_soedifilename\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soediemailbody\",\"columnshort\":\"cust_soediemailbody\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soedicc\",\"columnshort\":\"cust_soedicc\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soediprofile_id\",\"columnshort\":\"cust_soediprofile_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_gracedays\",\"columnshort\":\"cust_gracedays\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_ediemailhtml\",\"columnshort\":\"cust_ediemailhtml\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_soediemailhtml\",\"columnshort\":\"cust_soediemailhtml\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_taxzone_id\",\"columnshort\":\"cust_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Customer\",\"display\":\"cohead_cust_id_cust_name\"},{\"table\":\"cohead\",\"column\":\"cohead_custponumber\",\"columnshort\":\"cohead_custponumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer PO#\"},{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"cohead\",\"column\":\"cohead_warehous_id\",\"columnshort\":\"cohead_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"warehous_id\",\"deps\":[{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_code\",\"columnshort\":\"warehous_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_descrip\",\"columnshort\":\"warehous_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_fob\",\"columnshort\":\"warehous_fob\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_active\",\"columnshort\":\"warehous_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_counttag_prefix\",\"columnshort\":\"warehous_counttag_prefix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_counttag_number\",\"columnshort\":\"warehous_counttag_number\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_bol_prefix\",\"columnshort\":\"warehous_bol_prefix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_bol_number\",\"columnshort\":\"warehous_bol_number\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_shipping\",\"columnshort\":\"warehous_shipping\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_useslips\",\"columnshort\":\"warehous_useslips\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_usezones\",\"columnshort\":\"warehous_usezones\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_aislesize\",\"columnshort\":\"warehous_aislesize\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_aislealpha\",\"columnshort\":\"warehous_aislealpha\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_racksize\",\"columnshort\":\"warehous_racksize\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_rackalpha\",\"columnshort\":\"warehous_rackalpha\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_binsize\",\"columnshort\":\"warehous_binsize\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_binalpha\",\"columnshort\":\"warehous_binalpha\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_locationsize\",\"columnshort\":\"warehous_locationsize\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_locationalpha\",\"columnshort\":\"warehous_locationalpha\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_enforcearbl\",\"columnshort\":\"warehous_enforcearbl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_default_accnt_id\",\"columnshort\":\"warehous_default_accnt_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_shipping_commission\",\"columnshort\":\"warehous_shipping_commission\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_cntct_id\",\"columnshort\":\"warehous_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_addr_id\",\"columnshort\":\"warehous_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_transit\",\"columnshort\":\"warehous_transit\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_shipform_id\",\"columnshort\":\"warehous_shipform_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_shipvia_id\",\"columnshort\":\"warehous_shipvia_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_shipcomments\",\"columnshort\":\"warehous_shipcomments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_costcat_id\",\"columnshort\":\"warehous_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_sitetype_id\",\"columnshort\":\"warehous_sitetype_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_taxzone_id\",\"columnshort\":\"warehous_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"whsinfo\",\"column\":\"cohead_warehous_id_warehous_sequence\",\"columnshort\":\"warehous_sequence\",\"ctype\":\"int4\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Warehouse\",\"display\":\"cohead_warehous_id_warehous_descrip\"},{\"table\":\"cohead\",\"column\":\"cohead_shipto_id\",\"columnshort\":\"cohead_shipto_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"shipto_id\",\"deps\":[{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_cust_id\",\"columnshort\":\"shipto_cust_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_name\",\"columnshort\":\"shipto_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_salesrep_id\",\"columnshort\":\"shipto_salesrep_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_comments\",\"columnshort\":\"shipto_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_shipcomments\",\"columnshort\":\"shipto_shipcomments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_shipzone_id\",\"columnshort\":\"shipto_shipzone_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_shipvia\",\"columnshort\":\"shipto_shipvia\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_commission\",\"columnshort\":\"shipto_commission\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_shipform_id\",\"columnshort\":\"shipto_shipform_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_shipchrg_id\",\"columnshort\":\"shipto_shipchrg_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_active\",\"columnshort\":\"shipto_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_default\",\"columnshort\":\"shipto_default\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_num\",\"columnshort\":\"shipto_num\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_ediprofile_id\",\"columnshort\":\"shipto_ediprofile_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_cntct_id\",\"columnshort\":\"shipto_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_addr_id\",\"columnshort\":\"shipto_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_taxzone_id\",\"columnshort\":\"shipto_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to\",\"display\":\"cohead_shipto_id_shipto_name\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoname\",\"columnshort\":\"cohead_shiptoname\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to name\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoaddress1\",\"columnshort\":\"cohead_shiptoaddress1\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to address\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoaddress2\",\"columnshort\":\"cohead_shiptoaddress2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to address(2)\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoaddress3\",\"columnshort\":\"cohead_shiptoaddress3\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to address(3)\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoaddress4\",\"columnshort\":\"cohead_shiptoaddress4\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to address(4)\"},{\"table\":\"cohead\",\"column\":\"cohead_shiptoaddress5\",\"columnshort\":\"cohead_shiptoaddress5\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to address(5)\"},{\"table\":\"cohead\",\"column\":\"cohead_salesrep_id\",\"columnshort\":\"cohead_salesrep_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"salesrep_id\",\"deps\":[{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_active\",\"columnshort\":\"salesrep_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_number\",\"columnshort\":\"salesrep_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_commission\",\"columnshort\":\"salesrep_commission\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_method\",\"columnshort\":\"salesrep_method\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cohead_salesrep_id_salesrep_emp_id\",\"columnshort\":\"salesrep_emp_id\",\"ctype\":\"int4\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Staff I.C.\",\"display\":\"cohead_salesrep_id_salesrep_name\"},{\"table\":\"cohead\",\"column\":\"cohead_terms_id\",\"columnshort\":\"cohead_terms_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"terms_id\",\"deps\":[{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_code\",\"columnshort\":\"terms_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_type\",\"columnshort\":\"terms_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_duedays\",\"columnshort\":\"terms_duedays\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_discdays\",\"columnshort\":\"terms_discdays\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_discprcnt\",\"columnshort\":\"terms_discprcnt\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_cutoffday\",\"columnshort\":\"terms_cutoffday\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_ap\",\"columnshort\":\"terms_ap\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_ar\",\"columnshort\":\"terms_ar\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\",\"display\":\"cohead_terms_id_terms_descrip\"},{\"table\":\"cohead\",\"column\":\"cohead_ordercomments\",\"columnshort\":\"cohead_ordercomments\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order Comments\"},{\"table\":\"cohead\",\"column\":\"cohead_shipcomments\",\"columnshort\":\"cohead_shipcomments\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Shipment Comments\"},{\"table\":\"cohead\",\"column\":\"cohead_curr_id\",\"columnshort\":\"cohead_curr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"curr_id\",\"deps\":[{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_base\",\"columnshort\":\"curr_base\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_symbol\",\"columnshort\":\"curr_symbol\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_abbr\",\"columnshort\":\"curr_abbr\",\"ctype\":\"varchar\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Currency\",\"display\":\"cohead_curr_id_curr_symbol\"},{\"table\":\"cohead\",\"column\":\"cohead_shipto_cntct_id\",\"columnshort\":\"cohead_shipto_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"cntct_id\",\"deps\":[{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_crmacct_id\",\"columnshort\":\"cntct_crmacct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_addr_id\",\"columnshort\":\"cntct_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_first_name\",\"columnshort\":\"cntct_first_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_last_name\",\"columnshort\":\"cntct_last_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_honorific\",\"columnshort\":\"cntct_honorific\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_initials\",\"columnshort\":\"cntct_initials\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_active\",\"columnshort\":\"cntct_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_fax\",\"columnshort\":\"cntct_fax\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_email\",\"columnshort\":\"cntct_email\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_webaddr\",\"columnshort\":\"cntct_webaddr\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_notes\",\"columnshort\":\"cntct_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_title\",\"columnshort\":\"cntct_title\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_number\",\"columnshort\":\"cntct_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_middle\",\"columnshort\":\"cntct_middle\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_suffix\",\"columnshort\":\"cntct_suffix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_owner_username\",\"columnshort\":\"cntct_owner_username\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_shipto_cntct_id_cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to Contact\",\"display\":\"cohead_shipto_cntct_id_cntct_name\"},{\"table\":\"cohead\",\"column\":\"cohead_billto_cntct_id\",\"columnshort\":\"cohead_billto_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"cntct_id\",\"deps\":[{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_crmacct_id\",\"columnshort\":\"cntct_crmacct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_addr_id\",\"columnshort\":\"cntct_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_first_name\",\"columnshort\":\"cntct_first_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_last_name\",\"columnshort\":\"cntct_last_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_honorific\",\"columnshort\":\"cntct_honorific\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_initials\",\"columnshort\":\"cntct_initials\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_active\",\"columnshort\":\"cntct_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_fax\",\"columnshort\":\"cntct_fax\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_email\",\"columnshort\":\"cntct_email\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_webaddr\",\"columnshort\":\"cntct_webaddr\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_notes\",\"columnshort\":\"cntct_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_title\",\"columnshort\":\"cntct_title\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_number\",\"columnshort\":\"cntct_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_middle\",\"columnshort\":\"cntct_middle\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_suffix\",\"columnshort\":\"cntct_suffix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_owner_username\",\"columnshort\":\"cntct_owner_username\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cohead_billto_cntct_id_cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Bill To (name)\",\"display\":\"cohead_billto_cntct_id_cntct_name\"},{\"table\":\"cohead\",\"column\":\"cohead_taxzone_id\",\"columnshort\":\"cohead_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"taxzone_id\",\"deps\":[{\"table\":\"taxzone\",\"column\":\"cohead_taxzone_id_taxzone_code\",\"columnshort\":\"taxzone_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"taxzone\",\"column\":\"cohead_taxzone_id_taxzone_descrip\",\"columnshort\":\"taxzone_descrip\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Tax Zone\",\"display\":\"cohead_taxzone_id_taxzone_descrip\"},{\"table\":\"cohead\",\"column\":\"cohead_taxtype_id\",\"columnshort\":\"cohead_taxtype_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"taxtype_id\",\"deps\":[{\"table\":\"taxtype\",\"column\":\"cohead_taxtype_id_taxtype_name\",\"columnshort\":\"taxtype_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"taxtype\",\"column\":\"cohead_taxtype_id_taxtype_descrip\",\"columnshort\":\"taxtype_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"taxtype\",\"column\":\"cohead_taxtype_id_taxtype_sys\",\"columnshort\":\"taxtype_sys\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Tax Type\",\"display\":\"cohead_taxtype_id_taxtype_descrip\"}],\"cols_ex\":[\"cohead_cust_id_cust_name\",\"cohead_warehous_id_warehous_descrip\",\"cohead_shipto_id_shipto_name\",\"cohead_salesrep_id_salesrep_name\",\"cohead_terms_id_terms_descrip\",\"cohead_curr_id_curr_symbol\",\"cohead_shipto_cntct_id_cntct_name\",\"cohead_billto_cntct_id_cntct_name\",\"cohead_taxzone_id_taxzone_descrip\",\"cohead_taxtype_id_taxtype_descrip\"],\"table\":\"cohead\",\"xtype\":\"LayoutDialog\",\"|xns\":\"Roo\"}",
+            "closable": true,
+            "collapsible": false,
+            "height": 450,
+            "modal": true,
+            "resizable": true,
+            "title": "Edit / Create Credit Memo",
+            "width": 950,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center",
+                    "alwaysShowTabs": true,
+                    "tabPosition": "top"
+                },
+                {
+                    "listeners": {
+                        "activate": "function (_self)\n{\n    // we need to reload to find out the subtotal.\n    if (!_this.data || !_this.data.cmhead_id) {\n        return;\n    }\n    \n    new Pman.Request({\n        method : 'GET',\n        url : baseURL + '/Roo/cmhead',\n        params : { \n            _id : _this.data.cmhead_id\n        },\n        success : function(res) {\n            // update the items and tax values...?\n            _this.form.findField('cmhead_value').setValue(res.data.cmhead_value);\n            _this.form.findField('cmhead_tax_value').setValue(res.data.cmhead_tax_value * 1);            \n            _this.form.findField('cmhead_taxable_value').setValue(res.data.cmhead_taxable_value * 1);  \n             _this.form.findField('cmhead_misc_per').update();\n            _this.form.findField('cmhead_total').recalc();\n        \n        }\n    });\n}"
+                    },
+                    "region": "center",
+                    "title": "Credit Details",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        _this.saveBtn.show();\n        \n        if (_this.data.cmhead_id) {\n           this.load({ method: 'GET', params: { '_id' : _this.data.cmhead_id }});\n           \n           return;\n        }\n        _this.dialog.setTitle(\"Add New Credit Memo\");\n       \n        _this.form.findField('cmhead_docdate').setValue(new Date());\n        \n       return;\n    }\n    if (action.type == 'load') {\n         \n        _this.data = action.result.data;\n        \n        if(_this.data.cmhead_posted){\n            _this.saveBtn.hide();\n        }\n        _this.dataloading = true;\n        if (_this.data.cmhead_shipto_cntct_id == _this.data.cmhead_billto_cntct_id) {\n            this.findField('_shipto_same').setValue(1);\n                      Roo.log('set shipto 1');\n        } else {\n//          this.findField('_shipto_same').setValue(0);\n                      Roo.log('set shipto 0');\n          }\n        _this.dataloading = false;          \n        \n        \n        this.findField('billto_address').update();\n//        this.findField('shipto_address').update();        \n        _this.dialog.setTitle(\"Edit Credit Memo Order - \" + this.findField('cmhead_number').getValue());\n        \n      _this.form.findField('cmhead_misc_per').update();\n        _this.form.findField('cmhead_total').recalc();\n        return;\n    }\n    if (action.type =='submit') {\n    \n\n        var id = _this.form.findField('cmhead_id').getValue() * 1;\n        if (id < 1) {\n\n            _this.data.cmhead_id = action.result.data.cmhead_id;\n             this.load({ method: 'GET', params: { '_id' : _this.data.cmhead_id }});\n            return;\n        }\n    \n        _this.dialog.hide();\n        \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n",
+                                "actionfailed": "function (_self, action)\n{\n    if (action.failureType == 'client') {\n        Roo.MessageBox.alert(\"Error\", \"Fill in all the required fields\");\n    }\n    if (action.failureType == 'server') {    \n        Roo.log(action);\n        Roo.MessageBox.alert(\"Error\", action.result.errorMsg);\n    }\n    _this.dialog.layout.getRegion('center').showPanel(0);\n}"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cmhead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "width": "435",
+                                    "items": [
+                                        {
+                                            "labelWidth": 120,
+                                            "legend": "Credit",
+                                            "style": "width:420px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelWidth": 100,
+                                                    "width": 410,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": true,
+                                                            "emptyText": "Automatic",
+                                                            "fieldLabel": "Ref #",
+                                                            "name": "cmhead_number",
+                                                            "readOnly": true,
+                                                            "width": 150,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "editable": false,
+                                                            "fieldLabel": "Customer",
+                                                            "name": "cmhead_cust_id_cust_name",
+                                                            "readOnly": true,
+                                                            "width": 300,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "location_name",
+                                                            "editable": true,
+                                                            "emptyText": "select location",
+                                                            "fieldLabel": "Return stock to",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cmhead_location_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cmhead_location_id_location_name",
+                                                            "pageSize": 200,
+                                                            "qtip": "Select terms",
+                                                            "queryParam": "query[location_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> {location_descrip}</div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "location_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n     o.params._notinternalcompany = 1;\n     o.params.location_restrict = 0;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "location_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{'name':'location_id','type':'int'},'location_name']",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Date",
+                                                            "format": "Y-m-d",
+                                                            "name": "cmhead_docdate",
+                                                            "width": 100,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "displayField": "salesrep_name",
+                                                            "editable": false,
+                                                            "emptyText": "Select salesrep",
+                                                            "fieldLabel": "Staff I.C.",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cmhead_salesrep_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cmhead_salesrep_id_salesrep_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select salesrep",
+                                                            "queryParam": "query[salesrep_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "salesrep_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'salesrep_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/salesrep.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "salesrep_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{'name':'salesrep_id','type':'int'},'salesrep_name']",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Comments",
+                                                            "height": 80,
+                                                            "name": "cmhead_comments",
+                                                            "width": 300,
+                                                            "xtype": "TextArea",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "style": "margin-left:10px",
+                                    "width": 450,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "legend": "Price Details",
+                                            "style": "width:420px",
+                                            "labelWidth": "50",
+                                            "items": [
+                                                {
+                                                    "labelAlign": "right",
+                                                    "labelWidth": 300,
+                                                    "width": 420,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "labelAlign": "right",
+                                                            "labelWidth": 300,
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Items Value",
+                                                                    "name": "cmhead_value",
+                                                                    "readOnly": true,
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowBlank": false,
+                                                                    "displayField": "curr_name",
+                                                                    "editable": false,
+                                                                    "emptyText": "Select Currency",
+                                                                    "fieldLabel": "Currency",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "cmhead_curr_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "cmhead_curr_id_curr_name",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select Currency",
+                                                                    "queryParam": "query[curr_name]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "curr_id",
+                                                                    "width": 285,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "method": "GET",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "curr_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[{'name':'curr_id','type':'int'},'curr_symbol']",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "keyup": "function (_self, e)\n{\n    _this.form.findField('cmhead_total').recalc();\n}"
+                                                                    },
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Freight",
+                                                                    "name": "cmhead_freight",
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Discount Description",
+                                                                    "name": "cmhead_misc_descrip",
+                                                                    "width": 230,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "keyup": "function (_self, e)\n{\n    var m = _this.form.findField('cmhead_misc');\n    var pv =  _this.form.findField('cmhead_value').getValue();\n    var n = this.getValue();\n    var discount = parseInt(n * pv * 0.01);\n    m.setValue(discount * -1.000);\n     \n    \n    _this.form.findField('cmhead_total').recalc();\n    var val = discount * -1.0;\n     if (val > 0) {\n        _this.form.findField('cohead_misc_descrip').setValue(\"Discount of \" + val.toFixed(1)+'%');\n    }\n}"
+                                                                    },
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 1,
+                                                                    "fieldLabel": "%",
+                                                                    "name": "cmhead_misc_per",
+                                                                    "width": 35,
+                                                                    "xtype": "NumberField",
+                                                                    "|update": "function() {\n    var m = _this.form.findField('cmhead_misc_per');\n    var pv =  parseFloat(_this.form.findField('cmhead_value').getValue());\n    var discount = parseFloat(_this.form.findField('cmhead_misc').getValue());\n    \n    if (discount > 0.0) {\n        this.setValue(0);        \n        return;\n    }\n    if (pv < 0) {\n        this.setValue(0);        \n        return;\n    }\n    var val = ((discount) / pv) * -100;\n    \n    //Roo.log(\"update discount?\" + val);\n    this.setValue(val.toFixed(1));\n    \n     if (val > 0.0) {\n        _this.form.findField('cmhead_misc_descrip').setValue(\"Discount of \" + val.toFixed(1)+'%');\n    \n    }\n    \n   \n}\n",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "keyup": "function (_self, e)\n{\n   _this.form.findField('cmhead_misc_per').update();\n    _this.form.findField('cmhead_total').recalc();\n}"
+                                                                    },
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "&nbsp;",
+                                                                    "name": "cmhead_misc",
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "select": "function (combo, record, index)\n{\n    _this.form.findField('cmhead_tax_value').setValue(\n        record.data.taxzone_rate * _this.form.findField('cmhead_taxable_value').getValue()\n    );\n}"
+                                                                    },
+                                                                    "allowBlank": false,
+                                                                    "displayField": "taxzone_descrip",
+                                                                    "editable": false,
+                                                                    "emptyText": "Select tax zone",
+                                                                    "fieldLabel": "Tax Zone",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "cmhead_taxzone_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "cmhead_taxzone_id_taxzone_descrip",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select tax zone",
+                                                                    "queryParam": "query[taxzone_descrip]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxzone_descrip}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "taxzone_id",
+                                                                    "width": 285,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    \n    o.params.with_date = _this.form.findField('cmhead_docdate').getValue().format('Y-m-d');\n    Roo.log(\"with date?\" + o.params.with_date);\n    \n    \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'taxzone_descrip' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/taxzone.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "taxzone_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[{'name':'taxzone_id','type':'int'},'taxzone_descrip']",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Tax",
+                                                                    "name": "cmhead_tax_value",
+                                                                    "readOnly": true,
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "right",
+                                                            "labelWidth": 300,
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Total",
+                                                                    "name": "cmhead_total",
+                                                                    "readOnly": true,
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|recalc": "function() {\n    var vals = _this.form.getValues();\n    this.setValue(\n        (1*vals.cmhead_value) + (1*vals.cmhead_freight) + (1*vals.cmhead_tax_value) + (1*vals.cmhead_misc)\n    );\n}\n",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "legend": "Billing",
+                                            "style": "width:420px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "width": "420",
+                                                    "labelWidth": "50",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeselect": "function (combo, record, index)\n{\n    // set _this.data values ..\n    \n    // just add everything...\n    for(var i in record.data) {\n      //  Roo.log('cmhead_billto_cntct_id_' + i +' ='  + record.data[i]);\n        _this.data['cmhead_billto_cntct_id_' + i] = record.data[i];\n    }\n\n    _this.form.findField('billto_address').update();\n    \n \n}",
+                                                                "add": "function (combo)\n{\n  \n  Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cmhead_cust_id').getValue()\n            },\n            \n            function (data) {\n               \n                for(var i in  data) {\n                    \n                    _this.data['cmhead_billto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('billto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cmhead_billto_cntct_id : data.cntct_id,\n                    cmhead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                    \n                });\n            }\n        );\n        //  Pman.Dialog.XtupleCustomer.show(\n            //{ cust_id : _this.form.findField('cohead_cust_id').getValue() }, \n            //function(data) {\n        // refresh the data in the pulldown..\n    //    }); \n\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "cntct_name",
+                                                            "editable": true,
+                                                            "emptyText": "Select Contact",
+                                                            "fieldLabel": "Bill To (select)",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cmhead_billto_cntct_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cmhead_billto_cntct_id_cntct_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select Contact",
+                                                            "queryParam": "query[cntct_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cntct_name}</b> {cntct_addr_id_addr_line1}</div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "cntct_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params._customer_id = _this.data.cmhead_cust_id;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'cntct_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/cntct.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "cntct_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{'name':'cntct_id','type':'int'},'cntct_name']",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n   Roo.log(this.el)\n   \n   \n   \n   this.el.on('click', function() { \n       var id = _this.form.findField('cmhead_billto_cntct_id').getValue();\n        Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cmhead_cust_id').getValue()\n            },\n            \n            function (data) {\n            \n                for(var i in  data) {\n                    \n                    _this.data['cmhead_billto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('billto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cmhead_billto_cntct_id : data.cntct_id,\n                    cmhead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                });\n            }\n        );\n     });\n}"
+                                                            },
+                                                            "fieldLabel": "or enter Address",
+                                                            "name": "billto_address",
+                                                            "readOnly": true,
+                                                            "xtype": "TextArea",
+                                                            "|update": "function() {\n\n    var c = ['first_name', 'last_name' ] ;\n    var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];\n    var v = [];\n    Roo.each(c, function(e) {\n        if (_this.data['cmhead_billto_cntct_id_cntct_' +e] &&\n            _this.data['cmhead_billto_cntct_id_cntct_' +e].length) {\n            v.push(_this.data['cmhead_billto_cntct_id_cntct_' +e]);\n        }\n    });\n    Roo.each(a, function(e) {\n        if (_this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e] &&\n            _this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e].length) {\n            v.push(_this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e]);\n        }\n    });\n    this.setValue(v.join(\"\\n\"));\n}\n",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "cmhead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cmhead_billto_addr_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cmhead_taxable_value",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cmhead_posted",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cmhead_cust_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "taxzone_rate",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "has_item",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "deactivate": "function (_self)\n{\n    if(_this.grid){\n        _this.grid.stopEditing();\n    }\n}",
+                        "activate": "function (_self)\n{\n\n    _this.panel = this;\n    \n    try { if (MODULE.isBuilder) {\n        return;\n    } } catch(e) { }\n    \n    var id = _this.form.findField('cmhead_id').getValue() * 1;\n    if (id < 1) {\n        Roo.MessageBox.alert(\"Save First\", \"Save the order first, before adding items\");\n        _this.dialog.layout.getRegion('center').showPanel(0);\n        return;\n    }\n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "coitem",
+                    "title": "Credit Items",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    _this.hasQuery = 0;\n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                "afteredit": "function (e)\n{\n    //Roo.log('afteredit');\n    //Roo.log(e);\n    \n    if (e.field == 'item_number' || e.originalValue == e.value) {\n        // afterselect handles this...\n        return;\n    }\n    var r = e.record;\n    \n    if ( r && r.data.cmitem_id) {\n        // as we disable update to the display on the ajax callback to \n        // allow editing flow to continue, and not refresh - we can only update\n        // these values after something has actually been edited.\n         r.set('coitem_id', r.data.cmitem_id);\n    }\n    \n    var rate = 0;\n    if(r.data.cmitem_taxtype_id_taxtype_name == 'Taxable' ){\n        rate = _this.form.findField('taxzone_rate').getValue();\n    }\n    if(e.field == 'cmitem_tax_unitprice'){\n        r.set('cmitem_unitprice', r.data.cmitem_tax_unitprice * 1 / (1 + rate * 1));\n//        fields.push('cmitem_unitprice');\n    }\n    if(e.field == 'cmitem_unitprice'){\n        r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1) );\n//        fields.push('cmitem_tax_unitprice');\n    }\n    if(e.field == 'cmitem_taxtype_id'){\n        r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1) );\n//        fields.push('cmitem_tax_unitprice');\n                \n    }\n    r.set('cmitem_tax_listprice', r.data.cmitem_item_listprice * (1 + rate * 1) );\n//    fields.push('cmitem_tax_listprice');\n    r.set('cmitem_line_value', r.data.cmitem_qtycredit * r.data.cmitem_unitprice );\n//    fields.push('cmitem_line_value');\n    r.set('cmitem_line_tax_value', r.data.cmitem_qtycredit * r.data.cmitem_tax_unitprice );\n//    fields.push('cmitem_line_tax_value'); \n    \n//    fields.push('cmitem_id');\n    \n    _this.hasQuery += 1;\n    \n     var doupdate = function() { \n       if (!_this.itemsUpdating) {\n            Roo.log('doupdate...');\n            \n            _this.hasQuery -= 1;\n            r.commit();\n            return;\n        }\n        doupdate.defer(1000);\n    }\n    \n    doupdate();\n    \n    \n}",
+                                "beforeedit": "function (e)\n{\n    // we can only edit if nothing is assigned to shipping or invoices..\n    if (_this.form.findField('cmhead_posted').getValue() == 'true') {\n        Roo.MessageBox.alert(\"Error\", \"credit memo is already posted\");\n        e.cancel = true;\n        return;\n    }\n    \n    return;\n    \n    // seems below logic is useless...!!!!\n    var rec = e.record;\n\n    if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {\n        Roo.MessageBox.alert(\"Error\", \"That item has been shipped or invoices - void the shipments/invoices first\");\n        e.cancel = true;\n        return;\n    }\n    \n    if (rec.data.coitem_subnumber * 1 > 0) {\n        Roo.log(\"Edit container event\");\n        Roo.log(e); // if it's a tab.. \n\n        \n        switch(e.field) {\n            // allow editing of source / destination..\n            case 'coitem_shipto_id':\n            case 'coitem_location_src':            \n                return;\n            default : \n                break;\n        }\n        Roo.MessageBox.alert(\"Error\", \"That is a kit item, edit the container.\");\n        e.cancel = true;\n        return;\n    }\n    // zero off values..\n    //if (e.field == 'coitem_qtyord' && rec.data.coitem_qtyord == 0) {\n    //        e.value ='';\n    //    }\n    //    if (e.field == 'coitem_custprice' && rec.data.coitem_qtyord == 0.0) {\n    //        e.value ='';\n    //    }\n    \n    if (rec.data.item_type == 'K' && e.field == 'item_number') {\n        // you can not change the product type on kits' as it messing things up..\n        Roo.MessageBox.alert(\"Error\", \"That is a kit item,if you need to change it, delete it first.\");\n        e.cancel = true;\n        return;\n    }\n    \n}",
+                                "celldblclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var rec = this.ds.getAt(rowIndex);\n    var di = this.cm.getDataIndex(columnIndex);\n    if (di != 'avail_qty') {\n        return;\n    }\n    Pman.Dialog.XtupleInvHistory.show({\n        itemsite_item_id_item_number   : rec.data.item_number,\n       // itemsite_item_id_item_descript1 : rec.data.item_descrip1,\n        location_name : rec.data.coitem_location_src_location_name,\n        location_descrip : rec.data.coitem_location_src_location_descrip,\n        \n        invhist_transdate : _this.form.findField('cohead_targetdate').getValue() \n    }); \n    \n}",
+                                "rowclass": "function (gridview, rowcfg)\n{\n    if (rowcfg.record.data.coitem_status == 'C' &&\n        rowcfg.record.data.shipitem_shipped * 1 < 1) {\n        \n        rowcfg.rowClass = 'strikethrough';\n    }\n     if (rowcfg.record.data.coitem_status == 'X'  ) {\n        \n        rowcfg.rowClass = 'strikethrough';\n    }\n   // Roo.log(rowcfg);\n//    shipitem_shipped\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "cmitem_comments",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|loadAvail": "function() {\n    \n    return; //not used.\n       \n     var q = [];\n    this.ds.each(  function(r) {\n    \n        // only update if we do not have the details.\n        if (r.data.avail_qty == 0) {\n        \n        }\n        q.push( { \n            item : r.data.item_number, \n            loc: r.data.coitem_location_src_location_name,\n            id: r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '')\n         } );\n    });\n    \n    // needs to be a post to allow long lists of products..\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/itemloc',\n        method : 'POST',\n        mask : \"Loading available qty\",\n        maskel : _this.grid.view.el,\n        params : {\n            _availqty : Roo.encode(q),\n            curr_id : _this.form.findField('cohead_curr_id').getValue()\n        },\n        success : function(d) \n        {\n            _this.grid.ds.each(function(r) { \n                 var id = r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '');\n            \n            \n                if (typeof(d.data[id]) == 'undefined') {\n                    return;\n                }\n                r.set('avail_qty', d.data[id].qty);\n                if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {\n                    r.set('coitem_unitcost_in_order_cur', d.data[id].unitcost);\n                }\n            \n            });\n        \n        }\n    });\n    \n        \n                \n}\n",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "tabend": "function (_self)\n{\n    _this.addItemBtn.fireEvent('click', _this.addItemBtn);\n}",
+                                        "beforeeditnext": "function (eventdata)\n{\n    return;\n    // this does not work, as the reload effect cancels editng.\n    var rec = _this.grid.ds.getAt(eventdata.cell[0]);\n    if (rec.data.coitem_subnumber *1 < 0 ) {\n        return;\n    }\n    var r = eventdata.cell[0] + 1;\n\n    while (true) {\n        if (r > _this.grid.ds.getCount()-1 ) {\n            eventdata.cell = false;\n            return;\n        }\n        rec =  _this.grid.ds.getAt(r);\n        if (rec.data.coitem_subnumber *1 < 0 ) {\n           eventdata.cell = [ r, eventdata.cell[1] ];\n           return;\n        }\n        r++;\n    }\n    \n    \n \n\n}"
+                                    },
+                                    "*prop": "sm",
+                                    "enter_is_tab": true,
+                                    "xtype": "CellSelectionModel",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "listeners": {
+                                        "|beforeload": "function (_self,o) {\n\n    try {\n       this.removeAll();\n   } catch (e) { }\n   \n    Roo.log(_this.data);\n    if (!_this.data || !_this.data.cmhead_id) {\n        return false;\n    }\n    o.params = o.params || {};\n    Roo.log(_this.data);\n    o.params.cmitem_cmhead_id = _this.data.cmhead_id;\n    o.params.limit = 999;\n    \n}",
+                                        "update": "function (_self, rec, operation)\n{\n   \n   if (operation !=  Roo.data.Record.COMMIT) {\n       return;\n   }\n   \n   // row has been updated..\n   // if the qty + item has been filled in, we should try and save it..\n    if (!(rec.data.cmitem_itemsite_id * 1) || !(rec.data.cmitem_qtycredit*1) || !(rec.data.cmitem_unitprice*1)) {\n        Roo.log('not saving - row not completed');\n        return;\n    }\n\n    if (_this.itemsUpdating) {\n        Roo.log('currently updating?');\n        return;\n    }\n    _this.itemsUpdating = true;\n\n\n    Roo.log('Running update');   \n    \n    new Pman.Request({\n        url : baseURL+'/Roo/Cmitem',\n        method : 'POST',\n        \n        params : rec.data,\n        success: function(res)\n        {\n            Roo.log('GOT success');\n            // update the data...\n            if (rec.data.item_type == 'K') {\n                 _this.itemsUpdating = false; \n                _this.grid.ds.load({});\n                return;\n            }\n            if (_this.grid.activeEditor) {\n                 rec.editing = true;\n             } \n            rec.set('cmitem_id', res.data.cmitem_id);\n            \n            _this.itemsUpdating = false; \n            \n            if(_this.hasQuery != 0){\n                 \n                return;\n            }\n            \n            rec.dirty = false;\n            delete rec.modified;\n            \n            _this.grid.loadAvail();\n            \n        },\n        failure : function(res)\n        {\n            Roo.MessageBox.alert(res.message);\n            _this.itemsUpdating = false;\n        }\n        \n        \n    });\n    \n    \n   \n   \n   \n}",
+                                        "load": "function (_self, records, options)\n{\n    // need to fetch availablity from master data..\n    // build a list of what to ask..\n    Roo.log(records);\n    // query: ITEM CODE - LOCATION\n    \n    //_this.grid.loadAvail.defer(100, _this.grid);\n    var rate = 0;\n        \n    Roo.each(records, function(r){\n        rate = 0;\n        if(r.data.cmitem_taxtype_id == r.data.cmitem_taxable_id ){\n            rate = _this.form.findField('taxzone_rate').getValue();\n        }\n        r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1));\n        r.set('cmitem_tax_listprice', r.data.cmitem_item_listprice * (1 + rate * 1));\n        r.set('cmitem_line_tax_value', r.data.cmitem_line_value * (1 + rate * 1));\n    })    \n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'cmitem_linenumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/Cmitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'coitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyord'\n    },\n    {\n        'name': 'coitem_unitcost'\n    },\n    {\n        'name': 'coitem_price'\n    },\n    {\n        'name': 'coitem_custprice'\n    },\n    {\n        'name': 'coitem_qtyreturned'\n    },\n    {\n        'name': 'coitem_prcost'\n    },\n    {\n        'name': 'coitem_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyreserved'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n    \n    \n    if (_this.form.findField('cmhead_posted').getValue() == 'true') {\n        Roo.MessageBox.alert(\"Error\", \"credit memo is already posted\");\n        return;\n    }\n    // work out last \n       // work out last \n                var grid = _this.grid;\n                var last = 0;\n                \n                _this.grid.ds.each(function(r) {\n                    last = r.data.cmitem_linenumber;\n                });\n                \n                last++;\n                grid.stopEditing();\n                var nr = _this.grid.ds.reader.newRow({\n                    cmitem_linenumber : last,\n                    item_number : '',\n                    item_descrip1 : '',\n                    cmitem_cmhead_id : _this.form.findField('cmhead_id').getValue(),\n                    cmitem_comments : '',\n                    cmitem_taxtype_id : _this.data.default_taxtype_id,\n                    cmitem_taxtype_id_taxtype_name : 'Taxable'\n                });\n                grid.stopEditing();\n                grid.ds.insert(grid.ds.getCount(), nr); \n                grid.startEditing(grid.ds.getCount()-1, 1); // type..\n}\n",
+                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Add",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    \n    var last = 1;    \n    _this.grid.ds.each(function(r) {\n        last = r.data.cmitem_linenumber +1;\n\n    \n    });\n    \n    var grid = _this.grid;\n    var ct  =    _this.grid.ds.getCount();\r\n    var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;\r\n         \r\n    var cmhead_cust_id = _this.form.findField('cmhead_cust_id').getValue();\n    var cmhead_id = _this.form.findField('cmhead_id').getValue();\n    \n    Pman.Dialog.XtupleSalesProductList.show( {cohead_cust_id : cmhead_cust_id, cmhead_id : cmhead_id} , function(res) {\n    \n        Roo.log(res);\n        grid.stopEditing();\n\n        if (lastrow) {\n            var lr = lastrow;\n            if (!lr.data.cmitem_itemsite_id) {\n                lr.set('cmitem_itemsite_id', res.item_itemsite_id_itemsite_id);\n                lr.set('item_number',  res.item_number);\n                lr.set('item_descrip1', res.item_descrip1);                                \n                lr.set('cmitem_comments', res.item_descrip1);\n                lr.set('cmitem_cmhead_id', _this.form.findField('cmhead_id').getValue());\n                return;\n            }\n        }\n        var rate = _this.form.findField('taxzone_rate').getValue();\r\n         var nr = grid.ds.reader.newRow({\n                    cmitem_linenumber : last,\n                    cmitem_itemsite_id : res.item_itemsite_id_itemsite_id,\n                    item_number :  res.item_number,\n                    item_descrip1 : res.item_descrip1 ,\n                    cmitem_cmhead_id : _this.form.findField('cmhead_id').getValue(),\n                    cmitem_comments : res.item_descrip1,\n                    cmitem_tax_listprice : res.item_price * ( 1 + rate * 1),\n                    cmitem_item_listprice : res.item_price,\n                    cmitem_tax_unitprice : res.item_price * ( 1 + rate * 1),\n                    cmitem_unitprice : res.item_price,\n                    cmitem_qtycredit : 1,\n                    cmitem_line_value : res.item_price,\n                    cmitem_line_tax_value : res.item_price * ( 1 + rate * 1)\n                    \n                });\n        grid.ds.insert(grid.ds.getCount(), nr);\n        \n        var ar = grid.ds.getAt(grid.ds.getCount() - 1);\n        ar.commit();\n        \n   }); \n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Find Products",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function ()\n{\n    var cmhead_id = 1 * _this.form.findField('cmhead_id').getValue();\n    if (!cmhead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Save credit memo first!\");\n        return;\n    \n    }\n    \n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 600000,\n        params : {\n            _group : 'cmhead',\n            _name : 'items',\n            'cmhead_id:number' : cmhead_id,\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });   \n            \n   \n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Download Excel",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function (_self, e)\n{\n   \n    if (_this.form.findField('cmhead_posted').getValue() == 'true') {\n        Roo.MessageBox.alert(\"Error\", \"credit memo is already posted\");\n        return;\n    }\n   \n    Pman.Dialog.Image.show(\n       {\n            _url : baseURL + '/Xtuple/Import/CreditMemo',\n            onid : _this.form.findField('cmhead_id').getValue()\n        \n       },\n       function (res) {\n            _this.grid.ds.load({});\r\n       }\n   );\n}",
+                                                "render": "function (_self)\n{\n    _this.uploadBtn = _self;\n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Upload Excel",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "xtype": "Fill",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     _this.grid.stopEditing();\n    // check that no shipments or invoices are done..\n if (_this.form.findField('cmhead_posted').getValue() == 'true') {\n        Roo.MessageBox.alert(\"Error\", \"credit memo is already posted\");\n        return;\n    }\n                                            // check that no shipments or invoices are done..\n    var rc = _this.grid.getSelectionModel().getSelectedCell();\n    \n    var rec = _this.grid.ds.getAt(rc[0]);\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to delete that line?\", function(r)\n    {\n        if (r != 'yes') {\n            return;\n        }\n        remove();\n    });\n    \n    if (!rec.data.cmitem_id) {\n        _this.grid.ds.remove(rec);\n        return;\n    }\n    function remove()\n    {\n        new  Pman.Request({\n            url : baseURL + '/Roo/cmitem',\n            method : 'POST',\n            params : {\n                _delete : rec.data.cmitem_id\n            \n            },\n            success : function() {\n                if (rec.data.item_type == 'K') {\n                    _this.grid.ds.load({});\n                    return;\n                }\n                _this.grid.ds.remove(rec);\n            }\n        \n        });\n    }\n\n    \n    \n}\n        "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Delete",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"}",
+                                    "dataIndex": "cmitem_linenumber",
+                                    "header": "Item#",
+                                    "width": 60,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n\n    if (r.data.coitem_subnumber * 1 > 0) {\n         return String.format('{0}.{1}', v,r.data.coitem_subnumber);\n     }\n     return String.format('{0}', v);\n  }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item Code",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n  // set _this.data values ..\n  var ar = _this.grid.activeEditor.record;\n  //Roo.log('beforeselect');\n  \n  var rate = _this.form.findField('taxzone_rate').getValue();\n  \n  (function() { \n    \n    ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);\n    ar.set('cmitem_comments', record.data.itemsite_item_id_item_descrip1);        \n    ar.set('cmitem_tax_listprice', record.data.item_listprice * ( 1 + rate * 1) );\n    ar.set('cmitem_item_listprice', record.data.item_listprice * 1);\n    ar.set('cmitem_tax_unitprice', record.data.item_price * ( 1 + rate * 1) );\n    ar.set('cmitem_unitprice', record.data.item_price * 1);\n    ar.set('cmitem_qtycredit', 1);\n    ar.set('cmitem_line_value', record.data.item_price * ar.data.cmitem_qtycredit);\n    ar.set('cmitem_line_tax_value', ar.data.cmitem_tax_unitprice * ar.data.cmitem_qtycredit);\n    ar.set('cmitem_itemsite_id', record.data.itemsite_id);\n    ar.set('item_number', record.data.itemsite_item_id_item_number);\n    ar.set('item_type', record.data.itemsite_item_id_item_type);\n    ar.set('avail_qty', 0);\n  //  ar.updateFields = ['All'];\n    ar.commit();\n  }).defer(100);\n  \n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "itemsite_item_id_item_number",
+                                                    "editable": true,
+                                                    "emptyText": "Select item",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "itemsite_item_id_item_number",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "item_number",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select item",
+                                                    "queryParam": "query[number]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> ${item_price:toFixed(2)}- {itemsite_item_id_item_descrip1} </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": false,
+                                                    "valueField": "item_number",
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.customer_id = _this.form.findField('cmhead_cust_id').getValue();\n    o.params['query[cmhead_id]'] = _this.form.findField('cmhead_id').getValue();\n    //o.params.shipto_cust_id = _this.data.cohead_cust_id;\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'item_number' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "shipto_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{'name':'item_id','type':'int'},'item_number']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cmitem_comments",
+                                    "header": "Item Description",
+                                    "width": "150.00",
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    if (!v.length) {\n        r.set('cmitem_comments', r.data.item_descrip1);\n        v = r.data.item_descrip1;\n    }\n    if (v && v.length > 49) {\n        return String.format('<span style=\"color:orange\" qtip=\"line may be too long to print\">{0}</span>', v);\n    }\n    return String.format('{0}', v); \n        \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_qtycredit",
+                                    "header": "Qty",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v)\n{\n    return String.format('{0}', v ? parseInt(v) : '');\n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "editor",
+                                            "xtype": "GridEditor",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowDecimals": false,
+                                                    "decimalPrecision": 0,
+                                                    "minValue": 1,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"}",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_tax_listprice",
+                                    "header": "List Price w. tax",
+                                    "width": 80,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r)\n{\n //   var rate = _this.form.findField('taxzone_rate').getValue();\n //   v = v * (1 + rate * 1);\n \n    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');\n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_taxtype_id",
+                                    "header": "Taxed",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}', r.data.cmitem_taxtype_id_taxtype_name); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "taxtype_name",
+                                                    "editable": false,
+                                                    "emptyText": "Select Tax Type",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "cmitem_taxtype_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "cmitem_taxtype_id_taxtype_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select taxtype",
+                                                    "queryParam": "query[taxtype_id]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxtype_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "taxtype_id",
+                                                    "width": 285,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    \n/*    o.params.with_date = _this.form.findField('cohead_orderdate').getValue().format('Y-m-d'); \n    Roo.log(\"with date?\" + o.params.with_date);*/\n    \n    \n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'taxtype_name' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/taxtype.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "taxtype_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{'name':'taxtype_id','type':'int'},'taxtype_name']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_tax_unitprice",
+                                    "header": "Unit Price w. tax",
+                                    "width": 90,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r)\n{\n    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');\n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 2,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_unitprice",
+                                    "header": "Unit Price",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v)\n{\n    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');\n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 2,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_line_value",
+                                    "header": "Total",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v)\n{\n    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');\n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cmitem_line_tax_value",
+                                    "header": "Total w. tax",
+                                    "width": 80,
+                                    "|renderer": "function(v,x,r)\n{\n    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');\n}",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.cpanel = this;\n    \n    var id = _this.form.findField('cmhead_id').getValue() * 1;\n    if (id < 1) {\n        Roo.MessageBox.alert(\"Error\", \"save the credit memo first!\");\n        _this.dialog.layout.getRegion('center').showPanel(0);\n        return;\n    }\n    \n    if (_this.cgrid) {\n        _this.cgrid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "checkitem",
+                    "title": "Miscellaneous Check",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.cgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.cpanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "checkitem_checkhead_id_checkhead_notes",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, options)\n{\n    options.params = options.params || {};\n    options.params.checkitem_cmnumber = _this.form.findField('cmhead_number').getValue();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'checkitem_id', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/checkitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying check item{0} - {1} of {2}",
+                                    "emptyMsg": "No check item found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "checkitem_docdate",
+                                    "header": "Date",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "checkitem_bankaccnt_id_bankaccnt_name",
+                                    "header": "Bank Account",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "checkitem_checkhead_id_checkhead_for",
+                                    "header": "Memo",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "checkitem_checkhead_id_checkhead_notes",
+                                    "header": "Notes",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "checkitem_curr_id_curr_name",
+                                    "header": "Currency",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "checkitem_amount",
+                                    "header": "Amount",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? parseFloat(v).toFixed(2) : ''); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.apanel = this;\n    if (_this.agrid) {\n        _this.agrid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "invchead",
+                    "title": "Applications",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.agrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.apanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "arapply_target_docnumber",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self,o) {\n\n    try {\n       this.removeAll();\n    } catch (e) { }\n\n    if (!_this.data || !_this.data.cmhead_id) {\n        return false;\n    }\n    o.params = o.params || {};\n    \n    o.params._application = _this.data.cmhead_id\n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'arapply_id', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/Arapply.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying application{0} - {1} of {2}",
+                                    "emptyMsg": "No application found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_id",
+                                    "header": "ID",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_distdate",
+                                    "header": "Date",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_target_doctype",
+                                    "header": "Target Doctype",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_target_docnumber",
+                                    "header": "Target Docnumber",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_curr_id_curr_name",
+                                    "header": "Currency",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "arapply_applied",
+                                    "header": "Applied",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.hpanel = this;\n    if (_this.hgrid) {\n        _this.hgrid.footer.onClick('first');\n    }\n}"
+                    },
+                    ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "events",
+                    "title": "History",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.hgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.hpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "autoExpandColumn": "remarks",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, options)\n{\n    options.params._related_on_table = 'cmhead';\n    options.params._related_on_id = _this.form.findField('cmhead_id').getValue();\n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'event_when', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/events.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'event_when',\n        'type': 'date'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "xtype": "PagingToolbar",
+                                    "pageSize": 25,
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying events{0} - {1} of {2}",
+                                    "emptyMsg": "No events found",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "event_when",
+                                    "header": "Changed",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "action",
+                                    "header": "action",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "ipaddr",
+                                    "header": "IP address",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "person_id_name",
+                                    "header": "Who",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}",
+                                    "dataIndex": "remarks",
+                                    "header": "Notes",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n      if (_this.grid)  _this.grid.stopEditing();\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n  // do some checks?\n       if (_this.grid)  _this.grid.stopEditing();\n      if (_this.form.findField('cmhead_posted').getValue() == 'true') {\n          Roo.MessageBox.alert(\"Error\", \"credit memo is already posted\");\n          return;\n      }\n      var loose = false;\n      var ar = [];\n      if (_this.grid && _this.grid.ds) {\n          _this.grid.ds.each(function(rec) {\n              if (!(rec.data.cmitem_itemsite_id * 1) || !(rec.data.cmitem_qtycredit*1) || !(rec.data.cmitem_unitprice*1)) {\n                  loose = true;\n                  return true;\n              } \n              ar.push(rec);\n              \n          });\n          if (loose) {\n              Roo.MessageBox.alert(\"Error\", \"Some lines do not have product/qty/price set\");\n              return;\n          }    \n      }\n      if(ar.length){\n          _this.form.findField('has_item').setValue(ar.length);\n      } \n  \n      _this.form.doAction(\"submit\");\n}",
+                        "render": "function (_self)\n{\n_this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleCreditMemo.js b/Pman.Dialog.XtupleCreditMemo.js
new file mode 100644 (file)
index 0000000..7da305f
--- /dev/null
@@ -0,0 +1,2617 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleCreditMemo = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function () {
+                       this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : true,
+            collapsible : false,
+            height : 450,
+            modal : true,
+            resizable : true,
+            title : "Edit / Create Credit Memo",
+            width : 950,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function (_self)
+                        {
+                            // we need to reload to find out the subtotal.
+                            if (!_this.data || !_this.data.cmhead_id) {
+                                return;
+                            }
+                            
+                            new Pman.Request({
+                                method : 'GET',
+                                url : baseURL + '/Roo/cmhead',
+                                params : { 
+                                    _id : _this.data.cmhead_id
+                                },
+                                success : function(res) {
+                                    // update the items and tax values...?
+                                    _this.form.findField('cmhead_value').setValue(res.data.cmhead_value);
+                                    _this.form.findField('cmhead_tax_value').setValue(res.data.cmhead_tax_value * 1);            
+                                    _this.form.findField('cmhead_taxable_value').setValue(res.data.cmhead_taxable_value * 1);  
+                                     _this.form.findField('cmhead_misc_per').update();
+                                    _this.form.findField('cmhead_total').recalc();
+                                
+                                }
+                            });
+                        }
+                    },
+                    region : 'center',
+                    title : "Credit Details",
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        _this.saveBtn.show();
+                                        
+                                        if (_this.data.cmhead_id) {
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.cmhead_id }});
+                                           
+                                           return;
+                                        }
+                                        _this.dialog.setTitle("Add New Credit Memo");
+                                       
+                                        _this.form.findField('cmhead_docdate').setValue(new Date());
+                                        
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                         
+                                        _this.data = action.result.data;
+                                        
+                                        if(_this.data.cmhead_posted){
+                                            _this.saveBtn.hide();
+                                        }
+                                        _this.dataloading = true;
+                                        if (_this.data.cmhead_shipto_cntct_id == _this.data.cmhead_billto_cntct_id) {
+                                            this.findField('_shipto_same').setValue(1);
+                                                      Roo.log('set shipto 1');
+                                        } else {
+                                //          this.findField('_shipto_same').setValue(0);
+                                                      Roo.log('set shipto 0');
+                                          }
+                                        _this.dataloading = false;          
+                                        
+                                        
+                                        this.findField('billto_address').update();
+                                //        this.findField('shipto_address').update();        
+                                        _this.dialog.setTitle("Edit Credit Memo Order - " + this.findField('cmhead_number').getValue());
+                                        
+                                      _this.form.findField('cmhead_misc_per').update();
+                                        _this.form.findField('cmhead_total').recalc();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                
+                                        var id = _this.form.findField('cmhead_id').getValue() * 1;
+                                        if (id < 1) {
+                                
+                                            _this.data.cmhead_id = action.result.data.cmhead_id;
+                                             this.load({ method: 'GET', params: { '_id' : _this.data.cmhead_id }});
+                                            return;
+                                        }
+                                    
+                                        _this.dialog.hide();
+                                        
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                },
+                                actionfailed : function (_self, action)
+                                {
+                                    if (action.failureType == 'client') {
+                                        Roo.MessageBox.alert("Error", "Fill in all the required fields");
+                                    }
+                                    if (action.failureType == 'server') {    
+                                        Roo.log(action);
+                                        Roo.MessageBox.alert("Error", action.result.errorMsg);
+                                    }
+                                    _this.dialog.layout.getRegion('center').showPanel(0);
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/cmhead.php',
+                            items : [
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : '435',
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            labelWidth : 120,
+                                            legend : "Credit",
+                                            style : 'width:420px',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelWidth : 100,
+                                                    width : 410,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            allowBlank : true,
+                                                            emptyText : "Automatic",
+                                                            fieldLabel : 'Ref #',
+                                                            name : 'cmhead_number',
+                                                            readOnly : true,
+                                                            width : 150
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            editable : false,
+                                                            fieldLabel : 'Customer',
+                                                            name : 'cmhead_cust_id_cust_name',
+                                                            readOnly : true,
+                                                            width : 300
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            displayField : 'location_name',
+                                                            editable : true,
+                                                            emptyText : "select location",
+                                                            fieldLabel : 'Return stock to',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cmhead_location_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cmhead_location_id_location_name',
+                                                            pageSize : 200,
+                                                            qtip : "Select terms",
+                                                            queryParam : 'query[location_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> {location_descrip}</div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'location_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                         o.params.location_netable = 1;
+                                                                         o.params._notinternalcompany = 1;
+                                                                         o.params.location_restrict = 0;
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/location.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'location_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{'name':'location_id','type':'int'},'location_name']
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            fieldLabel : 'Date',
+                                                            format : 'Y-m-d',
+                                                            name : 'cmhead_docdate',
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            displayField : 'salesrep_name',
+                                                            editable : false,
+                                                            emptyText : "Select salesrep",
+                                                            fieldLabel : 'Staff I.C.',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cmhead_salesrep_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cmhead_salesrep_id_salesrep_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select salesrep",
+                                                            queryParam : 'query[salesrep_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'salesrep_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'salesrep_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/salesrep.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'salesrep_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{'name':'salesrep_id','type':'int'},'salesrep_name']
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Comments',
+                                                            height : 80,
+                                                            name : 'cmhead_comments',
+                                                            width : 300
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    style : 'margin-left:10px',
+                                    width : 450,
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Price Details",
+                                            style : 'width:420px',
+                                            labelWidth : '50',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'right',
+                                                    labelWidth : 300,
+                                                    width : 420,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'right',
+                                                            labelWidth : 300,
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Items Value',
+                                                                    name : 'cmhead_value',
+                                                                    readOnly : true,
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'ComboBox',
+                                                                    xns: Roo.form,
+                                                                    allowBlank : false,
+                                                                    displayField : 'curr_name',
+                                                                    editable : false,
+                                                                    emptyText : "Select Currency",
+                                                                    fieldLabel : 'Currency',
+                                                                    forceSelection : true,
+                                                                    hiddenName : 'cmhead_curr_id',
+                                                                    listWidth : 400,
+                                                                    loadingText : "Searching...",
+                                                                    minChars : 2,
+                                                                    name : 'cmhead_curr_id_curr_name',
+                                                                    pageSize : 20,
+                                                                    qtip : "Select Currency",
+                                                                    queryParam : 'query[curr_name]',
+                                                                    selectOnFocus : true,
+                                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                                                    triggerAction : 'all',
+                                                                    typeAhead : true,
+                                                                    valueField : 'curr_id',
+                                                                    width : 285,
+                                                                    store : {
+                                                                        xtype: 'Store',
+                                                                        xns: Roo.data,
+                                                                        listeners : {
+                                                                            beforeload : function (_self, o){
+                                                                                o.params = o.params || {};
+                                                                                // set more here
+                                                                               
+                                                                            }
+                                                                        },
+                                                                        remoteSort : true,
+                                                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                                                        proxy : {
+                                                                            xtype: 'HttpProxy',
+                                                                            xns: Roo.data,
+                                                                            method : 'GET',
+                                                                            url : baseURL + '/Roo/curr_symbol.php'
+                                                                        },
+                                                                        reader : {
+                                                                            xtype: 'JsonReader',
+                                                                            xns: Roo.data,
+                                                                            id : 'curr_id',
+                                                                            root : 'data',
+                                                                            totalProperty : 'total',
+                                                                            fields : [{'name':'curr_id','type':'int'},'curr_symbol']
+                                                                        }
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        keyup : function (_self, e)
+                                                                        {
+                                                                            _this.form.findField('cmhead_total').recalc();
+                                                                        }
+                                                                    },
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Freight',
+                                                                    name : 'cmhead_freight',
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    fieldLabel : 'Discount Description',
+                                                                    name : 'cmhead_misc_descrip',
+                                                                    width : 230
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        keyup : function (_self, e)
+                                                                        {
+                                                                            var m = _this.form.findField('cmhead_misc');
+                                                                            var pv =  _this.form.findField('cmhead_value').getValue();
+                                                                            var n = this.getValue();
+                                                                            var discount = parseInt(n * pv * 0.01);
+                                                                            m.setValue(discount * -1.000);
+                                                                             
+                                                                            
+                                                                            _this.form.findField('cmhead_total').recalc();
+                                                                            var val = discount * -1.0;
+                                                                             if (val > 0) {
+                                                                                _this.form.findField('cohead_misc_descrip').setValue("Discount of " + val.toFixed(1)+'%');
+                                                                            }
+                                                                        }
+                                                                    },
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 1,
+                                                                    fieldLabel : '%',
+                                                                    name : 'cmhead_misc_per',
+                                                                    width : 35,
+                                                                    update : function() {
+                                                                        var m = _this.form.findField('cmhead_misc_per');
+                                                                        var pv =  parseFloat(_this.form.findField('cmhead_value').getValue());
+                                                                        var discount = parseFloat(_this.form.findField('cmhead_misc').getValue());
+                                                                        
+                                                                        if (discount > 0.0) {
+                                                                            this.setValue(0);        
+                                                                            return;
+                                                                        }
+                                                                        if (pv < 0) {
+                                                                            this.setValue(0);        
+                                                                            return;
+                                                                        }
+                                                                        var val = ((discount) / pv) * -100;
+                                                                        
+                                                                        //Roo.log("update discount?" + val);
+                                                                        this.setValue(val.toFixed(1));
+                                                                        
+                                                                         if (val > 0.0) {
+                                                                            _this.form.findField('cmhead_misc_descrip').setValue("Discount of " + val.toFixed(1)+'%');
+                                                                        
+                                                                        }
+                                                                        
+                                                                       
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        keyup : function (_self, e)
+                                                                        {
+                                                                           _this.form.findField('cmhead_misc_per').update();
+                                                                            _this.form.findField('cmhead_total').recalc();
+                                                                        }
+                                                                    },
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : '&nbsp;',
+                                                                    name : 'cmhead_misc',
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'ComboBox',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        select : function (combo, record, index)
+                                                                        {
+                                                                            _this.form.findField('cmhead_tax_value').setValue(
+                                                                                record.data.taxzone_rate * _this.form.findField('cmhead_taxable_value').getValue()
+                                                                            );
+                                                                        }
+                                                                    },
+                                                                    allowBlank : false,
+                                                                    displayField : 'taxzone_descrip',
+                                                                    editable : false,
+                                                                    emptyText : "Select tax zone",
+                                                                    fieldLabel : 'Tax Zone',
+                                                                    forceSelection : true,
+                                                                    hiddenName : 'cmhead_taxzone_id',
+                                                                    listWidth : 400,
+                                                                    loadingText : "Searching...",
+                                                                    minChars : 2,
+                                                                    name : 'cmhead_taxzone_id_taxzone_descrip',
+                                                                    pageSize : 20,
+                                                                    qtip : "Select tax zone",
+                                                                    queryParam : 'query[taxzone_descrip]',
+                                                                    selectOnFocus : true,
+                                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxzone_descrip}</b> </div>',
+                                                                    triggerAction : 'all',
+                                                                    typeAhead : true,
+                                                                    valueField : 'taxzone_id',
+                                                                    width : 285,
+                                                                    store : {
+                                                                        xtype: 'Store',
+                                                                        xns: Roo.data,
+                                                                        listeners : {
+                                                                            beforeload : function (_self, o){
+                                                                                o.params = o.params || {};
+                                                                                // set more here
+                                                                                
+                                                                                o.params.with_date = _this.form.findField('cmhead_docdate').getValue().format('Y-m-d');
+                                                                                Roo.log("with date?" + o.params.with_date);
+                                                                                
+                                                                                
+                                                                            }
+                                                                        },
+                                                                        remoteSort : true,
+                                                                        sortInfo : { direction : 'ASC', field: 'taxzone_descrip' },
+                                                                        proxy : {
+                                                                            xtype: 'HttpProxy',
+                                                                            xns: Roo.data,
+                                                                            method : 'GET',
+                                                                            url : baseURL + '/Roo/taxzone.php'
+                                                                        },
+                                                                        reader : {
+                                                                            xtype: 'JsonReader',
+                                                                            xns: Roo.data,
+                                                                            id : 'taxzone_id',
+                                                                            root : 'data',
+                                                                            totalProperty : 'total',
+                                                                            fields : [{'name':'taxzone_id','type':'int'},'taxzone_descrip']
+                                                                        }
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Tax',
+                                                                    name : 'cmhead_tax_value',
+                                                                    readOnly : true,
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'right',
+                                                            labelWidth : 300,
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Total',
+                                                                    name : 'cmhead_total',
+                                                                    readOnly : true,
+                                                                    width : 100,
+                                                                    recalc : function() {
+                                                                        var vals = _this.form.getValues();
+                                                                        this.setValue(
+                                                                            (1*vals.cmhead_value) + (1*vals.cmhead_freight) + (1*vals.cmhead_tax_value) + (1*vals.cmhead_misc)
+                                                                        );
+                                                                    }
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Billing",
+                                            style : 'width:420px',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    width : '420',
+                                                    labelWidth : '50',
+                                                    items : [
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                beforeselect : function (combo, record, index)
+                                                                {
+                                                                    // set _this.data values ..
+                                                                    
+                                                                    // just add everything...
+                                                                    for(var i in record.data) {
+                                                                      //  Roo.log('cmhead_billto_cntct_id_' + i +' ='  + record.data[i]);
+                                                                        _this.data['cmhead_billto_cntct_id_' + i] = record.data[i];
+                                                                    }
+                                                                
+                                                                    _this.form.findField('billto_address').update();
+                                                                    
+                                                                 
+                                                                },
+                                                                add : function (combo)
+                                                                {
+                                                                  
+                                                                  Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cmhead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                               
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cmhead_billto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('billto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cmhead_billto_cntct_id : data.cntct_id,
+                                                                                    cmhead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                    
+                                                                                });
+                                                                            }
+                                                                        );
+                                                                        //  Pman.Dialog.XtupleCustomer.show(
+                                                                            //{ cust_id : _this.form.findField('cohead_cust_id').getValue() }, 
+                                                                            //function(data) {
+                                                                        // refresh the data in the pulldown..
+                                                                    //    }); 
+                                                                
+                                                                }
+                                                            },
+                                                            allowBlank : false,
+                                                            alwaysQuery : true,
+                                                            displayField : 'cntct_name',
+                                                            editable : true,
+                                                            emptyText : "Select Contact",
+                                                            fieldLabel : 'Bill To (select)',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cmhead_billto_cntct_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cmhead_billto_cntct_id_cntct_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select Contact",
+                                                            queryParam : 'query[cntct_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cntct_name}</b> {cntct_addr_id_addr_line1}</div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'cntct_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                        o.params._customer_id = _this.data.cmhead_cust_id;
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'cntct_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/cntct.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'cntct_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{'name':'cntct_id','type':'int'},'cntct_name']
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                render : function (_self)
+                                                                {
+                                                                   Roo.log(this.el)
+                                                                   
+                                                                   
+                                                                   
+                                                                   this.el.on('click', function() { 
+                                                                       var id = _this.form.findField('cmhead_billto_cntct_id').getValue();
+                                                                        Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cmhead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                            
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cmhead_billto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('billto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cmhead_billto_cntct_id : data.cntct_id,
+                                                                                    cmhead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                });
+                                                                            }
+                                                                        );
+                                                                     });
+                                                                }
+                                                            },
+                                                            fieldLabel : 'or enter Address',
+                                                            name : 'billto_address',
+                                                            readOnly : true,
+                                                            update : function() {
+                                                            
+                                                                var c = ['first_name', 'last_name' ] ;
+                                                                var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];
+                                                                var v = [];
+                                                                Roo.each(c, function(e) {
+                                                                    if (_this.data['cmhead_billto_cntct_id_cntct_' +e] &&
+                                                                        _this.data['cmhead_billto_cntct_id_cntct_' +e].length) {
+                                                                        v.push(_this.data['cmhead_billto_cntct_id_cntct_' +e]);
+                                                                    }
+                                                                });
+                                                                Roo.each(a, function(e) {
+                                                                    if (_this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e] &&
+                                                                        _this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e].length) {
+                                                                        v.push(_this.data['cmhead_billto_cntct_id_cntct_addr_id_addr_' +e]);
+                                                                    }
+                                                                });
+                                                                this.setValue(v.join("\n"));
+                                                            }
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cmhead_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cmhead_billto_addr_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cmhead_taxable_value'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cmhead_posted'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cmhead_cust_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'taxzone_rate'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'has_item'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        deactivate : function (_self)
+                        {
+                            if(_this.grid){
+                                _this.grid.stopEditing();
+                            }
+                        },
+                        activate : function (_self)
+                        {
+                        
+                            _this.panel = this;
+                            
+                            try { if (MODULE.isBuilder) {
+                                return;
+                            } } catch(e) { }
+                            
+                            var id = _this.form.findField('cmhead_id').getValue() * 1;
+                            if (id < 1) {
+                                Roo.MessageBox.alert("Save First", "Save the order first, before adding items");
+                                _this.dialog.layout.getRegion('center').showPanel(0);
+                                return;
+                            }
+                            if (_this.grid) {
+                                _this.grid.ds.load({});
+                            }
+                        
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'coitem',
+                    title : "Credit Items",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                _this.hasQuery = 0;
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.ds.load({});
+                                }
+                            },
+                            afteredit : function (e)
+                            {
+                                //Roo.log('afteredit');
+                                //Roo.log(e);
+                                
+                                if (e.field == 'item_number' || e.originalValue == e.value) {
+                                    // afterselect handles this...
+                                    return;
+                                }
+                                var r = e.record;
+                                
+                                if ( r && r.data.cmitem_id) {
+                                    // as we disable update to the display on the ajax callback to 
+                                    // allow editing flow to continue, and not refresh - we can only update
+                                    // these values after something has actually been edited.
+                                     r.set('coitem_id', r.data.cmitem_id);
+                                }
+                                
+                                var rate = 0;
+                                if(r.data.cmitem_taxtype_id_taxtype_name == 'Taxable' ){
+                                    rate = _this.form.findField('taxzone_rate').getValue();
+                                }
+                                if(e.field == 'cmitem_tax_unitprice'){
+                                    r.set('cmitem_unitprice', r.data.cmitem_tax_unitprice * 1 / (1 + rate * 1));
+                            //        fields.push('cmitem_unitprice');
+                                }
+                                if(e.field == 'cmitem_unitprice'){
+                                    r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1) );
+                            //        fields.push('cmitem_tax_unitprice');
+                                }
+                                if(e.field == 'cmitem_taxtype_id'){
+                                    r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1) );
+                            //        fields.push('cmitem_tax_unitprice');
+                                            
+                                }
+                                r.set('cmitem_tax_listprice', r.data.cmitem_item_listprice * (1 + rate * 1) );
+                            //    fields.push('cmitem_tax_listprice');
+                                r.set('cmitem_line_value', r.data.cmitem_qtycredit * r.data.cmitem_unitprice );
+                            //    fields.push('cmitem_line_value');
+                                r.set('cmitem_line_tax_value', r.data.cmitem_qtycredit * r.data.cmitem_tax_unitprice );
+                            //    fields.push('cmitem_line_tax_value'); 
+                                
+                            //    fields.push('cmitem_id');
+                                
+                                _this.hasQuery += 1;
+                                
+                                 var doupdate = function() { 
+                                   if (!_this.itemsUpdating) {
+                                        Roo.log('doupdate...');
+                                        
+                                        _this.hasQuery -= 1;
+                                        r.commit();
+                                        return;
+                                    }
+                                    doupdate.defer(1000);
+                                }
+                                
+                                doupdate();
+                                
+                                
+                            },
+                            beforeedit : function (e)
+                            {
+                                // we can only edit if nothing is assigned to shipping or invoices..
+                                if (_this.form.findField('cmhead_posted').getValue() == 'true') {
+                                    Roo.MessageBox.alert("Error", "credit memo is already posted");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                
+                                return;
+                                
+                                // seems below logic is useless...!!!!
+                                var rec = e.record;
+                            
+                                if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {
+                                    Roo.MessageBox.alert("Error", "That item has been shipped or invoices - void the shipments/invoices first");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                
+                                if (rec.data.coitem_subnumber * 1 > 0) {
+                                    Roo.log("Edit container event");
+                                    Roo.log(e); // if it's a tab.. 
+                            
+                                    
+                                    switch(e.field) {
+                                        // allow editing of source / destination..
+                                        case 'coitem_shipto_id':
+                                        case 'coitem_location_src':            
+                                            return;
+                                        default : 
+                                            break;
+                                    }
+                                    Roo.MessageBox.alert("Error", "That is a kit item, edit the container.");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                // zero off values..
+                                //if (e.field == 'coitem_qtyord' && rec.data.coitem_qtyord == 0) {
+                                //        e.value ='';
+                                //    }
+                                //    if (e.field == 'coitem_custprice' && rec.data.coitem_qtyord == 0.0) {
+                                //        e.value ='';
+                                //    }
+                                
+                                if (rec.data.item_type == 'K' && e.field == 'item_number') {
+                                    // you can not change the product type on kits' as it messing things up..
+                                    Roo.MessageBox.alert("Error", "That is a kit item,if you need to change it, delete it first.");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                
+                            },
+                            celldblclick : function (_self, rowIndex, columnIndex, e)
+                            {
+                                var rec = this.ds.getAt(rowIndex);
+                                var di = this.cm.getDataIndex(columnIndex);
+                                if (di != 'avail_qty') {
+                                    return;
+                                }
+                                Pman.Dialog.XtupleInvHistory.show({
+                                    itemsite_item_id_item_number   : rec.data.item_number,
+                                   // itemsite_item_id_item_descript1 : rec.data.item_descrip1,
+                                    location_name : rec.data.coitem_location_src_location_name,
+                                    location_descrip : rec.data.coitem_location_src_location_descrip,
+                                    
+                                    invhist_transdate : _this.form.findField('cohead_targetdate').getValue() 
+                                }); 
+                                
+                            },
+                            rowclass : function (gridview, rowcfg)
+                            {
+                                if (rowcfg.record.data.coitem_status == 'C' &&
+                                    rowcfg.record.data.shipitem_shipped * 1 < 1) {
+                                    
+                                    rowcfg.rowClass = 'strikethrough';
+                                }
+                                 if (rowcfg.record.data.coitem_status == 'X'  ) {
+                                    
+                                    rowcfg.rowClass = 'strikethrough';
+                                }
+                               // Roo.log(rowcfg);
+                            //    shipitem_shipped
+                            }
+                        },
+                        autoExpandColumn : 'cmitem_comments',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        loadAvail : function() {
+                            
+                            return; //not used.
+                               
+                             var q = [];
+                            this.ds.each(  function(r) {
+                            
+                                // only update if we do not have the details.
+                                if (r.data.avail_qty == 0) {
+                                
+                                }
+                                q.push( { 
+                                    item : r.data.item_number, 
+                                    loc: r.data.coitem_location_src_location_name,
+                                    id: r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '')
+                                 } );
+                            });
+                            
+                            // needs to be a post to allow long lists of products..
+                            
+                            new Pman.Request({
+                                url : baseURL + '/Roo/itemloc',
+                                method : 'POST',
+                                mask : "Loading available qty",
+                                maskel : _this.grid.view.el,
+                                params : {
+                                    _availqty : Roo.encode(q),
+                                    curr_id : _this.form.findField('cohead_curr_id').getValue()
+                                },
+                                success : function(d) 
+                                {
+                                    _this.grid.ds.each(function(r) { 
+                                         var id = r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '');
+                                    
+                                    
+                                        if (typeof(d.data[id]) == 'undefined') {
+                                            return;
+                                        }
+                                        r.set('avail_qty', d.data[id].qty);
+                                        if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {
+                                            r.set('coitem_unitcost_in_order_cur', d.data[id].unitcost);
+                                        }
+                                    
+                                    });
+                                
+                                }
+                            });
+                            
+                                
+                                        
+                        },
+                        sm : {
+                            xtype: 'CellSelectionModel',
+                            xns: Roo.grid,
+                            listeners : {
+                                tabend : function (_self)
+                                {
+                                    _this.addItemBtn.fireEvent('click', _this.addItemBtn);
+                                },
+                                beforeeditnext : function (eventdata)
+                                {
+                                    return;
+                                    // this does not work, as the reload effect cancels editng.
+                                    var rec = _this.grid.ds.getAt(eventdata.cell[0]);
+                                    if (rec.data.coitem_subnumber *1 < 0 ) {
+                                        return;
+                                    }
+                                    var r = eventdata.cell[0] + 1;
+                                
+                                    while (true) {
+                                        if (r > _this.grid.ds.getCount()-1 ) {
+                                            eventdata.cell = false;
+                                            return;
+                                        }
+                                        rec =  _this.grid.ds.getAt(r);
+                                        if (rec.data.coitem_subnumber *1 < 0 ) {
+                                           eventdata.cell = [ r, eventdata.cell[1] ];
+                                           return;
+                                        }
+                                        r++;
+                                    }
+                                    
+                                    
+                                 
+                                
+                                }
+                            },
+                            enter_is_tab : true
+                        },
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                
+                                    try {
+                                       this.removeAll();
+                                   } catch (e) { }
+                                   
+                                    Roo.log(_this.data);
+                                    if (!_this.data || !_this.data.cmhead_id) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    Roo.log(_this.data);
+                                    o.params.cmitem_cmhead_id = _this.data.cmhead_id;
+                                    o.params.limit = 999;
+                                    
+                                },
+                                update : function (_self, rec, operation)
+                                {
+                                   
+                                   if (operation !=  Roo.data.Record.COMMIT) {
+                                       return;
+                                   }
+                                   
+                                   // row has been updated..
+                                   // if the qty + item has been filled in, we should try and save it..
+                                    if (!(rec.data.cmitem_itemsite_id * 1) || !(rec.data.cmitem_qtycredit*1) || !(rec.data.cmitem_unitprice*1)) {
+                                        Roo.log('not saving - row not completed');
+                                        return;
+                                    }
+                                
+                                    if (_this.itemsUpdating) {
+                                        Roo.log('currently updating?');
+                                        return;
+                                    }
+                                    _this.itemsUpdating = true;
+                                
+                                
+                                    Roo.log('Running update');   
+                                    
+                                    new Pman.Request({
+                                        url : baseURL+'/Roo/Cmitem',
+                                        method : 'POST',
+                                        
+                                        params : rec.data,
+                                        success: function(res)
+                                        {
+                                            Roo.log('GOT success');
+                                            // update the data...
+                                            if (rec.data.item_type == 'K') {
+                                                 _this.itemsUpdating = false; 
+                                                _this.grid.ds.load({});
+                                                return;
+                                            }
+                                            if (_this.grid.activeEditor) {
+                                                 rec.editing = true;
+                                             } 
+                                            rec.set('cmitem_id', res.data.cmitem_id);
+                                            
+                                            _this.itemsUpdating = false; 
+                                            
+                                            if(_this.hasQuery != 0){
+                                                 
+                                                return;
+                                            }
+                                            
+                                            rec.dirty = false;
+                                            delete rec.modified;
+                                            
+                                            _this.grid.loadAvail();
+                                            
+                                        },
+                                        failure : function(res)
+                                        {
+                                            Roo.MessageBox.alert(res.message);
+                                            _this.itemsUpdating = false;
+                                        }
+                                        
+                                        
+                                    });
+                                    
+                                    
+                                   
+                                   
+                                   
+                                },
+                                load : function (_self, records, options)
+                                {
+                                    // need to fetch availablity from master data..
+                                    // build a list of what to ask..
+                                    Roo.log(records);
+                                    // query: ITEM CODE - LOCATION
+                                    
+                                    //_this.grid.loadAvail.defer(100, _this.grid);
+                                    var rate = 0;
+                                        
+                                    Roo.each(records, function(r){
+                                        rate = 0;
+                                        if(r.data.cmitem_taxtype_id == r.data.cmitem_taxable_id ){
+                                            rate = _this.form.findField('taxzone_rate').getValue();
+                                        }
+                                        r.set('cmitem_tax_unitprice', r.data.cmitem_unitprice * (1 + rate * 1));
+                                        r.set('cmitem_tax_listprice', r.data.cmitem_item_listprice * (1 + rate * 1));
+                                        r.set('cmitem_line_tax_value', r.data.cmitem_line_value * (1 + rate * 1));
+                                    })    
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'cmitem_linenumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/Cmitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'coitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyord'
+                                    },
+                                    {
+                                        'name': 'coitem_unitcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price'
+                                    },
+                                    {
+                                        'name': 'coitem_custprice'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreturned'
+                                    },
+                                    {
+                                        'name': 'coitem_prcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreserved'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                            
+                                            
+                                            if (_this.form.findField('cmhead_posted').getValue() == 'true') {
+                                                Roo.MessageBox.alert("Error", "credit memo is already posted");
+                                                return;
+                                            }
+                                            // work out last 
+                                               // work out last 
+                                                        var grid = _this.grid;
+                                                        var last = 0;
+                                                        
+                                                        _this.grid.ds.each(function(r) {
+                                                            last = r.data.cmitem_linenumber;
+                                                        });
+                                                        
+                                                        last++;
+                                                        grid.stopEditing();
+                                                        var nr = _this.grid.ds.reader.newRow({
+                                                            cmitem_linenumber : last,
+                                                            item_number : '',
+                                                            item_descrip1 : '',
+                                                            cmitem_cmhead_id : _this.form.findField('cmhead_id').getValue(),
+                                                            cmitem_comments : '',
+                                                            cmitem_taxtype_id : _this.data.default_taxtype_id,
+                                                            cmitem_taxtype_id_taxtype_name : 'Taxable'
+                                                        });
+                                                        grid.stopEditing();
+                                                        grid.ds.insert(grid.ds.getCount(), nr); 
+                                                        grid.startEditing(grid.ds.getCount()-1, 1); // type..
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.addItemBtn = _self;
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Add",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            
+                                            var last = 1;    
+                                            _this.grid.ds.each(function(r) {
+                                                last = r.data.cmitem_linenumber +1;
+                                        
+                                            
+                                            });
+                                            
+                                            var grid = _this.grid;
+                                            var ct  =    _this.grid.ds.getCount();
+                                            var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;
+                                                 
+                                            var cmhead_cust_id = _this.form.findField('cmhead_cust_id').getValue();
+                                            var cmhead_id = _this.form.findField('cmhead_id').getValue();
+                                            
+                                            Pman.Dialog.XtupleSalesProductList.show( {cohead_cust_id : cmhead_cust_id, cmhead_id : cmhead_id} , function(res) {
+                                            
+                                                Roo.log(res);
+                                                grid.stopEditing();
+                                        
+                                                if (lastrow) {
+                                                    var lr = lastrow;
+                                                    if (!lr.data.cmitem_itemsite_id) {
+                                                        lr.set('cmitem_itemsite_id', res.item_itemsite_id_itemsite_id);
+                                                        lr.set('item_number',  res.item_number);
+                                                        lr.set('item_descrip1', res.item_descrip1);                                
+                                                        lr.set('cmitem_comments', res.item_descrip1);
+                                                        lr.set('cmitem_cmhead_id', _this.form.findField('cmhead_id').getValue());
+                                                        return;
+                                                    }
+                                                }
+                                                var rate = _this.form.findField('taxzone_rate').getValue();
+                                                 var nr = grid.ds.reader.newRow({
+                                                            cmitem_linenumber : last,
+                                                            cmitem_itemsite_id : res.item_itemsite_id_itemsite_id,
+                                                            item_number :  res.item_number,
+                                                            item_descrip1 : res.item_descrip1 ,
+                                                            cmitem_cmhead_id : _this.form.findField('cmhead_id').getValue(),
+                                                            cmitem_comments : res.item_descrip1,
+                                                            cmitem_tax_listprice : res.item_price * ( 1 + rate * 1),
+                                                            cmitem_item_listprice : res.item_price,
+                                                            cmitem_tax_unitprice : res.item_price * ( 1 + rate * 1),
+                                                            cmitem_unitprice : res.item_price,
+                                                            cmitem_qtycredit : 1,
+                                                            cmitem_line_value : res.item_price,
+                                                            cmitem_line_tax_value : res.item_price * ( 1 + rate * 1)
+                                                            
+                                                        });
+                                                grid.ds.insert(grid.ds.getCount(), nr);
+                                                
+                                                var ar = grid.ds.getAt(grid.ds.getCount() - 1);
+                                                ar.commit();
+                                                
+                                           }); 
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Find Products",
+                                    icon : rootURL + '/Pman/templates/images/search.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function ()
+                                        {
+                                            var cmhead_id = 1 * _this.form.findField('cmhead_id').getValue();
+                                            if (!cmhead_id) {
+                                                Roo.MessageBox.alert("Error", "Save credit memo first!");
+                                                return;
+                                            
+                                            }
+                                            
+                                            new Pman.Download({
+                                                url : baseURL + '/Roo/Metasql',
+                                                method : 'GET',
+                                                timeout: 600000,
+                                                params : {
+                                                    _group : 'cmhead',
+                                                    _name : 'items',
+                                                    'cmhead_id:number' : cmhead_id,
+                                                    csvCols : '*',
+                                                    csvTitles : '*', 
+                                                    limit : 9999       
+                                                }
+                                            });   
+                                                    
+                                           
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Download Excel",
+                                    icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                           
+                                            if (_this.form.findField('cmhead_posted').getValue() == 'true') {
+                                                Roo.MessageBox.alert("Error", "credit memo is already posted");
+                                                return;
+                                            }
+                                           
+                                            Pman.Dialog.Image.show(
+                                               {
+                                                    _url : baseURL + '/Xtuple/Import/CreditMemo',
+                                                    onid : _this.form.findField('cmhead_id').getValue()
+                                                
+                                               },
+                                               function (res) {
+                                                    _this.grid.ds.load({});
+                                               }
+                                           );
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.uploadBtn = _self;
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Upload Excel",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             _this.grid.stopEditing();
+                                            // check that no shipments or invoices are done..
+                                         if (_this.form.findField('cmhead_posted').getValue() == 'true') {
+                                                Roo.MessageBox.alert("Error", "credit memo is already posted");
+                                                return;
+                                            }
+                                                                                    // check that no shipments or invoices are done..
+                                            var rc = _this.grid.getSelectionModel().getSelectedCell();
+                                            
+                                            var rec = _this.grid.ds.getAt(rc[0]);
+                                            
+                                            Roo.MessageBox.confirm("Confirm", "Are you sure you want to delete that line?", function(r)
+                                            {
+                                                if (r != 'yes') {
+                                                    return;
+                                                }
+                                                remove();
+                                            });
+                                            
+                                            if (!rec.data.cmitem_id) {
+                                                _this.grid.ds.remove(rec);
+                                                return;
+                                            }
+                                            function remove()
+                                            {
+                                                new  Pman.Request({
+                                                    url : baseURL + '/Roo/cmitem',
+                                                    method : 'POST',
+                                                    params : {
+                                                        _delete : rec.data.cmitem_id
+                                                    
+                                                    },
+                                                    success : function() {
+                                                        if (rec.data.item_type == 'K') {
+                                                            _this.grid.ds.load({});
+                                                            return;
+                                                        }
+                                                        _this.grid.ds.remove(rec);
+                                                    }
+                                                
+                                                });
+                                            }
+                                        
+                                            
+                                            
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Delete",
+                                    icon : rootURL + '/Pman/templates/images/trash.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cmitem_linenumber',
+                                header : 'Item#',
+                                width : 60,
+                                renderer : function(v,x,r) {
+                                
+                                    if (r.data.coitem_subnumber * 1 > 0) {
+                                         return String.format('{0}.{1}', v,r.data.coitem_subnumber);
+                                     }
+                                     return String.format('{0}', v);
+                                  }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item Code',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            beforeselect : function (combo, record, index)
+                                            {
+                                              // set _this.data values ..
+                                              var ar = _this.grid.activeEditor.record;
+                                              //Roo.log('beforeselect');
+                                              
+                                              var rate = _this.form.findField('taxzone_rate').getValue();
+                                              
+                                              (function() { 
+                                                
+                                                ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);
+                                                ar.set('cmitem_comments', record.data.itemsite_item_id_item_descrip1);        
+                                                ar.set('cmitem_tax_listprice', record.data.item_listprice * ( 1 + rate * 1) );
+                                                ar.set('cmitem_item_listprice', record.data.item_listprice * 1);
+                                                ar.set('cmitem_tax_unitprice', record.data.item_price * ( 1 + rate * 1) );
+                                                ar.set('cmitem_unitprice', record.data.item_price * 1);
+                                                ar.set('cmitem_qtycredit', 1);
+                                                ar.set('cmitem_line_value', record.data.item_price * ar.data.cmitem_qtycredit);
+                                                ar.set('cmitem_line_tax_value', ar.data.cmitem_tax_unitprice * ar.data.cmitem_qtycredit);
+                                                ar.set('cmitem_itemsite_id', record.data.itemsite_id);
+                                                ar.set('item_number', record.data.itemsite_item_id_item_number);
+                                                ar.set('item_type', record.data.itemsite_item_id_item_type);
+                                                ar.set('avail_qty', 0);
+                                              //  ar.updateFields = ['All'];
+                                                ar.commit();
+                                              }).defer(100);
+                                              
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'itemsite_item_id_item_number',
+                                        editable : true,
+                                        emptyText : "Select item",
+                                        forceSelection : true,
+                                        hiddenName : 'itemsite_item_id_item_number',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'item_number',
+                                        pageSize : 20,
+                                        qtip : "Select item",
+                                        queryParam : 'query[number]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> ${item_price:toFixed(2)}- {itemsite_item_id_item_descrip1} </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'item_number',
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    o.params.customer_id = _this.form.findField('cmhead_cust_id').getValue();
+                                                    o.params['query[cmhead_id]'] = _this.form.findField('cmhead_id').getValue();
+                                                    //o.params.shipto_cust_id = _this.data.cohead_cust_id;
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'item_number' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/itemsite.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'shipto_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{'name':'item_id','type':'int'},'item_number']
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cmitem_comments',
+                                header : 'Item Description',
+                                width : '150.00',
+                                renderer : function(v,x,r) { 
+                                
+                                    if (!v.length) {
+                                        r.set('cmitem_comments', r.data.item_descrip1);
+                                        v = r.data.item_descrip1;
+                                    }
+                                    if (v && v.length > 49) {
+                                        return String.format('<span style="color:orange" qtip="line may be too long to print">{0}</span>', v);
+                                    }
+                                    return String.format('{0}', v); 
+                                        
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        allowBlank : false
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_qtycredit',
+                                header : 'Qty',
+                                width : 50,
+                                renderer : function(v)
+                                {
+                                    return String.format('{0}', v ? parseInt(v) : '');
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        allowDecimals : false,
+                                        decimalPrecision : 0,
+                                        minValue : 1,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_tax_listprice',
+                                header : 'List Price w. tax',
+                                width : 80,
+                                renderer : function(v,x,r)
+                                {
+                                 //   var rate = _this.form.findField('taxzone_rate').getValue();
+                                 //   v = v * (1 + rate * 1);
+                                 
+                                    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_taxtype_id',
+                                header : 'Taxed',
+                                width : 50,
+                                renderer : function(v,x,r) { return String.format('{0}', r.data.cmitem_taxtype_id_taxtype_name); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        allowBlank : false,
+                                        displayField : 'taxtype_name',
+                                        editable : false,
+                                        emptyText : "Select Tax Type",
+                                        forceSelection : true,
+                                        hiddenName : 'cmitem_taxtype_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'cmitem_taxtype_id_taxtype_name',
+                                        pageSize : 20,
+                                        qtip : "Select taxtype",
+                                        queryParam : 'query[taxtype_id]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxtype_name}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        valueField : 'taxtype_id',
+                                        width : 285,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                    
+                                                /*    o.params.with_date = _this.form.findField('cohead_orderdate').getValue().format('Y-m-d'); 
+                                                    Roo.log("with date?" + o.params.with_date);*/
+                                                    
+                                                    
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'taxtype_name' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/taxtype.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'taxtype_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{'name':'taxtype_id','type':'int'},'taxtype_name']
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_tax_unitprice',
+                                header : 'Unit Price w. tax',
+                                width : 90,
+                                renderer : function(v,x,r)
+                                {
+                                    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 2,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_unitprice',
+                                header : 'Unit Price',
+                                width : 75,
+                                renderer : function(v)
+                                {
+                                    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 2,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cmitem_line_value',
+                                header : 'Total',
+                                width : 75,
+                                renderer : function(v)
+                                {
+                                    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');
+                                }
+                            },
+                            {
+                                align : 'right',
+                                dataIndex : 'cmitem_line_tax_value',
+                                header : 'Total w. tax',
+                                width : 80,
+                                renderer : function(v,x,r)
+                                {
+                                    return String.format('{0}', v ? parseFloat(v).toFixed(2) : '');
+                                },
+                                xns : Roo.grid
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.cpanel = this;
+                            
+                            var id = _this.form.findField('cmhead_id').getValue() * 1;
+                            if (id < 1) {
+                                Roo.MessageBox.alert("Error", "save the credit memo first!");
+                                _this.dialog.layout.getRegion('center').showPanel(0);
+                                return;
+                            }
+                            
+                            if (_this.cgrid) {
+                                _this.cgrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'checkitem',
+                    title : "Miscellaneous Check",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.cgrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.cpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'checkitem_checkhead_id_checkhead_notes',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, options)
+                                {
+                                    options.params = options.params || {};
+                                    options.params.checkitem_cmnumber = _this.form.findField('cmhead_number').getValue();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'checkitem_id', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/checkitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'type',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_office_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_phone',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_fax',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_email',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_company_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_role',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_remarks',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_passwd',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_owner_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_lang',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_no_reset_sent',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_action_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_project_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_by',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_dt',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'leader_firstname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_lastname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_name_facebook',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_blog',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_twitter',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_linkedin',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_crm_lead_percentage',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_industry_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_updated_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_created_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_type_id',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Displaying check item{0} - {1} of {2}",
+                            emptyMsg : "No check item found",
+                            pageSize : 25
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'checkitem_docdate',
+                                header : 'Date',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'checkitem_bankaccnt_id_bankaccnt_name',
+                                header : 'Bank Account',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'checkitem_checkhead_id_checkhead_for',
+                                header : 'Memo',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'checkitem_checkhead_id_checkhead_notes',
+                                header : 'Notes',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'checkitem_curr_id_curr_name',
+                                header : 'Currency',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'checkitem_amount',
+                                header : 'Amount',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v ? parseFloat(v).toFixed(2) : ''); }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.apanel = this;
+                            if (_this.agrid) {
+                                _this.agrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'invchead',
+                    title : "Applications",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.agrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.apanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'arapply_target_docnumber',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                
+                                    try {
+                                       this.removeAll();
+                                    } catch (e) { }
+                                
+                                    if (!_this.data || !_this.data.cmhead_id) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    
+                                    o.params._application = _this.data.cmhead_id
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'arapply_id', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/Arapply.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'type',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_office_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_phone',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_fax',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_email',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_company_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_role',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_remarks',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_passwd',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_owner_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_lang',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_no_reset_sent',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_action_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_project_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_by',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_dt',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'leader_firstname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_lastname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_name_facebook',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_blog',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_twitter',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_linkedin',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_crm_lead_percentage',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_industry_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_updated_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_created_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_type_id',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Displaying application{0} - {1} of {2}",
+                            emptyMsg : "No application found",
+                            pageSize : 25
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_id',
+                                header : 'ID',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_distdate',
+                                header : 'Date',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_target_doctype',
+                                header : 'Target Doctype',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_target_docnumber',
+                                header : 'Target Docnumber',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_curr_id_curr_name',
+                                header : 'Currency',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'arapply_applied',
+                                header : 'Applied',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.hpanel = this;
+                            if (_this.hgrid) {
+                                _this.hgrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'events',
+                    title : "History",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.hgrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.hpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'remarks',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, options)
+                                {
+                                    options.params._related_on_table = 'cmhead';
+                                    options.params._related_on_id = _this.form.findField('cmhead_id').getValue();
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'event_when', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/events.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'event_when',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'action',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'ipaddr',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'person_id_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'remarks',
+                                        'type': 'string'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            pageSize : 25,
+                            displayInfo : true,
+                            displayMsg : "Displaying events{0} - {1} of {2}",
+                            emptyMsg : "No events found"
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'event_when',
+                                header : 'Changed',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'action',
+                                header : 'action',
+                                width : 120,
+                                renderer : function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'ipaddr',
+                                header : 'IP address',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'person_id_name',
+                                header : 'Who',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'remarks',
+                                header : 'Notes',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                alwaysShowTabs : true,
+                tabPosition : 'top'
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                              if (_this.grid)  _this.grid.stopEditing();
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                          // do some checks?
+                               if (_this.grid)  _this.grid.stopEditing();
+                              if (_this.form.findField('cmhead_posted').getValue() == 'true') {
+                                  Roo.MessageBox.alert("Error", "credit memo is already posted");
+                                  return;
+                              }
+                              var loose = false;
+                              var ar = [];
+                              if (_this.grid && _this.grid.ds) {
+                                  _this.grid.ds.each(function(rec) {
+                                      if (!(rec.data.cmitem_itemsite_id * 1) || !(rec.data.cmitem_qtycredit*1) || !(rec.data.cmitem_unitprice*1)) {
+                                          loose = true;
+                                          return true;
+                                      } 
+                                      ar.push(rec);
+                                      
+                                  });
+                                  if (loose) {
+                                      Roo.MessageBox.alert("Error", "Some lines do not have product/qty/price set");
+                                      return;
+                                  }    
+                              }
+                              if(ar.length){
+                                  _this.form.findField('has_item').setValue(ar.length);
+                              } 
+                          
+                              _this.form.doAction("submit");
+                        },
+                        render : function (_self)
+                        {
+                        _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleCreditMemoNew.bjs b/Pman.Dialog.XtupleCreditMemoNew.bjs
new file mode 100644 (file)
index 0000000..fef6b68
--- /dev/null
@@ -0,0 +1,121 @@
+{
+    "id": "roo-file-3",
+    "name": "Pman.Dialog.XtupleCreditMemoNew",
+    "parent": "",
+    "title": "",
+    "path": "/home/julian/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleCreditMemoNew.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    _this.form.findField('cmhead_cust_id').focus();\n}"
+            },
+            "closable": false,
+            "height": 120,
+            "modal": true,
+            "resizable": false,
+            "title": "Create new Credit Memo",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}"
+                            },
+                            "xtype": "Form",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "add": "function (combo)\n{\n \n    Pman.Dialog.XtupleCustomer.show( { id : 0 } , function(res) {\n        Roo.log(res);\n        // fill in customer\n        _this.form.findField('cmhed_cust_id_cust_name').setValue(res.cust_id);\n        _this.form.findField('cmhed_cust_id_cust_name').el.dom.value = res.cust_name;\n        \n    })\n    \n}\n\n"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "fieldLabel": "Select Customer",
+                                    "forceSelection": true,
+                                    "hiddenName": "cmhead_cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cmhead_cust_id_cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select custinfo",
+                                    "queryParam": "query[cust_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\">{cust_number}: <b>{cust_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "cust_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   // o.params._with_last_location = 1;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   //_this.findField('cuinfo_\n   \n   // check if customer is filled in.\n   if (_this.form.findField('cmhead_cust_id').getValue() < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a customer\");\n        return;\n   }\n   \n   var data = _this.form.getFieldValues();\n   var c = _this.form.findField('cmhead_cust_id').lastData;\n   \n   data.cmhead_curr_id      = c.cust_curr_id;\n   data.cmhead_curr_id_curr_name = c.cust_curr_id_curr_name;\n   \n   data.cmhead_terms_id      = c.cust_terms_id;\n   data.cmhead_terms_id_terms_descrip = c.cust_terms_id_terms_descrip;\n   \n   // fill in staff in/c..\n   \n   data.cmhead_salesrep_id =  Pman.Login.authUser.salesrep.salesrep_id;\n   data.cmhead_salesrep_id_salesrep_name =  Pman.Login.authUser.salesrep.salesrep_name;\n   \n   data.cmhead_docdate = new Date();\n   \n   data.cmhead_taxzone_id = c.cust_taxzone_id;\n   data.cmhead_taxzone_id_taxzone_descrip = c.cust_taxzone_id_taxzone_descrip;\n   data.cmhead_location_id = c.default_location_id,\n   data.cmhead_location_id_location_name = c.default_location_name;\n\n   Pman.Dialog.XtupleCreditMemo.show(data, function() {\n    _this.dialog.hide();\n    _this.callback();\n   }); \n   \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleCreditMemoNew.js b/Pman.Dialog.XtupleCreditMemoNew.js
new file mode 100644 (file)
index 0000000..5619901
--- /dev/null
@@ -0,0 +1,194 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleCreditMemoNew = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    _this.form.findField('cmhead_cust_id').focus();
+                }
+            },
+            closable : false,
+            height : 120,
+            modal : true,
+            resizable : false,
+            title : "Create new Credit Memo",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                }
+                            },
+                            items : [
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        add : function (combo)
+                                        {
+                                         
+                                            Pman.Dialog.XtupleCustomer.show( { id : 0 } , function(res) {
+                                                Roo.log(res);
+                                                // fill in customer
+                                                _this.form.findField('cmhed_cust_id_cust_name').setValue(res.cust_id);
+                                                _this.form.findField('cmhed_cust_id_cust_name').el.dom.value = res.cust_name;
+                                                
+                                            })
+                                            
+                                        }
+                                    },
+                                    allowBlank : false,
+                                    displayField : 'cust_name',
+                                    editable : true,
+                                    fieldLabel : 'Select Customer',
+                                    forceSelection : true,
+                                    hiddenName : 'cmhead_cust_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'cmhead_cust_id_cust_name',
+                                    pageSize : 20,
+                                    qtip : "Select custinfo",
+                                    queryParam : 'query[cust_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button">{cust_number}: <b>{cust_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'cust_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                               // o.params._with_last_location = 1;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/custinfo.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'cust_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           //_this.findField('cuinfo_
+                           
+                           // check if customer is filled in.
+                           if (_this.form.findField('cmhead_cust_id').getValue() < 1) {
+                                Roo.MessageBox.alert("Error", "Select a customer");
+                                return;
+                           }
+                           
+                           var data = _this.form.getFieldValues();
+                           var c = _this.form.findField('cmhead_cust_id').lastData;
+                           
+                           data.cmhead_curr_id      = c.cust_curr_id;
+                           data.cmhead_curr_id_curr_name = c.cust_curr_id_curr_name;
+                           
+                           data.cmhead_terms_id      = c.cust_terms_id;
+                           data.cmhead_terms_id_terms_descrip = c.cust_terms_id_terms_descrip;
+                           
+                           // fill in staff in/c..
+                           
+                           data.cmhead_salesrep_id =  Pman.Login.authUser.salesrep.salesrep_id;
+                           data.cmhead_salesrep_id_salesrep_name =  Pman.Login.authUser.salesrep.salesrep_name;
+                           
+                           data.cmhead_docdate = new Date();
+                           
+                           data.cmhead_taxzone_id = c.cust_taxzone_id;
+                           data.cmhead_taxzone_id_taxzone_descrip = c.cust_taxzone_id_taxzone_descrip;
+                           data.cmhead_location_id = c.default_location_id,
+                           data.cmhead_location_id_location_name = c.default_location_name;
+                        
+                           Pman.Dialog.XtupleCreditMemo.show(data, function() {
+                            _this.dialog.hide();
+                            _this.callback();
+                           }); 
+                           
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleCustomer.bjs b/Pman.Dialog.XtupleCustomer.bjs
new file mode 100644 (file)
index 0000000..2f1aae4
--- /dev/null
@@ -0,0 +1,1109 @@
+{
+    "id": "roo-file-279",
+    "name": "Pman.Dialog.XtupleCustomer",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleCustomer.bjs",
+    "items": [
+        {
+            ".builderCfg": "{\"cols\":[{\"table\":\"custinfo\",\"column\":\"cust_custtype_id\",\"columnshort\":\"cust_custtype_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"custtype_id\",\"deps\":[{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_code\",\"columnshort\":\"custtype_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_char\",\"columnshort\":\"custtype_char\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Customer Type\",\"display\":\"cust_custtype_id_custtype_descrip\"},{\"table\":\"custinfo\",\"column\":\"cust_salesrep_id\",\"columnshort\":\"cust_salesrep_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"salesrep_id\",\"deps\":[{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_active\",\"columnshort\":\"salesrep_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_number\",\"columnshort\":\"salesrep_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_commission\",\"columnshort\":\"salesrep_commission\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_method\",\"columnshort\":\"salesrep_method\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_emp_id\",\"columnshort\":\"salesrep_emp_id\",\"ctype\":\"int4\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Sales Rep\",\"display\":\"cust_salesrep_id_salesrep_name\"},{\"table\":\"custinfo\",\"column\":\"cust_commprcnt\",\"columnshort\":\"cust_commprcnt\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"cust_commprcnt\"},{\"table\":\"custinfo\",\"column\":\"cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Name\"},{\"table\":\"custinfo\",\"column\":\"cust_creditlmt\",\"columnshort\":\"cust_creditlmt\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Credit Limit\",\"display\":\"cust_creditlmt_curr_id_curr_symbol\"},{\"table\":\"custinfo\",\"column\":\"cust_creditrating\",\"columnshort\":\"cust_creditrating\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Credit Rating\"},{\"table\":\"custinfo\",\"column\":\"cust_financecharge\",\"columnshort\":\"cust_financecharge\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Apply Finance Charge\"},{\"table\":\"custinfo\",\"column\":\"cust_backorder\",\"columnshort\":\"cust_backorder\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Allow Back Order\"},{\"table\":\"custinfo\",\"column\":\"cust_partialship\",\"columnshort\":\"cust_partialship\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Allow Partial Shipment\"},{\"table\":\"custinfo\",\"column\":\"cust_terms_id\",\"columnshort\":\"cust_terms_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"terms_id\",\"deps\":[{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_code\",\"columnshort\":\"terms_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_type\",\"columnshort\":\"terms_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_duedays\",\"columnshort\":\"terms_duedays\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_discdays\",\"columnshort\":\"terms_discdays\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_discprcnt\",\"columnshort\":\"terms_discprcnt\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_cutoffday\",\"columnshort\":\"terms_cutoffday\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_ap\",\"columnshort\":\"terms_ap\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"terms\",\"column\":\"cust_terms_id_terms_ar\",\"columnshort\":\"terms_ar\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\",\"display\":\"cust_terms_id_terms_descrip\"},{\"table\":\"custinfo\",\"column\":\"cust_discntprcnt\",\"columnshort\":\"cust_discntprcnt\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Discount Percent\"},{\"table\":\"custinfo\",\"column\":\"cust_balmethod\",\"columnshort\":\"cust_balmethod\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Balance Method\"},{\"table\":\"custinfo\",\"column\":\"cust_ffshipto\",\"columnshort\":\"cust_ffshipto\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"is ff Ship To\"},{\"table\":\"custinfo\",\"column\":\"cust_shipform_id\",\"columnshort\":\"cust_shipform_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"shipform_id\",\"deps\":[{\"table\":\"shipform\",\"column\":\"cust_shipform_id_shipform_name\",\"columnshort\":\"shipform_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"shipform\",\"column\":\"cust_shipform_id_shipform_report_id\",\"columnshort\":\"shipform_report_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"shipform\",\"column\":\"cust_shipform_id_shipform_report_name\",\"columnshort\":\"shipform_report_name\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Shipment Form\",\"display\":\"cust_shipform_id_shipform_name\"},{\"table\":\"custinfo\",\"column\":\"cust_shipvia\",\"columnshort\":\"cust_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship Via\"},{\"table\":\"custinfo\",\"column\":\"cust_creditstatus\",\"columnshort\":\"cust_creditstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Credit Status\"},{\"table\":\"custinfo\",\"column\":\"cust_comments\",\"columnshort\":\"cust_comments\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Comments\"},{\"table\":\"custinfo\",\"column\":\"cust_ffbillto\",\"columnshort\":\"cust_ffbillto\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"is ff Bill To\"},{\"table\":\"custinfo\",\"column\":\"cust_number\",\"columnshort\":\"cust_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer #\"},{\"table\":\"custinfo\",\"column\":\"cust_dateadded\",\"columnshort\":\"cust_dateadded\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Added\"},{\"table\":\"custinfo\",\"column\":\"cust_curr_id\",\"columnshort\":\"cust_curr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"curr_id\",\"deps\":[{\"table\":\"curr_symbol\",\"column\":\"cust_curr_id_curr_base\",\"columnshort\":\"curr_base\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_curr_id_curr_symbol\",\"columnshort\":\"curr_symbol\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_curr_id_curr_abbr\",\"columnshort\":\"curr_abbr\",\"ctype\":\"varchar\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Currency\",\"display\":\"cust_curr_id_curr_symbol\"},{\"table\":\"custinfo\",\"column\":\"cust_creditlmt_curr_id\",\"columnshort\":\"cust_creditlmt_curr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"curr_id\",\"deps\":[{\"table\":\"curr_symbol\",\"column\":\"cust_creditlmt_curr_id_curr_base\",\"columnshort\":\"curr_base\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_creditlmt_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_creditlmt_curr_id_curr_symbol\",\"columnshort\":\"curr_symbol\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cust_creditlmt_curr_id_curr_abbr\",\"columnshort\":\"curr_abbr\",\"ctype\":\"varchar\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Credit Limit Currency\",\"display\":\"cust_creditlmt_curr_id_curr_symbol\"},{\"table\":\"custinfo\",\"column\":\"cust_cntct_id\",\"columnshort\":\"cust_cntct_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"cntct_id\",\"deps\":[{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_crmacct_id\",\"columnshort\":\"cntct_crmacct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_addr_id\",\"columnshort\":\"cntct_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_first_name\",\"columnshort\":\"cntct_first_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_last_name\",\"columnshort\":\"cntct_last_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_honorific\",\"columnshort\":\"cntct_honorific\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_initials\",\"columnshort\":\"cntct_initials\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_active\",\"columnshort\":\"cntct_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_fax\",\"columnshort\":\"cntct_fax\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_email\",\"columnshort\":\"cntct_email\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_webaddr\",\"columnshort\":\"cntct_webaddr\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_notes\",\"columnshort\":\"cntct_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_title\",\"columnshort\":\"cntct_title\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_number\",\"columnshort\":\"cntct_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_middle\",\"columnshort\":\"cntct_middle\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_suffix\",\"columnshort\":\"cntct_suffix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_owner_username\",\"columnshort\":\"cntct_owner_username\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_cntct_id_cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Contact\",\"display\":\"cust_cntct_id_cntct_name\"},{\"table\":\"custinfo\",\"column\":\"cust_corrcntct_id\",\"columnshort\":\"cust_corrcntct_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"cntct_id\",\"deps\":[{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_crmacct_id\",\"columnshort\":\"cntct_crmacct_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_addr_id\",\"columnshort\":\"cntct_addr_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_first_name\",\"columnshort\":\"cntct_first_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_last_name\",\"columnshort\":\"cntct_last_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_honorific\",\"columnshort\":\"cntct_honorific\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_initials\",\"columnshort\":\"cntct_initials\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_active\",\"columnshort\":\"cntct_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_fax\",\"columnshort\":\"cntct_fax\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_email\",\"columnshort\":\"cntct_email\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_webaddr\",\"columnshort\":\"cntct_webaddr\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_notes\",\"columnshort\":\"cntct_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_title\",\"columnshort\":\"cntct_title\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_number\",\"columnshort\":\"cntct_number\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_middle\",\"columnshort\":\"cntct_middle\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_suffix\",\"columnshort\":\"cntct_suffix\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_owner_username\",\"columnshort\":\"cntct_owner_username\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"cntct\",\"column\":\"cust_corrcntct_id_cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Corr? Contact\",\"display\":\"cust_corrcntct_id_cntct_name\"},{\"table\":\"custinfo\",\"column\":\"cust_taxzone_id\",\"columnshort\":\"cust_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"taxzone_id\",\"deps\":[{\"table\":\"taxzone\",\"column\":\"cust_taxzone_id_taxzone_code\",\"columnshort\":\"taxzone_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"taxzone\",\"column\":\"cust_taxzone_id_taxzone_descrip\",\"columnshort\":\"taxzone_descrip\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Tax Zone\",\"display\":\"cust_taxzone_id_taxzone_descrip\"}],\"cols_ex\":[\"cust_custtype_id_custtype_descrip\",\"cust_salesrep_id_salesrep_name\",\"cust_terms_id_terms_descrip\",\"cust_shipform_id_shipform_name\",\"cust_curr_id_curr_symbol\",\"cust_creditlmt_curr_id_curr_symbol\",\"cust_cntct_id_cntct_name\",\"cust_corrcntct_id_cntct_name\",\"cust_taxzone_id_taxzone_descrip\"],\"table\":\"custinfo\",\"xtype\":\"LayoutDialog\",\"|xns\":\"Roo\"}",
+            "closable": false,
+            "collapsible": false,
+            "height": 640,
+            "modal": true,
+            "resizable": true,
+            "title": "Customer Information",
+            "width": 900,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center",
+                    "alwaysShowTabs": true,
+                    "tabPosition": "top",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "Toolbar",
+                            "*prop": "toolbar",
+                            "items": [
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n    var cid = _this.form.findField('cust_id').getValue();\n    if(!cid){\n        Roo.Msg.alert('Error','please save the customer first');\n        return;\n    }\n    \n    Pman.Dialog.XtupleCustomerCode.show({cust_id : cid}, function(res){\n        _this.form.reset();\n       _this.form.fireEvent('actioncomplete', _this.form,  { type: 'setdata', data: {cust_id : res.cust_id} });\n    \n    });\n    \n}"
+                                    },
+                                    "text": "Change Customer Code",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "background": false,
+                    "region": "center",
+                    "title": "Details",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "*prop": "east",
+                                    "width": 300,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "region": "center",
+                                    "xtype": "ContentPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n    \n        _this.dialog.layout.getRegion('center').showPanel(0);\n    \n        if (_this.data.cust_id) {\n           this.load({ method: 'GET', params: { '_id' : _this.data.cust_id, '_with_char' : true }});\n           return;\n       } \n       this.findField('cust_active').setValue(true);\n      _this.grid.ds.load({});\n      _this.dialog.setTitle(\"New Customer\");\n\n      \n      \n       return;\n    }\n    if (action.type == 'load') {\n    \n          _this.dialog.setTitle(\"Edit Customer (\" + _this.data.cust_id +\") \" + _this.form.findField('cust_name').getValue() );\n    \n        _this.grid.ds.load({});\n        \n        \n        return;\n    }\n    if (action.type =='submit') {\n        \n        \n        if (_this.data.cust_id > 0 ) {\n            \n            \n            _this.dialog.hide();\n        \n             if (_this.callback) {\n                _this.callback.call(_this, _this.form.getValues());\n             }\n             _this.form.reset();\n             return;\n         }\n         // carry on editing.. and set data..\n\n         _this.data.cust_id = action.result.data.cust_id;\n         _this.form.fireEvent('actioncomplete', \n                _this.form,  { type: 'setdata', data: _this.data });\n         \n         \n    }\n}\n",
+                                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                                            },
+                                            "method": "POST",
+                                            "style": "margin:10px;",
+                                            "xtype": "Form",
+                                            "|url": "baseURL + '/Roo/custinfo.php'",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "legend": "Basic Details",
+                                                    "style": "width:460px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "keyup": "function (_self, e)\n{\n    if (!(_this.form.findField('cust_id').getValue() * 1)) {\n    \n        _this.form.findField('cust_number').setValue(this.getValue().replace(/[^a-z0-9]/ig, '').toUpperCase());\n    \n    }\n}"
+                                                            },
+                                                            "fieldLabel": "Name",
+                                                            "name": "cust_name",
+                                                            "width": 300,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "Row",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Customer #",
+                                                                    "name": "cust_number",
+                                                                    "readOnly": true,
+                                                                    "width": 150,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "allowBlank": true,
+                                                                    "displayField": "charopt_value",
+                                                                    "editable": false,
+                                                                    "emptyText": "",
+                                                                    "fieldLabel": "BG Company",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "cust_char_internalcompany",
+                                                                    "listWidth": 250,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "cust_char_internalcompany",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select charopt",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charopt_value}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "charopt_value",
+                                                                    "width": 70,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.charopt_char_id_char_name = 'INTERNALCOMPANY';\n    o.params['!charopt_value'] = baseURL.split('/').pop().split('.').shift();\n    \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "method": "GET",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "|url": "baseURL + '/Roo/charopt.php'"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "id": "id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"charopt_value\",\"type\":\"string\"}]"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Active",
+                                                                    "|inputValue": "true",
+                                                                    "name": "cust_active",
+                                                                    "valueOff": 0,
+                                                                    "width": 100,
+                                                                    "xtype": "Checkbox",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "labelAlign": "right",
+                                                                    "labelWidth": 50,
+                                                                    "xtype": "Row",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "allowBlank": false,
+                                                                            "displayField": "custtype_descrip",
+                                                                            "editable": false,
+                                                                            "emptyText": "Select Type",
+                                                                            "fieldLabel": "Type",
+                                                                            "forceSelection": true,
+                                                                            "hiddenName": "cust_custtype_id",
+                                                                            "listWidth": 400,
+                                                                            "loadingText": "Searching...",
+                                                                            "minChars": 2,
+                                                                            "name": "cust_custtype_id_custtype_descrip",
+                                                                            "pageSize": 20,
+                                                                            "qtip": "Select custtype",
+                                                                            "queryParam": "q[cust_descript]",
+                                                                            "selectOnFocus": true,
+                                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{custtype_code}</b> {custtype_descrip}</div>",
+                                                                            "triggerAction": "all",
+                                                                            "typeAhead": true,
+                                                                            "valueField": "custtype_id",
+                                                                            "width": 160,
+                                                                            "xtype": "ComboBox",
+                                                                            "|xns": "Roo.form",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "store",
+                                                                                    "xtype": "Store",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "remoteSort": true,
+                                                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                                                    "listeners": {
+                                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                                    },
+                                                                                    "items": [
+                                                                                        {
+                                                                                            "*prop": "proxy",
+                                                                                            "xtype": "HttpProxy",
+                                                                                            "method": "GET",
+                                                                                            "|xns": "Roo.data",
+                                                                                            "|url": "baseURL + '/Roo/custtype.php'"
+                                                                                        },
+                                                                                        {
+                                                                                            "*prop": "reader",
+                                                                                            "xtype": "JsonReader",
+                                                                                            "|xns": "Roo.data",
+                                                                                            "id": "id",
+                                                                                            "root": "data",
+                                                                                            "totalProperty": "total",
+                                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"custtype_code\",\"type\":\"string\"}]"
+                                                                                        }
+                                                                                    ]
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "fieldLabel": "AU POST #",
+                                                            "name": "cust_char_au_post_accno",
+                                                            "width": 150,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": true,
+                                                            "displayField": "charopt_value",
+                                                            "editable": false,
+                                                            "emptyText": "",
+                                                            "fieldLabel": "Forecast Type",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cust_char_salesforecast",
+                                                            "listWidth": 250,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cust_char_salesforecast",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select charopt",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charopt_value}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "charopt_value",
+                                                            "width": 150,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.charopt_char_id_char_name = 'SALESFORECAST';\n    \n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/charopt.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"charopt_value\",\"type\":\"string\"}]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Comments",
+                                                            "height": 50,
+                                                            "name": "cust_comments",
+                                                            "width": 300,
+                                                            "xtype": "TextArea",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "curr_symbol",
+                                                            "editable": false,
+                                                            "emptyText": "Select curr_symbol",
+                                                            "fieldLabel": "Currency",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cust_curr_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cust_curr_id_curr_symbol",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select curr_symbol",
+                                                            "queryParam": "query[curr_symbol]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_symbol}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "curr_id",
+                                                            "width": 100,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "|xns": "Roo.data",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                                                    "xtype": "Store",
+                                                                    "remoteSort": true,
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "curr_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "ComboBox",
+                                                            "allowBlank": false,
+                                                            "editable": false,
+                                                            "emptyText": "Select taxzone",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select taxzone",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 300,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxzone_descrip}</b> </div>",
+                                                            "queryParam": "query[taxzone_descrip]",
+                                                            "fieldLabel": "Tax Zone",
+                                                            "valueField": "taxzone_id",
+                                                            "displayField": "taxzone_descrip",
+                                                            "hiddenName": "cust_taxzone_id",
+                                                            "name": "cust_taxzone_id_taxzone_descrip",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "|xns": "Roo.data",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'taxzone_descrip' }",
+                                                                    "xtype": "Store",
+                                                                    "remoteSort": true,
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/taxzone.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "taxzone_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"taxzone_id\",\"type\":\"int\"},\"taxzone_descrip\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "ComboBox",
+                                                            "allowBlank": false,
+                                                            "editable": false,
+                                                            "emptyText": "Select salesrep",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select salesrep",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 300,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                                            "queryParam": "query[salesrep_name]",
+                                                            "fieldLabel": "Sales Rep",
+                                                            "valueField": "salesrep_id",
+                                                            "displayField": "salesrep_name",
+                                                            "hiddenName": "cust_salesrep_id",
+                                                            "name": "cust_salesrep_id_salesrep_name",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "|xns": "Roo.data",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'salesrep_name' }",
+                                                                    "xtype": "Store",
+                                                                    "remoteSort": true,
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/salesrep.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "salesrep_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"},\"salesrep_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": true,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "ipshead_name",
+                                                            "editable": false,
+                                                            "emptyText": "Select price level",
+                                                            "fieldLabel": "Price Level",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "ipshead_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "ipshead_id_name",
+                                                            "pageSize": 50,
+                                                            "qtip": "Select ipshead",
+                                                            "queryParam": "q",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{ipshead_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "ipshead_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.ipshead_curr_id = _this.form.findField('cust_curr_id').getValue();\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'ipshead_id_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/ipshead.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"ipshead_name\",\"type\":\"string\"}]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "legend": "Financial",
+                                                    "style": "width:420px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "ComboBox",
+                                                            "allowBlank": false,
+                                                            "editable": false,
+                                                            "emptyText": "Select terms",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select terms",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 300,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{terms_descrip}</b> </div>",
+                                                            "queryParam": "query[terms_descrip]",
+                                                            "fieldLabel": "Terms",
+                                                            "valueField": "terms_id",
+                                                            "displayField": "terms_descrip",
+                                                            "hiddenName": "cust_terms_id",
+                                                            "name": "cust_terms_id_terms_descrip",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'terms_descrip' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/terms.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "terms_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"terms_id\",\"type\":\"int\"},\"terms_descrip\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form",
+                                                            "fieldLabel": "Credit Limit",
+                                                            "name": "cust_creditlmt",
+                                                            "width": 100,
+                                                            "align": "right"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "legend": "Shipping",
+                                                    "style": "width:420px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "ComboBox",
+                                                            "allowBlank": false,
+                                                            "editable": false,
+                                                            "emptyText": "Select shipform",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select shipform",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 300,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{shipform_name}</b> </div>",
+                                                            "queryParam": "query[shipform_name]",
+                                                            "fieldLabel": "Shipment Form",
+                                                            "valueField": "shipform_id",
+                                                            "displayField": "shipform_name",
+                                                            "hiddenName": "cust_shipform_id",
+                                                            "name": "cust_shipform_id_shipform_name",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'shipform_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/shipform.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "shipform_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"shipform_id\",\"type\":\"int\"},\"shipform_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form",
+                                                            "fieldLabel": "Ship Via",
+                                                            "name": "cust_shipvia",
+                                                            "width": 300
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "legend": "Reference",
+                                                    "style": "width:420px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "fieldLabel": "Date Added",
+                                                            "format": "Y-m-d",
+                                                            "name": "cust_dateadded",
+                                                            "readOnly": true,
+                                                            "width": 100,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "name": "cust_cntct_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cust_creditlmt_curr_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "shiplist",
+                                                    "xtype": "Hidden",
+                                                    "|update": "function() {\n     var ship = [];\n    _this.grid.ds.each(function(r) {\n        if (r.data.is_ship * 1) {\n            ship.push(r.data.cntct_id);\n        }\n    });\n    this.setValue(ship.join(','));\n}\n",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cust_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n}"
+                                    },
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line1\",\"columnshort\":\"addr_line1\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line2\",\"columnshort\":\"addr_line2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line3\",\"columnshort\":\"addr_line3\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_country\",\"columnshort\":\"addr_country\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"cntct_addr_id_addr_line1\"],\"table\":\"cntct\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "east",
+                                    "tableName": "cntct",
+                                    "title": "cntct",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.grid = this; \n\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n   \n    var d =this.getDataSource().getAt(rowIndex).data;\n    Pman.Dialog.XtupleContact.show( \n        {\n            cntct_id : d.cntct_id , \n            customer_id : _this.form.findField('cust_id').getValue()\n        } , function() {\n        _this.grid.ds.load({});\n    });\n}\n",
+                                                "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n\n       if (columnIndex > 1 ) {\n           return;\n       } \n       var d = this.ds.getAt(rowIndex);\n       var f = this.cm.getDataIndex(columnIndex);\n       \n       // toggle it..\n\n       d.set(f, d.data[f] * 1 ? 0 : 1);\n       \n         \n        if (f == 'is_main' && d.data[f] > 0 ) { // removed..\n            // set new main contact - remove old..\n            var cc = _this.form.findField('cust_cntct_id');\n            var old = cc.getValue() * 1;\n            if (old > 1) {\n                this.ds.each(function(r) {\n                    if (r.data.cntct_id == old) {\n                        r.set('is_main', 0);\n                    }\n                });\n            }\n            cc.setValue(d.data.cntct_id);\n        }\n        // sort out shipping.\n        _this.form.findField('shiplist').update();\n          \n       \n}"
+                                            },
+                                            "*prop": "grid",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line1\",\"columnshort\":\"addr_line1\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line2\",\"columnshort\":\"addr_line2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line3\",\"columnshort\":\"addr_line3\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_country\",\"columnshort\":\"addr_country\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"cntct_addr_id_addr_line1\"],\"table\":\"cntct\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "autoExpandColumn": "cntct_addr_id_addr_line1",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, options)\n{\n     options.params =  options.params || {};\n     options.params.limit = 99;\n    options.params._customer_id = _this.form.findField('cust_id').getValue() * 1;\n    if (options.params._customer_id < 1) {\n        this.removeAll();\n        _this.grid.view.el.mask(\"Save first\");\n        return false;\n    }\n    options.params._add_is_types = 1;\n    _this.grid.view.el.unmask();    \n}",
+                                                        "load": "function (_self, records, options)\n{\n     var cc = _this.form.findField('cust_cntct_id');\n     var old = cc.getValue() * 1;\n     if (old > 1) {\n        Roo.each(records,function(r) {\n            if (r.data.cntct_id == old) {\n                r.set('is_main',1);\n            }\n        });\n    }\n    (function() { \n         _this.form.findField('shiplist').update();\n     }).defer(50);\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'cntct_name', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|url": "baseURL + '/Roo/cntct.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            ".builderCfg": "{\"cols\":[{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line1\",\"columnshort\":\"addr_line1\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line2\",\"columnshort\":\"addr_line2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_line3\",\"columnshort\":\"addr_line3\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"addr\",\"column\":\"cntct_addr_id_addr_country\",\"columnshort\":\"addr_country\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone\",\"columnshort\":\"cntct_phone\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_phone2\",\"columnshort\":\"cntct_phone2\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cntct\",\"column\":\"cntct_name\",\"columnshort\":\"cntct_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"cntct_addr_id_addr_line1\"],\"table\":\"cntct\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'cntct_addr_id_addr_line1',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_addr_id_addr_line2',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_addr_id_addr_line3',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_addr_id_addr_country',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_phone2',\n        'type': 'string'\n    },\n    {\n        'name': 'cntct_name',\n        'type': 'string'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "sm",
+                                                    "singleSelect": true,
+                                                    "xtype": "RowSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "toolbar",
+                                                    "xtype": "Toolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "xtype": "Fill",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n       \n \n Pman.Dialog.XtupleQuickContact.show( \n        {\n             _id : 0,\n             customer_id : _this.form.findField('cust_id').getValue()\n        },\n        \n        function (data) {\n              _this.grid.ds.load({});\n        }\n    ); \n\n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    // will this work?\n     var sel = _this.grid.sm.getSelected();\n    if (!sel  || !sel.data.cntct_id) {\n        Roo.MessageBox.alert(\"Error\", \"Select a contact to delete\");\n        return;\n    }\n    new Pman.Request({\n        url : baseURL + '/Roo/cntct',\n        method : 'POST',\n        params : {\n            _delete : sel.data.cntct_id\n        },\n        success : function() \n        {\n            _this.grid.ds.load({});\n        }\n    });\n    \n    \n \n}\n        "
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Delete",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "is_main",
+                                                    "header": "Main",
+                                                    "width": 30,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n    return     '<img class=\"x-grid-check-icon' + \n                                        (v*1 ? '-checked' : '')  + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                                        \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "is_ship",
+                                                    "header": "Ship",
+                                                    "width": 30,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n// simple view of address:\n      return     '<img class=\"x-grid-check-icon' + \n                                        (v*1 ? '-checked' : '')  + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                                        \n    \n    \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "cntct_addr_id_addr_line1",
+                                                    "header": "Contact / Address",
+                                                    "width": 200,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n// simple view of address:\n\n    var add = [];\n    Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {\n        if (!r.data['cntct_addr_id_addr_' + k].length) {\n            return;\n        }\n        add.push(String.format(\"{0}\", r.data['cntct_addr_id_addr_' + k]));\n    \n    });\n\n    return String.format(\n        'Name: <B>{0}</B><br/>' + \n        'Phone: <B>{1}</B> / Mobile: <B>{2}</B><br/>' + \n        'Email: <a href=\"mailto:{3}\">{3}</a>' +         \n        (add.length  ? '<BR/>' : '')  + '<B>' + add.join('<BR/>') + '</B>',\n    \n        r.data.cntct_name,\n        r.data.cntct_phone,\n        r.data.cntct_phone2,\n        \n        r.data.cntct_email\n    );\n    \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.hpanel = this;\n    if (_this.hgrid) {\n        _this.hgrid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "cohist",
+                    "title": "History",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.hgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.hpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_descrip1",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n\n  \n    Roo.apply(o.params, {\n        _group : 'salesHistory',\n        _name : 'detail',\n        'cust_id:number' : _this.form.findField('cust_id').getValue(),\n        'credit:text' : 'credit',\n        'return:text' : 'return',\n        'includeFormatted:int' :  1,\n        'startDate:text' : _this.dateFrom.getValue(),\n        'endDate:text' :  _this.dateTo.getValue()\n    });\n    \n    \n    \n}",
+                                        "load": "function (_self, records, options)\n{\n    function setText(str) {\n    \n        _this.hgrid.footer.el.select('.sales-footer-text', \n                true).first().dom.innerHTML = str;\n    }\n    \n    \n    if (!records.length) {\n        //_this.footertext.setText('');\n        Roo.log(\"no records\");\n        setText('');\n        return;\n    }\n    new Pman.Request({\n        method : 'GET',\n        url : baseURL + '/Roo/cohist',\n        params : {\n            _sums : 1,\n            \n            cust_id : _this.form.findField('cust_id').getValue(),\n            startDate : _this.dateFrom.getValue(),\n            endDate :  _this.dateTo.getValue()\n        },\n        success : function(res) \n        {\n            setText(\"Total Orders : \" + parseInt(res.data[0].total_orders) + \n                    \"  Total Shipped : \" + parseInt(res.data[0].total_shipped) +                  \n                   \"   Total Value: \" + res.data[0].total_basecurr + \" \" +\n                    Roo.util.Format.number(res.data[0].total_value,2)\n            );\n        }\n    });\n    \n        \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'cohist_shipvia', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/metasql.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'cohist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_shipdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_ordernumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_orderdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_invcdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_qtyshipped',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_unitprice',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_billtoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_commissionpaid',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_unitcost',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_misc_type',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_misc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_doctype',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_promisedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_ponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_sequence',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_code',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_sys',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying Sales {0} - {1} of {2}",
+                                    "emptyMsg": "No cohist found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "text": "<span class=\"sales-footer-text\"></span>",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "text": "From",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "render": "function (_self)\n{\n  _this.dateFrom = _self;\n}"
+                                            },
+                                            "format": "d/M/Y",
+                                            "useIso": true,
+                                            "xtype": "DateField",
+                                            "|value": "(function() {return (new Date()).add(Date.MONTH, -3); })()",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "text": "To",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "render": "function (_self)\n{\n_this.dateTo = _self;\n}"
+                                            },
+                                            "format": "d/M/Y",
+                                            "useIso": true,
+                                            "xtype": "DateField",
+                                            "|value": "(function() {return (new Date()) })()",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    _this.hgrid.footer.onClick('first');\n}"
+                                            },
+                                            "text": "Refresh",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Fill"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid : _this.hgrid\n    });\n}"
+                                            },
+                                            "text": "Download",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cust_name",
+                                    "header": "Customer",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cohist_ordernumber",
+                                    "header": "Order",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invmonth",
+                                    "header": "Invoice Month",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n    \n    return String.format('{0}',v);\n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cohead_orderdate",
+                                    "header": "Invoice date",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cohist_invcdate",
+                                    "header": "Invoice date",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "cohist_invcnumber",
+                                    "header": "Invoice#",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item No.",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v   : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Description",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cohist_qtyshipped",
+                                    "header": "Qty",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return parseInt(v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "currabbr",
+                                    "header": "Currency",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v.split(/\\s+/)[0]); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cohist_unitprice",
+                                    "header": "Unit Price",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "extprice",
+                                    "header": "Ext Cost",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n     var bg_comp = _this.form.findField('cust_char_internalcompany').getValue();\n     var ctype  = _this.form.findField('cust_custtype_id').el.dom.value;\n     if (bg_comp.length && !ctype.match(/internal/i)) {\n        Roo.MessageBox.alert(\"Error\" ,\n            \"BG Company should only be set for internal companies\"\n        );\n        return;\n    }\n     \n     \n     \n     \n     \n    \n \n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleCustomer.js b/Pman.Dialog.XtupleCustomer.js
new file mode 100644 (file)
index 0000000..caf3d8a
--- /dev/null
@@ -0,0 +1,1661 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleCustomer = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 640,
+            modal : true,
+            resizable : true,
+            title : "Customer Information",
+            width : 900,
+            items : [
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    background : false,
+                    region : 'center',
+                    title : "Details",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'ContentPanel',
+                                xns: Roo,
+                                region : 'center',
+                                items : [
+                                    {
+                                        xtype: 'Form',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            actioncomplete : function(_self,action)
+                                            {
+                                                if (action.type == 'setdata') {
+                                                
+                                                    _this.dialog.layout.getRegion('center').showPanel(0);
+                                                
+                                                    if (_this.data.cust_id) {
+                                                       this.load({ method: 'GET', params: { '_id' : _this.data.cust_id, '_with_char' : true }});
+                                                       return;
+                                                   } 
+                                                   this.findField('cust_active').setValue(true);
+                                                  _this.grid.ds.load({});
+                                                  _this.dialog.setTitle("New Customer");
+                                            
+                                                  
+                                                  
+                                                   return;
+                                                }
+                                                if (action.type == 'load') {
+                                                
+                                                      _this.dialog.setTitle("Edit Customer (" + _this.data.cust_id +") " + _this.form.findField('cust_name').getValue() );
+                                                
+                                                    _this.grid.ds.load({});
+                                                    
+                                                    
+                                                    return;
+                                                }
+                                                if (action.type =='submit') {
+                                                    
+                                                    
+                                                    if (_this.data.cust_id > 0 ) {
+                                                        
+                                                        
+                                                        _this.dialog.hide();
+                                                    
+                                                         if (_this.callback) {
+                                                            _this.callback.call(_this, _this.form.getValues());
+                                                         }
+                                                         _this.form.reset();
+                                                         return;
+                                                     }
+                                                     // carry on editing.. and set data..
+                                            
+                                                     _this.data.cust_id = action.result.data.cust_id;
+                                                     _this.form.fireEvent('actioncomplete', 
+                                                            _this.form,  { type: 'setdata', data: _this.data });
+                                                     
+                                                     
+                                                }
+                                            },
+                                            rendered : function (form)
+                                            {
+                                                _this.form= form;
+                                            }
+                                        },
+                                        method : 'POST',
+                                        style : 'margin:10px;',
+                                        url : baseURL + '/Roo/custinfo.php',
+                                        items : [
+                                            {
+                                                xtype: 'FieldSet',
+                                                xns: Roo.form,
+                                                legend : "Basic Details",
+                                                style : 'width:460px',
+                                                items : [
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        listeners : {
+                                                            keyup : function (_self, e)
+                                                            {
+                                                                if (!(_this.form.findField('cust_id').getValue() * 1)) {
+                                                                
+                                                                    _this.form.findField('cust_number').setValue(this.getValue().replace(/[^a-z0-9]/ig, '').toUpperCase());
+                                                                
+                                                                }
+                                                            }
+                                                        },
+                                                        fieldLabel : 'Name',
+                                                        name : 'cust_name',
+                                                        width : 300
+                                                    },
+                                                    {
+                                                        xtype: 'Row',
+                                                        xns: Roo.form,
+                                                        items : [
+                                                            {
+                                                                xtype: 'TextField',
+                                                                xns: Roo.form,
+                                                                fieldLabel : 'Customer #',
+                                                                name : 'cust_number',
+                                                                readOnly : true,
+                                                                width : 150
+                                                            },
+                                                            {
+                                                                xtype: 'ComboBox',
+                                                                xns: Roo.form,
+                                                                allowBlank : true,
+                                                                displayField : 'charopt_value',
+                                                                editable : false,
+                                                                emptyText : "",
+                                                                fieldLabel : 'BG Company',
+                                                                forceSelection : true,
+                                                                hiddenName : 'cust_char_internalcompany',
+                                                                listWidth : 250,
+                                                                loadingText : "Searching...",
+                                                                minChars : 2,
+                                                                name : 'cust_char_internalcompany',
+                                                                pageSize : 20,
+                                                                qtip : "Select charopt",
+                                                                selectOnFocus : true,
+                                                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{charopt_value}</b> </div>',
+                                                                triggerAction : 'all',
+                                                                typeAhead : true,
+                                                                valueField : 'charopt_value',
+                                                                width : 70,
+                                                                store : {
+                                                                    xtype: 'Store',
+                                                                    xns: Roo.data,
+                                                                    listeners : {
+                                                                        beforeload : function (_self, o){
+                                                                            o.params = o.params || {};
+                                                                            // set more here
+                                                                            o.params.charopt_char_id_char_name = 'INTERNALCOMPANY';
+                                                                            o.params['!charopt_value'] = baseURL.split('/').pop().split('.').shift();
+                                                                            
+                                                                        }
+                                                                    },
+                                                                    remoteSort : true,
+                                                                    sortInfo : { direction : 'ASC', field: 'id' },
+                                                                    proxy : {
+                                                                        xtype: 'HttpProxy',
+                                                                        xns: Roo.data,
+                                                                        method : 'GET',
+                                                                        url : baseURL + '/Roo/charopt.php'
+                                                                    },
+                                                                    reader : {
+                                                                        xtype: 'JsonReader',
+                                                                        xns: Roo.data,
+                                                                        id : 'id',
+                                                                        root : 'data',
+                                                                        totalProperty : 'total',
+                                                                        fields : [{"name":"id","type":"int"},{"name":"charopt_value","type":"string"}]
+                                                                    }
+                                                                }
+                                                            }
+                                                        ]
+                                                    },
+                                                    {
+                                                        xtype: 'Row',
+                                                        xns: Roo.form,
+                                                        width : 500,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Checkbox',
+                                                                xns: Roo.form,
+                                                                fieldLabel : 'Active',
+                                                                inputValue : true,
+                                                                name : 'cust_active',
+                                                                valueOff : 0,
+                                                                width : 100
+                                                            },
+                                                            {
+                                                                xtype: 'Row',
+                                                                xns: Roo.form,
+                                                                labelAlign : 'right',
+                                                                labelWidth : 50,
+                                                                items : [
+                                                                    {
+                                                                        xtype: 'ComboBox',
+                                                                        xns: Roo.form,
+                                                                        allowBlank : false,
+                                                                        displayField : 'custtype_descrip',
+                                                                        editable : false,
+                                                                        emptyText : "Select Type",
+                                                                        fieldLabel : 'Type',
+                                                                        forceSelection : true,
+                                                                        hiddenName : 'cust_custtype_id',
+                                                                        listWidth : 400,
+                                                                        loadingText : "Searching...",
+                                                                        minChars : 2,
+                                                                        name : 'cust_custtype_id_custtype_descrip',
+                                                                        pageSize : 20,
+                                                                        qtip : "Select custtype",
+                                                                        queryParam : 'q[cust_descript]',
+                                                                        selectOnFocus : true,
+                                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{custtype_code}</b> {custtype_descrip}</div>',
+                                                                        triggerAction : 'all',
+                                                                        typeAhead : true,
+                                                                        valueField : 'custtype_id',
+                                                                        width : 160,
+                                                                        store : {
+                                                                            xtype: 'Store',
+                                                                            xns: Roo.data,
+                                                                            remoteSort : true,
+                                                                            sortInfo : { direction : 'ASC', field: 'id' },
+                                                                            listeners : {
+                                                                                beforeload : function (_self, o){
+                                                                                    o.params = o.params || {};
+                                                                                    // set more here
+                                                                                }
+                                                                            },
+                                                                            proxy : {
+                                                                                xtype: 'HttpProxy',
+                                                                                xns: Roo.data,
+                                                                                method : 'GET',
+                                                                                url : baseURL + '/Roo/custtype.php'
+                                                                            },
+                                                                            reader : {
+                                                                                xtype: 'JsonReader',
+                                                                                xns: Roo.data,
+                                                                                id : 'id',
+                                                                                root : 'data',
+                                                                                totalProperty : 'total',
+                                                                                fields : [{"name":"id","type":"int"},{"name":"custtype_code","type":"string"}]
+                                                                            }
+                                                                        }
+                                                                    }
+                                                                ]
+                                                            }
+                                                        ]
+                                                    },
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        fieldLabel : 'AU POST #',
+                                                        name : 'cust_char_au_post_accno',
+                                                        width : 150
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : true,
+                                                        displayField : 'charopt_value',
+                                                        editable : false,
+                                                        emptyText : "",
+                                                        fieldLabel : 'Forecast Type',
+                                                        forceSelection : true,
+                                                        hiddenName : 'cust_char_salesforecast',
+                                                        listWidth : 250,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        name : 'cust_char_salesforecast',
+                                                        pageSize : 20,
+                                                        qtip : "Select charopt",
+                                                        selectOnFocus : true,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{charopt_value}</b> </div>',
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        valueField : 'charopt_value',
+                                                        width : 150,
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                    o.params.charopt_char_id_char_name = 'SALESFORECAST';
+                                                                    
+                                                                }
+                                                            },
+                                                            remoteSort : true,
+                                                            sortInfo : { direction : 'ASC', field: 'id' },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/charopt.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"id","type":"int"},{"name":"charopt_value","type":"string"}]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'TextArea',
+                                                        xns: Roo.form,
+                                                        fieldLabel : 'Comments',
+                                                        height : 50,
+                                                        name : 'cust_comments',
+                                                        width : 300
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        displayField : 'curr_symbol',
+                                                        editable : false,
+                                                        emptyText : "Select curr_symbol",
+                                                        fieldLabel : 'Currency',
+                                                        forceSelection : true,
+                                                        hiddenName : 'cust_curr_id',
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        name : 'cust_curr_id_curr_symbol',
+                                                        pageSize : 20,
+                                                        qtip : "Select curr_symbol",
+                                                        queryParam : 'query[curr_symbol]',
+                                                        selectOnFocus : true,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_symbol}</b> </div>',
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        valueField : 'curr_id',
+                                                        width : 100,
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                                            remoteSort : true,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/curr_symbol.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'curr_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        editable : false,
+                                                        emptyText : "Select taxzone",
+                                                        forceSelection : true,
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        pageSize : 20,
+                                                        qtip : "Select taxzone",
+                                                        selectOnFocus : true,
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        width : 300,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxzone_descrip}</b> </div>',
+                                                        queryParam : 'query[taxzone_descrip]',
+                                                        fieldLabel : 'Tax Zone',
+                                                        valueField : 'taxzone_id',
+                                                        displayField : 'taxzone_descrip',
+                                                        hiddenName : 'cust_taxzone_id',
+                                                        name : 'cust_taxzone_id_taxzone_descrip',
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            sortInfo : { direction : 'ASC', field: 'taxzone_descrip' },
+                                                            remoteSort : true,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/taxzone.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'taxzone_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"taxzone_id","type":"int"},"taxzone_descrip"]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        editable : false,
+                                                        emptyText : "Select salesrep",
+                                                        forceSelection : true,
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        pageSize : 20,
+                                                        qtip : "Select salesrep",
+                                                        selectOnFocus : true,
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        width : 300,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                                                        queryParam : 'query[salesrep_name]',
+                                                        fieldLabel : 'Sales Rep',
+                                                        valueField : 'salesrep_id',
+                                                        displayField : 'salesrep_name',
+                                                        hiddenName : 'cust_salesrep_id',
+                                                        name : 'cust_salesrep_id_salesrep_name',
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            sortInfo : { direction : 'ASC', field: 'salesrep_name' },
+                                                            remoteSort : true,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/salesrep.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'salesrep_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"salesrep_id","type":"int"},"salesrep_name"]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : true,
+                                                        alwaysQuery : true,
+                                                        displayField : 'ipshead_name',
+                                                        editable : false,
+                                                        emptyText : "Select price level",
+                                                        fieldLabel : 'Price Level',
+                                                        forceSelection : true,
+                                                        hiddenName : 'ipshead_id',
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        name : 'ipshead_id_name',
+                                                        pageSize : 50,
+                                                        qtip : "Select ipshead",
+                                                        queryParam : 'q',
+                                                        selectOnFocus : true,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{ipshead_name}</b> </div>',
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        valueField : 'ipshead_id',
+                                                        width : 300,
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    o.params.ipshead_curr_id = _this.form.findField('cust_curr_id').getValue();
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            remoteSort : true,
+                                                            sortInfo : { direction : 'ASC', field: 'ipshead_id_name' },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/ipshead.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"id","type":"int"},{"name":"ipshead_name","type":"string"}]
+                                                            }
+                                                        }
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'FieldSet',
+                                                xns: Roo.form,
+                                                legend : "Financial",
+                                                style : 'width:420px',
+                                                items : [
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        editable : false,
+                                                        emptyText : "Select terms",
+                                                        forceSelection : true,
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        pageSize : 20,
+                                                        qtip : "Select terms",
+                                                        selectOnFocus : true,
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        width : 300,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{terms_descrip}</b> </div>',
+                                                        queryParam : 'query[terms_descrip]',
+                                                        fieldLabel : 'Terms',
+                                                        valueField : 'terms_id',
+                                                        displayField : 'terms_descrip',
+                                                        hiddenName : 'cust_terms_id',
+                                                        name : 'cust_terms_id_terms_descrip',
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            remoteSort : true,
+                                                            sortInfo : { direction : 'ASC', field: 'terms_descrip' },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/terms.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'terms_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"terms_id","type":"int"},"terms_descrip"]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'NumberField',
+                                                        xns: Roo.form,
+                                                        fieldLabel : 'Credit Limit',
+                                                        name : 'cust_creditlmt',
+                                                        width : 100,
+                                                        align : 'right'
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'FieldSet',
+                                                xns: Roo.form,
+                                                legend : "Shipping",
+                                                style : 'width:420px',
+                                                items : [
+                                                    {
+                                                        xtype: 'ComboBox',
+                                                        xns: Roo.form,
+                                                        allowBlank : false,
+                                                        editable : false,
+                                                        emptyText : "Select shipform",
+                                                        forceSelection : true,
+                                                        listWidth : 400,
+                                                        loadingText : "Searching...",
+                                                        minChars : 2,
+                                                        pageSize : 20,
+                                                        qtip : "Select shipform",
+                                                        selectOnFocus : true,
+                                                        triggerAction : 'all',
+                                                        typeAhead : true,
+                                                        width : 300,
+                                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{shipform_name}</b> </div>',
+                                                        queryParam : 'query[shipform_name]',
+                                                        fieldLabel : 'Shipment Form',
+                                                        valueField : 'shipform_id',
+                                                        displayField : 'shipform_name',
+                                                        hiddenName : 'cust_shipform_id',
+                                                        name : 'cust_shipform_id_shipform_name',
+                                                        store : {
+                                                            xtype: 'Store',
+                                                            xns: Roo.data,
+                                                            listeners : {
+                                                                beforeload : function (_self, o){
+                                                                    o.params = o.params || {};
+                                                                    // set more here
+                                                                }
+                                                            },
+                                                            remoteSort : true,
+                                                            sortInfo : { direction : 'ASC', field: 'shipform_name' },
+                                                            proxy : {
+                                                                xtype: 'HttpProxy',
+                                                                xns: Roo.data,
+                                                                method : 'GET',
+                                                                url : baseURL + '/Roo/shipform.php'
+                                                            },
+                                                            reader : {
+                                                                xtype: 'JsonReader',
+                                                                xns: Roo.data,
+                                                                id : 'shipform_id',
+                                                                root : 'data',
+                                                                totalProperty : 'total',
+                                                                fields : [{"name":"shipform_id","type":"int"},"shipform_name"]
+                                                            }
+                                                        }
+                                                    },
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        fieldLabel : 'Ship Via',
+                                                        name : 'cust_shipvia',
+                                                        width : 300
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'FieldSet',
+                                                xns: Roo.form,
+                                                legend : "Reference",
+                                                style : 'width:420px',
+                                                items : [
+                                                    {
+                                                        xtype: 'TextField',
+                                                        xns: Roo.form,
+                                                        fieldLabel : 'Date Added',
+                                                        format : 'Y-m-d',
+                                                        name : 'cust_dateadded',
+                                                        readOnly : true,
+                                                        width : 100
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cust_cntct_id'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cust_creditlmt_curr_id'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'shiplist',
+                                                update : function() {
+                                                     var ship = [];
+                                                    _this.grid.ds.each(function(r) {
+                                                        if (r.data.is_ship * 1) {
+                                                            ship.push(r.data.cntct_id);
+                                                        }
+                                                    });
+                                                    this.setValue(ship.join(','));
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cust_id'
+                                            }
+                                        ]
+                                    }
+                                ]
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.panel = this;
+                                        if (_this.grid) {
+                                            _this.grid.ds.load({});
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'east',
+                                tableName : 'cntct',
+                                title : "cntct",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.grid = this; 
+                                        
+                                            if (_this.panel.active) {
+                                               this.ds.load({});
+                                            }
+                                        },
+                                        rowdblclick : function (_self, rowIndex, e)
+                                        {
+                                           
+                                            var d =this.getDataSource().getAt(rowIndex).data;
+                                            Pman.Dialog.XtupleContact.show( 
+                                                {
+                                                    cntct_id : d.cntct_id , 
+                                                    customer_id : _this.form.findField('cust_id').getValue()
+                                                } , function() {
+                                                _this.grid.ds.load({});
+                                            });
+                                        },
+                                        cellclick : function (_self, rowIndex, columnIndex, e)
+                                        {
+                                        
+                                               if (columnIndex > 1 ) {
+                                                   return;
+                                               } 
+                                               var d = this.ds.getAt(rowIndex);
+                                               var f = this.cm.getDataIndex(columnIndex);
+                                               
+                                               // toggle it..
+                                        
+                                               d.set(f, d.data[f] * 1 ? 0 : 1);
+                                               
+                                                 
+                                                if (f == 'is_main' && d.data[f] > 0 ) { // removed..
+                                                    // set new main contact - remove old..
+                                                    var cc = _this.form.findField('cust_cntct_id');
+                                                    var old = cc.getValue() * 1;
+                                                    if (old > 1) {
+                                                        this.ds.each(function(r) {
+                                                            if (r.data.cntct_id == old) {
+                                                                r.set('is_main', 0);
+                                                            }
+                                                        });
+                                                    }
+                                                    cc.setValue(d.data.cntct_id);
+                                                }
+                                                // sort out shipping.
+                                                _this.form.findField('shiplist').update();
+                                                  
+                                               
+                                        }
+                                    },
+                                    autoExpandColumn : 'cntct_addr_id_addr_line1',
+                                    loadMask : true,
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, options)
+                                            {
+                                                 options.params =  options.params || {};
+                                                 options.params.limit = 99;
+                                                options.params._customer_id = _this.form.findField('cust_id').getValue() * 1;
+                                                if (options.params._customer_id < 1) {
+                                                    this.removeAll();
+                                                    _this.grid.view.el.mask("Save first");
+                                                    return false;
+                                                }
+                                                options.params._add_is_types = 1;
+                                                _this.grid.view.el.unmask();    
+                                            },
+                                            load : function (_self, records, options)
+                                            {
+                                                 var cc = _this.form.findField('cust_cntct_id');
+                                                 var old = cc.getValue() * 1;
+                                                 if (old > 1) {
+                                                    Roo.each(records,function(r) {
+                                                        if (r.data.cntct_id == old) {
+                                                            r.set('is_main',1);
+                                                        }
+                                                    });
+                                                }
+                                                (function() { 
+                                                     _this.form.findField('shiplist').update();
+                                                 }).defer(50);
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'cntct_name', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/cntct.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'cntct_addr_id_addr_line1',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_addr_id_addr_line2',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_addr_id_addr_line3',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_addr_id_addr_country',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_phone',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_phone2',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cntct_name',
+                                                    'type': 'string'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    sm : {
+                                        xtype: 'RowSelectionModel',
+                                        xns: Roo.grid,
+                                        singleSelect : true
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                           
+                                                     
+                                                     Pman.Dialog.XtupleQuickContact.show( 
+                                                            {
+                                                                 _id : 0,
+                                                                 customer_id : _this.form.findField('cust_id').getValue()
+                                                            },
+                                                            
+                                                            function (data) {
+                                                                  _this.grid.ds.load({});
+                                                            }
+                                                        ); 
+                                                    
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        // will this work?
+                                                         var sel = _this.grid.sm.getSelected();
+                                                        if (!sel  || !sel.data.cntct_id) {
+                                                            Roo.MessageBox.alert("Error", "Select a contact to delete");
+                                                            return;
+                                                        }
+                                                        new Pman.Request({
+                                                            url : baseURL + '/Roo/cntct',
+                                                            method : 'POST',
+                                                            params : {
+                                                                _delete : sel.data.cntct_id
+                                                            },
+                                                            success : function() 
+                                                            {
+                                                                _this.grid.ds.load({});
+                                                            }
+                                                        });
+                                                        
+                                                        
+                                                     
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Delete",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'is_main',
+                                            header : 'Main',
+                                            width : 30,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                return     '<img class="x-grid-check-icon' + 
+                                                                                    (v*1 ? '-checked' : '')  + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                                                    
+                                                
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'is_ship',
+                                            header : 'Ship',
+                                            width : 30,
+                                            renderer : function(v,x,r) { 
+                                            
+                                            // simple view of address:
+                                                  return     '<img class="x-grid-check-icon' + 
+                                                                                    (v*1 ? '-checked' : '')  + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                                                    
+                                                
+                                                
+                                                
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'cntct_addr_id_addr_line1',
+                                            header : 'Contact / Address',
+                                            width : 200,
+                                            renderer : function(v,x,r) { 
+                                            
+                                            // simple view of address:
+                                            
+                                                var add = [];
+                                                Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {
+                                                    if (!r.data['cntct_addr_id_addr_' + k].length) {
+                                                        return;
+                                                    }
+                                                    add.push(String.format("{0}", r.data['cntct_addr_id_addr_' + k]));
+                                                
+                                                });
+                                            
+                                                return String.format(
+                                                    'Name: <B>{0}</B><br/>' + 
+                                                    'Phone: <B>{1}</B> / Mobile: <B>{2}</B><br/>' + 
+                                                    'Email: <a href="mailto:{3}">{3}</a>' +         
+                                                    (add.length  ? '<BR/>' : '')  + '<B>' + add.join('<BR/>') + '</B>',
+                                                
+                                                    r.data.cntct_name,
+                                                    r.data.cntct_phone,
+                                                    r.data.cntct_phone2,
+                                                    
+                                                    r.data.cntct_email
+                                                );
+                                                
+                                                
+                                            }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        },
+                        east : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            width : 300
+                        }
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.hpanel = this;
+                            if (_this.hgrid) {
+                                _this.hgrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'cohist',
+                    title : "History",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.hgrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.hpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                
+                                  
+                                    Roo.apply(o.params, {
+                                        _group : 'salesHistory',
+                                        _name : 'detail',
+                                        'cust_id:number' : _this.form.findField('cust_id').getValue(),
+                                        'credit:text' : 'credit',
+                                        'return:text' : 'return',
+                                        'includeFormatted:int' :  1,
+                                        'startDate:text' : _this.dateFrom.getValue(),
+                                        'endDate:text' :  _this.dateTo.getValue()
+                                    });
+                                    
+                                    
+                                    
+                                },
+                                load : function (_self, records, options)
+                                {
+                                    function setText(str) {
+                                    
+                                        _this.hgrid.footer.el.select('.sales-footer-text', 
+                                                true).first().dom.innerHTML = str;
+                                    }
+                                    
+                                    
+                                    if (!records.length) {
+                                        //_this.footertext.setText('');
+                                        Roo.log("no records");
+                                        setText('');
+                                        return;
+                                    }
+                                    new Pman.Request({
+                                        method : 'GET',
+                                        url : baseURL + '/Roo/cohist',
+                                        params : {
+                                            _sums : 1,
+                                            
+                                            cust_id : _this.form.findField('cust_id').getValue(),
+                                            startDate : _this.dateFrom.getValue(),
+                                            endDate :  _this.dateTo.getValue()
+                                        },
+                                        success : function(res) 
+                                        {
+                                            setText("Total Orders : " + parseInt(res.data[0].total_orders) + 
+                                                    "  Total Shipped : " + parseInt(res.data[0].total_shipped) +                  
+                                                   "   Total Value: " + res.data[0].total_basecurr + " " +
+                                                    Roo.util.Format.number(res.data[0].total_value,2)
+                                            );
+                                        }
+                                    });
+                                    
+                                        
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'cohist_shipvia', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/metasql.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'cohist_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_cust_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_shipdate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'cohist_shipvia',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_ordernumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_orderdate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'cohist_invcnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_invcdate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'cohist_qtyshipped',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'cohist_unitprice',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'cohist_shipto_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_salesrep_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_duedate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'cohist_imported',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_billtoname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtoaddress1',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtoaddress2',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtoaddress3',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtocity',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtostate',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_billtozip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptoname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptoaddress1',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptoaddress2',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptoaddress3',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptocity',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptostate',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_shiptozip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_commission',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'cohist_commissionpaid',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_unitcost',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'cohist_misc_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_misc_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_misc_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_doctype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_promisedate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'cohist_ponumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_sequence',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_taxzone_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id_curr_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id_curr_base',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id_curr_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id_curr_symbol',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_curr_id_curr_abbr',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_taxzone_id_taxzone_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_taxzone_id_taxzone_code',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_taxzone_id_taxzone_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_taxtype_id_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'cohist_taxtype_id_taxtype_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_taxtype_id_taxtype_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'cohist_taxtype_id_taxtype_sys',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Displaying Sales {0} - {1} of {2}",
+                            emptyMsg : "No cohist found",
+                            pageSize : 25,
+                            items : [
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "<span class=\"sales-footer-text\"></span>"
+                                }
+                            ]
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "From"
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        render : function (_self)
+                                        {
+                                          _this.dateFrom = _self;
+                                        }
+                                    },
+                                    format : 'd/M/Y',
+                                    useIso : true,
+                                    value : (function() {return (new Date()).add(Date.MONTH, -3); })()
+                                },
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "To"
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        render : function (_self)
+                                        {
+                                        _this.dateTo = _self;
+                                        }
+                                    },
+                                    format : 'd/M/Y',
+                                    useIso : true,
+                                    value : (function() {return (new Date()) })()
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.hgrid.footer.onClick('first');
+                                        }
+                                    },
+                                    text : "Refresh"
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            new Pman.Download({
+                                                grid : _this.hgrid
+                                            });
+                                        }
+                                    },
+                                    text : "Download"
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cust_name',
+                                header : 'Customer',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cohist_ordernumber',
+                                header : 'Order',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invmonth',
+                                header : 'Invoice Month',
+                                width : 75,
+                                renderer : function(v) { 
+                                    
+                                    return String.format('{0}',v);
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cohead_orderdate',
+                                header : 'Invoice date',
+                                width : 75,
+                                renderer : function(v) { 
+                                    var d = Date.parseDate(v, 'Y-m-d');
+                                    return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cohist_invcdate',
+                                header : 'Invoice date',
+                                width : 75,
+                                renderer : function(v) { 
+                                    var d = Date.parseDate(v, 'Y-m-d');
+                                    return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'cohist_invcnumber',
+                                header : 'Invoice#',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item No.',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v ? v   : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Description',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cohist_qtyshipped',
+                                header : 'Qty',
+                                width : 70,
+                                renderer : function(v) { return parseInt(v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'currabbr',
+                                header : 'Currency',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v.split(/\s+/)[0]); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cohist_unitprice',
+                                header : 'Unit Price',
+                                width : 75,
+                                renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'extprice',
+                                header : 'Ext Cost',
+                                width : 75,
+                                renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                alwaysShowTabs : true,
+                tabPosition : 'top',
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    var cid = _this.form.findField('cust_id').getValue();
+                                    if(!cid){
+                                        Roo.Msg.alert('Error','please save the customer first');
+                                        return;
+                                    }
+                                    
+                                    Pman.Dialog.XtupleCustomerCode.show({cust_id : cid}, function(res){
+                                        _this.form.reset();
+                                       _this.form.fireEvent('actioncomplete', _this.form,  { type: 'setdata', data: {cust_id : res.cust_id} });
+                                    
+                                    });
+                                    
+                                }
+                            },
+                            text : "Change Customer Code"
+                        }
+                    ]
+                }
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                             var bg_comp = _this.form.findField('cust_char_internalcompany').getValue();
+                             var ctype  = _this.form.findField('cust_custtype_id').el.dom.value;
+                             if (bg_comp.length && !ctype.match(/internal/i)) {
+                                Roo.MessageBox.alert("Error" ,
+                                    "BG Company should only be set for internal companies"
+                                );
+                                return;
+                            }
+                             
+                             
+                             
+                             
+                             
+                            
+                         
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleCustomerCode.bjs b/Pman.Dialog.XtupleCustomerCode.bjs
new file mode 100644 (file)
index 0000000..9ae46f8
--- /dev/null
@@ -0,0 +1,80 @@
+{
+    "id": "roo-file-190",
+    "name": "Pman.Dialog.XtupleCustomerCode",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleCustomerCode.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 150,
+            "modal": true,
+            "resizable": false,
+            "title": "Eidt Customer Code",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/custinfo.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Customer Code",
+                                    "name": "cust_number",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cust_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleCustomerCode.js b/Pman.Dialog.XtupleCustomerCode.js
new file mode 100644 (file)
index 0000000..51f7030
--- /dev/null
@@ -0,0 +1,132 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleCustomerCode = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 150,
+            modal : true,
+            resizable : false,
+            title : "Eidt Customer Code",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/custinfo.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Customer Code',
+                                    name : 'cust_number',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cust_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                        
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleDiscountOfInvoice.bjs b/Pman.Dialog.XtupleDiscountOfInvoice.bjs
new file mode 100644 (file)
index 0000000..c8aa0ad
--- /dev/null
@@ -0,0 +1,82 @@
+{
+    "id": "roo-file-7",
+    "name": "Pman.Dialog.XtupleDiscountOfInvoice",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleDiscountOfInvoice.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n  _this.form.findField('discount').focus();\n}"
+            },
+            "closable": false,
+            "height": 150,
+            "modal": true,
+            "resizable": false,
+            "title": "% Discount to Offer",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}"
+                            },
+                            "labelWidth": 150,
+                            "xtype": "Form",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "allowDecimals": true,
+                                    "allowNegative": false,
+                                    "decimalPrecision": 2,
+                                    "fieldLabel": "% Discount to Offer.",
+                                    "name": "discount",
+                                    "width": 200,
+                                    "xtype": "NumberField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "invchead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   var data = _this.form.getFieldValues();\n   \n   if (data.invchead_id * 1 < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Missing invchead_id\");\n        return;\n   }\n   \n   if(data.discount > 100){\n        Roo.MessageBox.alert(\"Error\", \"Maximum of discount value is 100\");\n        return;\n   }\n   \n   var discount = 100 - data.discount;\n   \n   var params  = {\n        template: 'Shipping-Invoice-' + baseURL.split('/').pop().split('.').shift(),\n        filename : 'Shipping-Invoice-' + data.invchead_id,\n        'param[0]':   \"invchead_id:integer='\" + data.invchead_id + \"'\",\n        'param[1]':   \"discount:integer='\" + discount + \"'\"\n    };\n    \n   new Pman.Download({\n        url : baseURL + '/Xtuple/Print',\n        method : 'GET',\n        params : params,\n        success : function() {\n\n        }\n    })\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleDiscountOfInvoice.js b/Pman.Dialog.XtupleDiscountOfInvoice.js
new file mode 100644 (file)
index 0000000..ab945bc
--- /dev/null
@@ -0,0 +1,143 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleDiscountOfInvoice = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                  _this.form.findField('discount').focus();
+                }
+            },
+            closable : false,
+            height : 150,
+            modal : true,
+            resizable : false,
+            title : "% Discount to Offer",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                }
+                            },
+                            labelWidth : 150,
+                            items : [
+                                {
+                                    xtype: 'NumberField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    allowDecimals : true,
+                                    allowNegative : false,
+                                    decimalPrecision : 2,
+                                    fieldLabel : '% Discount to Offer.',
+                                    name : 'discount',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'invchead_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           var data = _this.form.getFieldValues();
+                           
+                           if (data.invchead_id * 1 < 1) {
+                                Roo.MessageBox.alert("Error", "Missing invchead_id");
+                                return;
+                           }
+                           
+                           if(data.discount > 100){
+                                Roo.MessageBox.alert("Error", "Maximum of discount value is 100");
+                                return;
+                           }
+                           
+                           var discount = 100 - data.discount;
+                           
+                           var params  = {
+                                template: 'Shipping-Invoice-' + baseURL.split('/').pop().split('.').shift(),
+                                filename : 'Shipping-Invoice-' + data.invchead_id,
+                                'param[0]':   "invchead_id:integer='" + data.invchead_id + "'",
+                                'param[1]':   "discount:integer='" + discount + "'"
+                            };
+                            
+                           new Pman.Download({
+                                url : baseURL + '/Xtuple/Print',
+                                method : 'GET',
+                                params : params,
+                                success : function() {
+                        
+                                }
+                            })
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleExpenses.bjs b/Pman.Dialog.XtupleExpenses.bjs
new file mode 100644 (file)
index 0000000..c72b011
--- /dev/null
@@ -0,0 +1,692 @@
+{
+    "id": "roo-file-6",
+    "name": "Pman.Dialog.XtupleExpenses",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleExpenses.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 640,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create expense Report",
+            "width": 900,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "*prop": "north",
+                    "height": 250,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    \n    var btns = ['postToManagement', 'postToAccounts','postToGL', 'postToStaff', 'saveBtn'];\n    var  showhide = function()\n    {\n        Roo.each(btns, function(b) {\n            _this[b].hide();\n        });\n        switch(_this.form.findField('expense_status').getValue()) {\n            case '':\n                _this['saveBtn'].show();\n                return; // do not show any button...\n            case 'Draft':            \n                _this['saveBtn'].show();\n                _this['postToManagement'].show();\n                break;\n                \n                \n            case 'Pending Management Approval':\n            case 'Pending Supervisor Approval': // old system..\n                // check if they are managmenet..\n                // eg. have to be in TIER2\n                if (!Pman.Login.inGroup('TIER2') && !Pman.Login.inGroup('TIER1') && \n                         !Pman.Login.inGroup('Administrators')) {\n                    return;\n                }\n                _this['postToAccounts'].show();\n                _this['postToStaff'].show(); \n                _this['saveBtn'].show();\n                break;\n            case 'Pending Accounting Approval':\n                if (!Pman.Login.inGroup('Administrators')) {\n                    return;\n                }\n            \n                // check if they are managmenet..\n                _this['postToGL'].show();\n                _this['postToStaff'].show();                \n                _this['saveBtn'].show();                \n                break;\n            \n        \n        }\n    }\n    \n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       if (_this.data.expense_id) {\n           this.load({ method: 'GET', params: { '_id' : _this.data.expense_id }});\n             \n           return;\n       }\n       showhide();\n       _this.grid.ds.load({});\n       return;\n    }\n    if (action.type == 'load') {\n    \n    \n        showhide();\n    \n    \n    \n       _this.grid.ds.load({});\n        return;\n    }\n    if (action.type =='submit') {\n        \n        \n        if (! (1 * _this.form.findField('expense_id').getValue()) ) {\n            Roo.log(\"fire event\");\n            _this.data = action.result.data;\n            this.fireEvent('actioncomplete', this,  { type: 'setdata', data: action.result.data });\n            return;\n        }\n        \n \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/expense.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "width": 400,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "legend": "Summary",
+                                            "style": "width:380px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Ref#",
+                                                    "name": "expense_number",
+                                                    "readOnly": true,
+                                                    "width": 200,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Due Date",
+                                                    "format": "Y-m-d",
+                                                    "name": "expense_trandate",
+                                                    "width": 100,
+                                                    "xtype": "DateField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Summary",
+                                                    "name": "expense_memo",
+                                                    "width": 200,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Status",
+                                                    "name": "expense_status",
+                                                    "readOnly": true,
+                                                    "width": 200,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelAlign": "top",
+                                            "style": "clear:both;float:left;",
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Comments / For Review etc.",
+                                                    "name": "expense_comments",
+                                                    "width": 400,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "width": 400,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "labelWidth": 50,
+                                            "legend": "Employee",
+                                            "style": "width:250px;margin-left:10px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Name",
+                                                    "name": "expense_emp_id_emp_name",
+                                                    "readOnly": true,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "legend": "Financial Details",
+                                            "style": "width:250px;margin-left:10px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Advance Paid",
+                                                    "name": "expense_advance",
+                                                    "width": 75,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Amount",
+                                                    "name": "expense_amount_ro",
+                                                    "readOnly": true,
+                                                    "width": 75,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Tax",
+                                                    "name": "expense_tax_ro",
+                                                    "readOnly": true,
+                                                    "width": 75,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Total",
+                                                    "name": "expense_total_ro",
+                                                    "readOnly": true,
+                                                    "width": 75,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "labelAlign": "top",
+                                                    "xtype": "Row",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": true,
+                                                            "displayField": "accnt_descrip",
+                                                            "editable": false,
+                                                            "emptyText": "Select accnt",
+                                                            "fieldLabel": "Paid from Bank Account (accounting only)",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "expense_accnt_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "expense_accnt_id_accnt_descrip",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select accnt",
+                                                            "queryParam": "",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{accnt_descrip}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "valueField": "accnt_id",
+                                                            "width": 250,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.accnt_subaccnttype_code =  'CA';\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'accnt_descrip' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/accnt.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"accnt_number\",\"type\":\"string\"}]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "base_curr_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "base_curr_name",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "def_expcat_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "def_expcat_descrip",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "expense_emp_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "expense_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "_post",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n      //  _this.grid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "expitem",
+                    "title": "expitem",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       //this.gi.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                                "afteredit": "function (e)\n{\n    \n    if (e.field == 'expitem_date') {\n        e.record.set('expitem_date', Date.parseDate(e.value, 'Y-m-d'));\n    \n    } \n    \n    e.record.commit();\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "expitem_memo",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, options)\n{\n    \n    options.params = options.param || {};\n    options.params.limit = 999;\n    _this.grid.view.el.unmask();\n    options.params.expitem_expense_id = _this.form.findField('expense_id').getValue() *1 ;\n   if (!    options.params.expitem_expense_id) {\n         Roo.log(\"no expense id yet\");\n        this.removeAll();\n        _this.grid.view.el.mask(\"Save First\");\n        return false;\n    }\n    \n}",
+                                        "update": "function (_self, record, operation)\n{\n    if (operation != 'commit') {\n        return;\n    }\n    var send = Roo.apply({}, record.data);\n    // fix date...\n    send.expitem_date = typeof(send.expitem_date) == 'object' ? send.expitem_date.format('Y-m-d') : send.expitem_date;\n    \n    \n    function updateTotals(){\n        var t = { expense_total_ro : 0 , expense_amount_ro : 0, expense_tax_ro : 0 }\n        _this.grid.ds.each(function(r) {\n            var fc_total = (r.data.expitem_tax * 1) + (r.data.expitem_amount_fc * 1);\n            if (!fc_total) {\n                return;\n            }\n            var base_total = r.data.expitem_total * 1;\n            var rate = base_total / fc_total;\n            t.expense_total_ro += base_total;\n            t.expense_amount_ro += (r.data.expitem_amount_fc * rate);\n            t.expense_tax_ro += (r.data.expitem_tax  * rate);\n        \n        });\n        t.expense_total_ro =         t.expense_total_ro.toFixed(2);\n        t.expense_amount_ro =        t.expense_amount_ro.toFixed(2);\n        t.expense_tax_ro = t.expense_tax_ro.toFixed(2);\n    \n        \n        _this.form.setValues(t);\n    }\n    \n    \n    new Pman.Request( {\n        method : 'POST' ,\n        url : baseURL + '/Roo/expitem',\n        params :send,\n        success : function(res) {\n           if (!record.data.expitem_id) {\n                record.set('expitem_id', res.data.expitem_id);\n           }\n           record.set('expitem_total', res.data.expitem_total);\n           updateTotals();\n        }\n    });\n    \n    \n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'expitem_row', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/expitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'expitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_expense_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_expcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_row',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'expitem_amount_fc',\n        'type': 'float'\n    },\n    {\n        'name': 'expitem_tax',\n        'type': 'float'\n    },\n    {\n        'name': 'expitem_total',\n        'type': 'float'\n    },\n    {\n        'name': 'expitem_date',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'expitem_is_billable',\n        'type': 'int'\n    },\n    {\n        'name': 'expitem_memo',\n        'type': 'string'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n   \n   \n \n   var grid = _this.grid;\n   var r = grid.getDataSource().reader.newRow({\n        expitem_id : 0,\n        expitem_expense_id : _this.form.findField('expense_id').getValue(),\n        expitem_row : grid.ds.getCount() + 1,\n        expitem_date : new Date(),\n        expitem_curr_id :           _this.form.findField('base_curr_id').getValue(),\n        expitem_curr_id_curr_name : _this.form.findField('base_curr_name').getValue(),\n        expitem_expcat_id :         _this.form.findField('def_expcat_id').getValue(),\n        expitem_expcat_id_expcat_descrip  : _this.form.findField('def_expcat_descrip').getValue(),\n        expitem_amount_tax : 0.0\n   \n   });\n       \n    grid.stopEditing();\n    var lr =   grid.ds.getCount()\n    grid.getDataSource().insert(lr, r); \n    grid.startEditing(lr, 1); \n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Add",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Fill"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n    var ce =  _this.grid.selModel.getSelectedCell();\n    if (!ce) {\n        Roo.MessageBox.alert(\"Error\", \"Select a line to delete\");\n        return;\n    }\n    var rec = _this.grid.ds.getAt(ce[0]);\n    if (!rec.data.expitem_id) {\n        _this.grid.ds.remove(rec);\n        return;\n    }\n    \n    \n    new Pman.Request({\n        mask : 'Deleting',\n        url : baseURL + '/Roo/expitem',\n        method : 'POST',\n        params : {\n            _delete : rec.data.expitem_id\n        },\n        success : function()\n        {\n            _this.grid.ds.remove(rec);            \n        }\n    });\n   \n   \n}\n        "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Delete",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "expitem_row",
+                                    "header": "Line#",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "expitem_date",
+                                    "header": "Date",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {\n    if (!v) {\n        return '<span style=\"color:red\">' + \"NO DATE\" + '</span>';\n    }\n\n     return String.format('{0}', typeof(v) == 'object' ? v.format('d/M/Y') : v); \n }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "format": "d/M/Y",
+                                                    "useIso": true,
+                                                    "xtype": "DateField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "expitem_expcat_id",
+                                    "header": "Category",
+                                    "width": 140,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}', r.data.expitem_expcat_id_expcat_descrip); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "expcat_descrip",
+                                                    "editable": false,
+                                                    "emptyText": "Select expcat",
+                                                    "fieldLabel": "expcat",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "expitem_expcat_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "expitem_expcat_id_expcat_descrip",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select expcat",
+                                                    "queryParam": "",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{expcat_descrip}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "expcat_id",
+                                                    "width": 300,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'expcat_descrip' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "xtype": "HttpProxy",
+                                                                    "method": "GET",
+                                                                    "|xns": "Roo.data",
+                                                                    "|url": "baseURL + '/Roo/expcat.php'"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "xtype": "JsonReader",
+                                                                    "|xns": "Roo.data",
+                                                                    "id": "id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"expcat_code\",\"type\":\"string\"}]"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "expitem_memo",
+                                    "header": "Description",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.form",
+                                                    "xtype": "TextField",
+                                                    "*prop": "field"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "expitem_curr_id",
+                                    "header": "Currency",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}', r.data.expitem_curr_id_curr_name); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "curr_name",
+                                                    "editable": false,
+                                                    "emptyText": "Select curr_symbol",
+                                                    "fieldLabel": "curr_symbol",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "expitem_curr_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "expitem_curr_id_curr_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select curr_symbol",
+                                                    "queryParam": "",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "curr_id",
+                                                    "width": 300,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "Store",
+                                                            "|xns": "Roo.data",
+                                                            "remoteSort": true,
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                            },
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "xtype": "HttpProxy",
+                                                                    "method": "GET",
+                                                                    "|xns": "Roo.data",
+                                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "xtype": "JsonReader",
+                                                                    "|xns": "Roo.data",
+                                                                    "id": "id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"curr_name\",\"type\":\"string\"}]"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "expitem_amount_fc",
+                                    "header": "Amount",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.form",
+                                                    "xtype": "NumberField",
+                                                    "*prop": "field"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "expitem_tax",
+                                    "header": "Tax",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.form",
+                                                    "xtype": "NumberField",
+                                                    "*prop": "field"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "expitem_total",
+                                    "header": "Base Total",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    if (!_this.form.findField('expense_id').getValue()) {\n        Roo.MessageBox.alert(\"Error\",\"You must save your expense report before printing/downloading\");\n        return;        \n    }\n    new Pman.Download({\n        url : baseURL + '/Roo/expense',\n        method : 'GET',\n        params : {\n            expense_id : _this.form.findField('expense_id').getValue(),\n            _asExcel : 1\n        }\n    });\n    Roo.MessageBox.alert(\"Notice\",\"Your report should be downloading now\");\n    \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Download/Print",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    _this.form.findField('expense_status').setValue('Pending Management Approval');\n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.postToManagement = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Post to Management",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n      _this.form.findField('expense_status').setValue('Pending Accounting Approval');\n \n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.postToAccounts = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Post to Accounts",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n \n    \n    \n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Post to General Ledger - this is very difficult to reverse so make sure it is correct\",\n        function(b) {\n            if (b!='yes') { \n                return;\n            }\n            _this.form.findField('_post').setValue(1);\n            _this.form.submit();\n        \n        }\n    );\n    \n    // do some checks?\n\n \n   // _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.postToGL = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Post to General Ledger",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n\n    if (!    _this.form.findField('expense_comments').getValue().length ) {\n        Roo.MessageBox.alert(\"Error\", \"Fill in a comment why it is getting rejected\");\n        return;\n    }\n     \n    _this.form.findField('expense_status').setValue('Draft');\n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.postToStaff = _self;\n    \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Reject / Require Clarification",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n \n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleExpenses.js b/Pman.Dialog.XtupleExpenses.js
new file mode 100644 (file)
index 0000000..bc095c8
--- /dev/null
@@ -0,0 +1,1016 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleExpenses = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 640,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create expense Report",
+            width : 900,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    
+                                    var btns = ['postToManagement', 'postToAccounts','postToGL', 'postToStaff', 'saveBtn'];
+                                    var  showhide = function()
+                                    {
+                                        Roo.each(btns, function(b) {
+                                            _this[b].hide();
+                                        });
+                                        switch(_this.form.findField('expense_status').getValue()) {
+                                            case '':
+                                                _this['saveBtn'].show();
+                                                return; // do not show any button...
+                                            case 'Draft':            
+                                                _this['saveBtn'].show();
+                                                _this['postToManagement'].show();
+                                                break;
+                                                
+                                                
+                                            case 'Pending Management Approval':
+                                            case 'Pending Supervisor Approval': // old system..
+                                                // check if they are managmenet..
+                                                // eg. have to be in TIER2
+                                                if (!Pman.Login.inGroup('TIER2') && !Pman.Login.inGroup('TIER1') && 
+                                                         !Pman.Login.inGroup('Administrators')) {
+                                                    return;
+                                                }
+                                                _this['postToAccounts'].show();
+                                                _this['postToStaff'].show(); 
+                                                _this['saveBtn'].show();
+                                                break;
+                                            case 'Pending Accounting Approval':
+                                                if (!Pman.Login.inGroup('Administrators')) {
+                                                    return;
+                                                }
+                                            
+                                                // check if they are managmenet..
+                                                _this['postToGL'].show();
+                                                _this['postToStaff'].show();                
+                                                _this['saveBtn'].show();                
+                                                break;
+                                            
+                                        
+                                        }
+                                    }
+                                    
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                       if (_this.data.expense_id) {
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.expense_id }});
+                                             
+                                           return;
+                                       }
+                                       showhide();
+                                       _this.grid.ds.load({});
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                    
+                                    
+                                        showhide();
+                                    
+                                    
+                                    
+                                       _this.grid.ds.load({});
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                        
+                                        
+                                        if (! (1 * _this.form.findField('expense_id').getValue()) ) {
+                                            Roo.log("fire event");
+                                            _this.data = action.result.data;
+                                            this.fireEvent('actioncomplete', this,  { type: 'setdata', data: action.result.data });
+                                            return;
+                                        }
+                                        
+                                 
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/expense.php',
+                            items : [
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : 400,
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Summary",
+                                            style : 'width:380px',
+                                            items : [
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Ref#',
+                                                    name : 'expense_number',
+                                                    readOnly : true,
+                                                    width : 200
+                                                },
+                                                {
+                                                    xtype: 'DateField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Due Date',
+                                                    format : 'Y-m-d',
+                                                    name : 'expense_trandate',
+                                                    width : 100
+                                                },
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Summary',
+                                                    name : 'expense_memo',
+                                                    width : 200
+                                                },
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Status',
+                                                    name : 'expense_status',
+                                                    readOnly : true,
+                                                    width : 200
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            labelAlign : 'top',
+                                            style : 'clear:both;float:left;',
+                                            items : [
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Comments / For Review etc.',
+                                                    name : 'expense_comments',
+                                                    width : 400
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : 400,
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            labelWidth : 50,
+                                            legend : "Employee",
+                                            style : 'width:250px;margin-left:10px',
+                                            items : [
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Name',
+                                                    name : 'expense_emp_id_emp_name',
+                                                    readOnly : true
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Financial Details",
+                                            style : 'width:250px;margin-left:10px',
+                                            items : [
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Advance Paid',
+                                                    name : 'expense_advance',
+                                                    width : 75
+                                                },
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Amount',
+                                                    name : 'expense_amount_ro',
+                                                    readOnly : true,
+                                                    width : 75
+                                                },
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Tax',
+                                                    name : 'expense_tax_ro',
+                                                    readOnly : true,
+                                                    width : 75
+                                                },
+                                                {
+                                                    xtype: 'TextField',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Total',
+                                                    name : 'expense_total_ro',
+                                                    readOnly : true,
+                                                    width : 75
+                                                },
+                                                {
+                                                    xtype: 'Row',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'top',
+                                                    items : [
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : true,
+                                                            displayField : 'accnt_descrip',
+                                                            editable : false,
+                                                            emptyText : "Select accnt",
+                                                            fieldLabel : 'Paid from Bank Account (accounting only)',
+                                                            forceSelection : true,
+                                                            hiddenName : 'expense_accnt_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'expense_accnt_id_accnt_descrip',
+                                                            pageSize : 20,
+                                                            qtip : "Select accnt",
+                                                            queryParam : '',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{accnt_descrip}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            valueField : 'accnt_id',
+                                                            width : 250,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                        o.params.accnt_subaccnttype_code =  'CA';
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'accnt_descrip' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/accnt.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"id","type":"int"},{"name":"accnt_number","type":"string"}]
+                                                                }
+                                                            }
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'base_curr_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'base_curr_name'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'def_expcat_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'def_expcat_descrip'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'expense_emp_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'expense_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : '_post'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            if (_this.grid) {
+                              //  _this.grid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'expitem',
+                    title : "expitem",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   //this.gi.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            },
+                            afteredit : function (e)
+                            {
+                                
+                                if (e.field == 'expitem_date') {
+                                    e.record.set('expitem_date', Date.parseDate(e.value, 'Y-m-d'));
+                                
+                                } 
+                                
+                                e.record.commit();
+                            }
+                        },
+                        autoExpandColumn : 'expitem_memo',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, options)
+                                {
+                                    
+                                    options.params = options.param || {};
+                                    options.params.limit = 999;
+                                    _this.grid.view.el.unmask();
+                                    options.params.expitem_expense_id = _this.form.findField('expense_id').getValue() *1 ;
+                                   if (!    options.params.expitem_expense_id) {
+                                         Roo.log("no expense id yet");
+                                        this.removeAll();
+                                        _this.grid.view.el.mask("Save First");
+                                        return false;
+                                    }
+                                    
+                                },
+                                update : function (_self, record, operation)
+                                {
+                                    if (operation != 'commit') {
+                                        return;
+                                    }
+                                    var send = Roo.apply({}, record.data);
+                                    // fix date...
+                                    send.expitem_date = typeof(send.expitem_date) == 'object' ? send.expitem_date.format('Y-m-d') : send.expitem_date;
+                                    
+                                    
+                                    function updateTotals(){
+                                        var t = { expense_total_ro : 0 , expense_amount_ro : 0, expense_tax_ro : 0 }
+                                        _this.grid.ds.each(function(r) {
+                                            var fc_total = (r.data.expitem_tax * 1) + (r.data.expitem_amount_fc * 1);
+                                            if (!fc_total) {
+                                                return;
+                                            }
+                                            var base_total = r.data.expitem_total * 1;
+                                            var rate = base_total / fc_total;
+                                            t.expense_total_ro += base_total;
+                                            t.expense_amount_ro += (r.data.expitem_amount_fc * rate);
+                                            t.expense_tax_ro += (r.data.expitem_tax  * rate);
+                                        
+                                        });
+                                        t.expense_total_ro =         t.expense_total_ro.toFixed(2);
+                                        t.expense_amount_ro =        t.expense_amount_ro.toFixed(2);
+                                        t.expense_tax_ro = t.expense_tax_ro.toFixed(2);
+                                    
+                                        
+                                        _this.form.setValues(t);
+                                    }
+                                    
+                                    
+                                    new Pman.Request( {
+                                        method : 'POST' ,
+                                        url : baseURL + '/Roo/expitem',
+                                        params :send,
+                                        success : function(res) {
+                                           if (!record.data.expitem_id) {
+                                                record.set('expitem_id', res.data.expitem_id);
+                                           }
+                                           record.set('expitem_total', res.data.expitem_total);
+                                           updateTotals();
+                                        }
+                                    });
+                                    
+                                    
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'expitem_row', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/expitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'expitem_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_expense_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_curr_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_expcat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_row',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_amount',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'expitem_amount_fc',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'expitem_tax',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'expitem_total',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'expitem_date',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'expitem_is_billable',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'expitem_memo',
+                                        'type': 'string'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                           
+                                           
+                                         
+                                           var grid = _this.grid;
+                                           var r = grid.getDataSource().reader.newRow({
+                                                expitem_id : 0,
+                                                expitem_expense_id : _this.form.findField('expense_id').getValue(),
+                                                expitem_row : grid.ds.getCount() + 1,
+                                                expitem_date : new Date(),
+                                                expitem_curr_id :           _this.form.findField('base_curr_id').getValue(),
+                                                expitem_curr_id_curr_name : _this.form.findField('base_curr_name').getValue(),
+                                                expitem_expcat_id :         _this.form.findField('def_expcat_id').getValue(),
+                                                expitem_expcat_id_expcat_descrip  : _this.form.findField('def_expcat_descrip').getValue(),
+                                                expitem_amount_tax : 0.0
+                                           
+                                           });
+                                               
+                                            grid.stopEditing();
+                                            var lr =   grid.ds.getCount()
+                                            grid.getDataSource().insert(lr, r); 
+                                            grid.startEditing(lr, 1); 
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Add",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                            var ce =  _this.grid.selModel.getSelectedCell();
+                                            if (!ce) {
+                                                Roo.MessageBox.alert("Error", "Select a line to delete");
+                                                return;
+                                            }
+                                            var rec = _this.grid.ds.getAt(ce[0]);
+                                            if (!rec.data.expitem_id) {
+                                                _this.grid.ds.remove(rec);
+                                                return;
+                                            }
+                                            
+                                            
+                                            new Pman.Request({
+                                                mask : 'Deleting',
+                                                url : baseURL + '/Roo/expitem',
+                                                method : 'POST',
+                                                params : {
+                                                    _delete : rec.data.expitem_id
+                                                },
+                                                success : function()
+                                                {
+                                                    _this.grid.ds.remove(rec);            
+                                                }
+                                            });
+                                           
+                                           
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Delete",
+                                    icon : rootURL + '/Pman/templates/images/trash.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'expitem_row',
+                                header : 'Line#',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'expitem_date',
+                                header : 'Date',
+                                width : 75,
+                                renderer : function(v) {
+                                    if (!v) {
+                                        return '<span style="color:red">' + "NO DATE" + '</span>';
+                                    }
+                                
+                                     return String.format('{0}', typeof(v) == 'object' ? v.format('d/M/Y') : v); 
+                                 },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        format : 'd/M/Y',
+                                        useIso : true
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'expitem_expcat_id',
+                                header : 'Category',
+                                width : 140,
+                                renderer : function(v,x,r) { return String.format('{0}', r.data.expitem_expcat_id_expcat_descrip); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        allowBlank : false,
+                                        displayField : 'expcat_descrip',
+                                        editable : false,
+                                        emptyText : "Select expcat",
+                                        fieldLabel : 'expcat',
+                                        forceSelection : true,
+                                        hiddenName : 'expitem_expcat_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'expitem_expcat_id_expcat_descrip',
+                                        pageSize : 20,
+                                        qtip : "Select expcat",
+                                        queryParam : '',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{expcat_descrip}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        valueField : 'expcat_id',
+                                        width : 300,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'expcat_descrip' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/expcat.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"id","type":"int"},{"name":"expcat_code","type":"string"}]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'expitem_memo',
+                                header : 'Description',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'TextField',
+                                        xns: Roo.form
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'expitem_curr_id',
+                                header : 'Currency',
+                                width : 75,
+                                renderer : function(v,x,r) { return String.format('{0}', r.data.expitem_curr_id_curr_name); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        allowBlank : false,
+                                        displayField : 'curr_name',
+                                        editable : false,
+                                        emptyText : "Select curr_symbol",
+                                        fieldLabel : 'curr_symbol',
+                                        forceSelection : true,
+                                        hiddenName : 'expitem_curr_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'expitem_curr_id_curr_name',
+                                        pageSize : 20,
+                                        qtip : "Select curr_symbol",
+                                        queryParam : '',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        valueField : 'curr_id',
+                                        width : 300,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'id' },
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                }
+                                            },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/curr_symbol.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"id","type":"int"},{"name":"curr_name","type":"string"}]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'expitem_amount_fc',
+                                header : 'Amount',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'expitem_tax',
+                                header : 'Tax',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'expitem_total',
+                                header : 'Base Total',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 250
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            if (!_this.form.findField('expense_id').getValue()) {
+                                Roo.MessageBox.alert("Error","You must save your expense report before printing/downloading");
+                                return;        
+                            }
+                            new Pman.Download({
+                                url : baseURL + '/Roo/expense',
+                                method : 'GET',
+                                params : {
+                                    expense_id : _this.form.findField('expense_id').getValue(),
+                                    _asExcel : 1
+                                }
+                            });
+                            Roo.MessageBox.alert("Notice","Your report should be downloading now");
+                            
+                        }
+                    },
+                    text : "Download/Print"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            _this.form.findField('expense_status').setValue('Pending Management Approval');
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.postToManagement = _self;
+                        }
+                    },
+                    text : "Post to Management"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                              _this.form.findField('expense_status').setValue('Pending Accounting Approval');
+                         
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.postToAccounts = _self;
+                        }
+                    },
+                    text : "Post to Accounts"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                         
+                            
+                            
+                            
+                            Roo.MessageBox.confirm("Confirm", "Post to General Ledger - this is very difficult to reverse so make sure it is correct",
+                                function(b) {
+                                    if (b!='yes') { 
+                                        return;
+                                    }
+                                    _this.form.findField('_post').setValue(1);
+                                    _this.form.submit();
+                                
+                                }
+                            );
+                            
+                            // do some checks?
+                        
+                         
+                           // _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.postToGL = _self;
+                        }
+                    },
+                    text : "Post to General Ledger"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                        
+                            if (!    _this.form.findField('expense_comments').getValue().length ) {
+                                Roo.MessageBox.alert("Error", "Fill in a comment why it is getting rejected");
+                                return;
+                            }
+                             
+                            _this.form.findField('expense_status').setValue('Draft');
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.postToStaff = _self;
+                            
+                        }
+                    },
+                    text : "Reject / Require Clarification"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                         
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleGLAccountNameEdit.bjs b/Pman.Dialog.XtupleGLAccountNameEdit.bjs
new file mode 100644 (file)
index 0000000..2795553
--- /dev/null
@@ -0,0 +1,97 @@
+{
+    "id": "roo-file-8",
+    "name": "Pman.Dialog.XtupleGLAccountNameEdit",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleGLAccountNameEdit.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 180,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit Account Name",
+            "width": 450,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if(_this.data.accnt_id * 1 >1){\n           _this.dialog.el.mask(\"Loading\");\n           this.load({ method: 'GET', params: { '_id' : _this.data.accnt_id }});\n       }\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "labelWidth": 150,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/Accnt.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Account Name",
+                                    "name": "accnt_descrip",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Alternative Code",
+                                    "name": "accnt_code_alt",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Alternative Description",
+                                    "name": "accnt_descrip_alt",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "accnt_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    \n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleGLAccountNameEdit.js b/Pman.Dialog.XtupleGLAccountNameEdit.js
new file mode 100644 (file)
index 0000000..3ada831
--- /dev/null
@@ -0,0 +1,151 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleGLAccountNameEdit = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 180,
+            modal : true,
+            resizable : false,
+            title : "Edit Account Name",
+            width : 450,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if(_this.data.accnt_id * 1 >1){
+                                           _this.dialog.el.mask("Loading");
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.accnt_id }});
+                                       }
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            labelWidth : 150,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/Accnt.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Account Name',
+                                    name : 'accnt_descrip',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Alternative Code',
+                                    name : 'accnt_code_alt',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Alternative Description',
+                                    name : 'accnt_descrip_alt',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'accnt_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleInvHistory.bjs b/Pman.Dialog.XtupleInvHistory.bjs
new file mode 100644 (file)
index 0000000..88136a8
--- /dev/null
@@ -0,0 +1,389 @@
+{
+    "id": "roo-file-9",
+    "name": "Pman.Dialog.XtupleInvHistory",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleInvHistory.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 500,
+            "modal": true,
+            "resizable": false,
+            "title": "View inventory history",
+            "width": 1000,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "*prop": "north",
+                    "height": 50,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});\n       _this.grid.footer.onClick('first');\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/invhist.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "width": 1000,
+                                    "xtype": "Row",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "specialkey": "function (_self, e)\n{\n\n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "fieldLabel": "Search Product",
+                                            "name": "search_name",
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "itemsite_item_id_item_number",
+                                            "editable": true,
+                                            "emptyText": "Select itemsite",
+                                            "fieldLabel": "Item",
+                                            "forceSelection": true,
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "itemsite_item_id_item_number",
+                                            "pageSize": 20,
+                                            "qtip": "Select itemsite",
+                                            "queryParam": "query[number]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "itemsite_item_id_item_number",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/itemsite.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"itemsite_abcclass\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "location_descrip",
+                                            "editable": true,
+                                            "emptyText": "Select location",
+                                            "fieldLabel": "location",
+                                            "forceSelection": true,
+                                            "hiddenName": "location_name",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "location_descrip",
+                                            "pageSize": 40,
+                                            "qtip": "Select location",
+                                            "queryParam": "query[location_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_descrip}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "location_name",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "invhist",
+                    "title": "invhist",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "invhist_comments",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n    if (!_this.form.findField('itemsite_item_id_item_number').getValue().length  && \n            !_this.form.findField('location_name').getValue().length\n            &&             !_this.form.findField('search_name').getValue().length ) {\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    o.params['query[item_number]'] = _this.form.findField('itemsite_item_id_item_number').getValue();\n    o.params['query[location_name]']   = _this.form.findField('location_name').getValue();\n    o.params['search[item]'] =     _this.form.findField('search_name').getValue();\n    \n    \n    o.params._with_item =1;\n    o.params._hide_void =1;\n    o.params._with_balance = 1;\n   \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'invhist_transdate,invdetail_id', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/invdetail.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_invqty',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_invuom',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_ordnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_docnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_qoh_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_qoh_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_unitcost',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_acct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_xfer_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_hasdetail',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_ordtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_analyze',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_user',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_created',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_value_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_value_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_series',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "xtype": "PagingToolbar",
+                                    "pageSize": 25,
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying invhist{0} - {1} of {2}",
+                                    "emptyMsg": "No invhist found",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_transdate",
+                                    "header": "Invhist transdate",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );\n    return String.format('{0}', vv ? vv.format('d/M/Y') : '');\n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_ordnumber",
+                                    "header": "Order#",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "SKU",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Descr.",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_docnumber",
+                                    "header": "doc#",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_transtype",
+                                    "header": "Type",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invhist_unitcost",
+                                    "header": " unitcost",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "location_name",
+                                    "header": "Location",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('<B>{0}</B>', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_qty",
+                                    "header": "Change",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_before_qty",
+                                    "header": "Opening Balance",
+                                    "width": 90,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_balance_qty",
+                                    "header": "Closing Balance",
+                                    "width": 85,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_comments",
+                                    "header": "Invhist comments",
+                                    "width": 150,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   Pman.Dialog.XtupleInvHistoryOld.show({\n        itemsite_item_id_item_number   : _this.data.itemsite_item_id_item_number,\n\n        location_name : _this.data.location_name,\n        location_descrip : _this.data.location_descrip,        \n        invhist_transdate : _this.data.invhist_transdate\n    }); \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "View (HK  data)",
+                    "xtype": "Button",
+                    "|hidden": "(function() {\n    return !!baseURL.match(/hk\\.php/);\n})()",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid : _this.grid\n    });\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Download",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Close",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleInvHistory.js b/Pman.Dialog.XtupleInvHistory.js
new file mode 100644 (file)
index 0000000..2f21ece
--- /dev/null
@@ -0,0 +1,585 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleInvHistory = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 500,
+            modal : true,
+            resizable : false,
+            title : "View inventory history",
+            width : 1000,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});
+                                       _this.grid.footer.onClick('first');
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/invhist.php',
+                            items : [
+                                {
+                                    xtype: 'Row',
+                                    xns: Roo.form,
+                                    width : 1000,
+                                    items : [
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                specialkey : function (_self, e)
+                                                {
+                                                
+                                                    _this.grid.footer.onClick('first');
+                                                }
+                                            },
+                                            fieldLabel : 'Search Product',
+                                            name : 'search_name'
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                select : function (combo, record, index)
+                                                {
+                                                  
+                                                 
+                                                   (function() { 
+                                                     if (_this.grid) {
+                                                        _this.grid.footer.onClick('first'); 
+                                                    }
+                                                     }).defer(100);
+                                                }
+                                            },
+                                            allowBlank : true,
+                                            displayField : 'itemsite_item_id_item_number',
+                                            editable : true,
+                                            emptyText : "Select itemsite",
+                                            fieldLabel : 'Item',
+                                            forceSelection : true,
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'itemsite_item_id_item_number',
+                                            pageSize : 20,
+                                            qtip : "Select itemsite",
+                                            queryParam : 'query[number]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'itemsite_item_id_item_number',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/itemsite.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"itemsite_abcclass","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                select : function (combo, record, index)
+                                                {
+                                                  
+                                                 
+                                                   (function() { 
+                                                     if (_this.grid) {
+                                                        _this.grid.footer.onClick('first'); 
+                                                    }
+                                                     }).defer(100);
+                                                }
+                                            },
+                                            allowBlank : true,
+                                            displayField : 'location_descrip',
+                                            editable : true,
+                                            emptyText : "Select location",
+                                            fieldLabel : 'location',
+                                            forceSelection : true,
+                                            hiddenName : 'location_name',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'location_descrip',
+                                            pageSize : 40,
+                                            qtip : "Select location",
+                                            queryParam : 'query[location_name]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_descrip}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'location_name',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/location.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                                }
+                                            }
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            if (_this.grid) {
+                                _this.grid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'invhist',
+                    title : "invhist",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'invhist_comments',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                    if (!_this.form.findField('itemsite_item_id_item_number').getValue().length  && 
+                                            !_this.form.findField('location_name').getValue().length
+                                            &&             !_this.form.findField('search_name').getValue().length ) {
+                                        _this.grid.ds.removeAll();
+                                        return false;
+                                    }
+                                    o.params['query[item_number]'] = _this.form.findField('itemsite_item_id_item_number').getValue();
+                                    o.params['query[location_name]']   = _this.form.findField('location_name').getValue();
+                                    o.params['search[item]'] =     _this.form.findField('search_name').getValue();
+                                    
+                                    
+                                    o.params._with_item =1;
+                                    o.params._hide_void =1;
+                                    o.params._with_balance = 1;
+                                   
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'invhist_transdate,invdetail_id', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/invdetail.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'invhist_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_transdate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'invhist_transtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_invqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_invuom',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_ordnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_docnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_qoh_before',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_qoh_after',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_unitcost',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_acct_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_xfer_warehous_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_posted',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_imported',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_hasdetail',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_ordtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_analyze',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_user',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_created',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'invhist_costmethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_value_before',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_value_after',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_series',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            pageSize : 25,
+                            displayInfo : true,
+                            displayMsg : "Displaying invhist{0} - {1} of {2}",
+                            emptyMsg : "No invhist found"
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_transdate',
+                                header : 'Invhist transdate',
+                                width : 75,
+                                renderer : function(v) { 
+                                    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );
+                                    return String.format('{0}', vv ? vv.format('d/M/Y') : '');
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_ordnumber',
+                                header : 'Order#',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'SKU',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Descr.',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_docnumber',
+                                header : 'doc#',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_transtype',
+                                header : 'Type',
+                                width : 50,
+                                renderer : function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invhist_unitcost',
+                                header : ' unitcost',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'location_name',
+                                header : 'Location',
+                                width : 100,
+                                renderer : function(v) { return String.format('<B>{0}</B>', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_qty',
+                                header : 'Change',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_before_qty',
+                                header : 'Opening Balance',
+                                width : 90,
+                                renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_balance_qty',
+                                header : 'Closing Balance',
+                                width : 85,
+                                renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_comments',
+                                header : 'Invhist comments',
+                                width : 150,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 50
+            },
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           Pman.Dialog.XtupleInvHistoryOld.show({
+                                itemsite_item_id_item_number   : _this.data.itemsite_item_id_item_number,
+                        
+                                location_name : _this.data.location_name,
+                                location_descrip : _this.data.location_descrip,        
+                                invhist_transdate : _this.data.invhist_transdate
+                            }); 
+                        }
+                    },
+                    text : "View (HK  data)",
+                    hidden : (function() {
+                        return !!baseURL.match(/hk\.php/);
+                    })()
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            new Pman.Download({
+                                grid : _this.grid
+                            });
+                        }
+                    },
+                    text : "Download"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Close"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleInvHistoryOld.bjs b/Pman.Dialog.XtupleInvHistoryOld.bjs
new file mode 100644 (file)
index 0000000..601991f
--- /dev/null
@@ -0,0 +1,362 @@
+{
+    "id": "roo-file-272",
+    "name": "Pman.Dialog.XtupleInvHistoryOld",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleInvHistoryOld.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 500,
+            "modal": true,
+            "resizable": false,
+            "title": "View inventory history - Hong Kong",
+            "width": 1000,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "*prop": "north",
+                    "height": 50,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});\n       _this.grid.footer.onClick('first');\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/invhist.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "width": 1000,
+                                    "xtype": "Row",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "itemsite_item_id_item_number",
+                                            "editable": true,
+                                            "emptyText": "Select itemsite",
+                                            "fieldLabel": "Item",
+                                            "forceSelection": true,
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "itemsite_item_id_item_number",
+                                            "pageSize": 20,
+                                            "qtip": "Select itemsite",
+                                            "queryParam": "query[number]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "itemsite_item_id_item_number",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Xtuple/Roo/itemsite.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"itemsite_abcclass\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "location_descrip",
+                                            "editable": true,
+                                            "emptyText": "Select location",
+                                            "fieldLabel": "location",
+                                            "forceSelection": true,
+                                            "hiddenName": "location_name",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "location_descrip",
+                                            "pageSize": 40,
+                                            "qtip": "Select location",
+                                            "queryParam": "query[location_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_descrip}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "location_name",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Xtuple/Roo/location.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "invhist",
+                    "title": "invhist",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "invhist_comments",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n    if (!_this.form.findField('itemsite_item_id_item_number').getValue().length \n             && !_this.form.findField('location_name').getValue().length) {\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    o.params['query[item_number]'] = _this.form.findField('itemsite_item_id_item_number').getValue();\n    o.params['query[location_name]']   = _this.form.findField('location_name').getValue();\n    o.params._with_item =1;\n        o.params._hide_void =1;\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'invhist_transdate,invdetail_id', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Xtuple/Roo/invdetail.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_invqty',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_invuom',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_ordnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_docnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_qoh_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_qoh_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_unitcost',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_acct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_xfer_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_hasdetail',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_ordtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_analyze',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_user',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_created',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_value_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_value_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_series',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "xtype": "PagingToolbar",
+                                    "pageSize": 25,
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying invhist{0} - {1} of {2}",
+                                    "emptyMsg": "No invhist found",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_transdate",
+                                    "header": "Invhist transdate",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );\n    return String.format('{0}', vv ? vv.format('d/M/Y') : '');\n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_ordnumber",
+                                    "header": "Order#",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_docnumber",
+                                    "header": "doc#",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invhist_transtype",
+                                    "header": "Type",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invhist_unitcost",
+                                    "header": "unitcost",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invfifo_unitcost",
+                                    "header": "fifocost",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "location_name",
+                                    "header": "Location",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('<B>{0}</B>', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_qty",
+                                    "header": "Change",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_bydate_qty",
+                                    "header": "Qty Before",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('<B>{0}</B>', parseInt(v)- parseInt(r.data.invdetail_qty)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invdetail_bydate_qty",
+                                    "header": "Qty after",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('<B>{0}</B>', parseInt( v)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "xtype": "ColumnModel",
+                                    "header": "Invhist comments",
+                                    "width": 200,
+                                    "dataIndex": "invhist_comments",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "*prop": "colModel[]"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid : _this.grid\n    });\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Download",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Close",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleInvHistoryOld.js b/Pman.Dialog.XtupleInvHistoryOld.js
new file mode 100644 (file)
index 0000000..75159da
--- /dev/null
@@ -0,0 +1,539 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleInvHistoryOld = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 500,
+            modal : true,
+            resizable : false,
+            title : "View inventory history - Hong Kong",
+            width : 1000,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});
+                                       _this.grid.footer.onClick('first');
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/invhist.php',
+                            items : [
+                                {
+                                    xtype: 'Row',
+                                    xns: Roo.form,
+                                    width : 1000,
+                                    items : [
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                select : function (combo, record, index)
+                                                {
+                                                  
+                                                 
+                                                   (function() { 
+                                                     if (_this.grid) {
+                                                        _this.grid.footer.onClick('first'); 
+                                                    }
+                                                     }).defer(100);
+                                                }
+                                            },
+                                            allowBlank : true,
+                                            displayField : 'itemsite_item_id_item_number',
+                                            editable : true,
+                                            emptyText : "Select itemsite",
+                                            fieldLabel : 'Item',
+                                            forceSelection : true,
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'itemsite_item_id_item_number',
+                                            pageSize : 20,
+                                            qtip : "Select itemsite",
+                                            queryParam : 'query[number]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'itemsite_item_id_item_number',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Xtuple/Roo/itemsite.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"itemsite_abcclass","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                select : function (combo, record, index)
+                                                {
+                                                  
+                                                 
+                                                   (function() { 
+                                                     if (_this.grid) {
+                                                        _this.grid.footer.onClick('first'); 
+                                                    }
+                                                     }).defer(100);
+                                                }
+                                            },
+                                            allowBlank : true,
+                                            displayField : 'location_descrip',
+                                            editable : true,
+                                            emptyText : "Select location",
+                                            fieldLabel : 'location',
+                                            forceSelection : true,
+                                            hiddenName : 'location_name',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'location_descrip',
+                                            pageSize : 40,
+                                            qtip : "Select location",
+                                            queryParam : 'query[location_name]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_descrip}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'location_name',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Xtuple/Roo/location.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                                }
+                                            }
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            if (_this.grid) {
+                                _this.grid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'invhist',
+                    title : "invhist",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'invhist_comments',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                    if (!_this.form.findField('itemsite_item_id_item_number').getValue().length 
+                                             && !_this.form.findField('location_name').getValue().length) {
+                                        _this.grid.ds.removeAll();
+                                        return false;
+                                    }
+                                    o.params['query[item_number]'] = _this.form.findField('itemsite_item_id_item_number').getValue();
+                                    o.params['query[location_name]']   = _this.form.findField('location_name').getValue();
+                                    o.params._with_item =1;
+                                        o.params._hide_void =1;
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'invhist_transdate,invdetail_id', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Xtuple/Roo/invdetail.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'invhist_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_transdate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'invhist_transtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_invqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_invuom',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_ordnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_docnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_qoh_before',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_qoh_after',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_unitcost',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_acct_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_xfer_warehous_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_posted',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_imported',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_hasdetail',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_ordtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_analyze',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invhist_user',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_created',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'invhist_costmethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invhist_value_before',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_value_after',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invhist_series',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            pageSize : 25,
+                            displayInfo : true,
+                            displayMsg : "Displaying invhist{0} - {1} of {2}",
+                            emptyMsg : "No invhist found"
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_transdate',
+                                header : 'Invhist transdate',
+                                width : 75,
+                                renderer : function(v) { 
+                                    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );
+                                    return String.format('{0}', vv ? vv.format('d/M/Y') : '');
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_ordnumber',
+                                header : 'Order#',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_docnumber',
+                                header : 'doc#',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invhist_transtype',
+                                header : 'Type',
+                                width : 50,
+                                renderer : function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invhist_unitcost',
+                                header : 'unitcost',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invfifo_unitcost',
+                                header : 'fifocost',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'location_name',
+                                header : 'Location',
+                                width : 100,
+                                renderer : function(v) { return String.format('<B>{0}</B>', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_qty',
+                                header : 'Change',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_bydate_qty',
+                                header : 'Qty Before',
+                                width : 75,
+                                renderer : function(v,x,r) { return String.format('<B>{0}</B>', parseInt(v)- parseInt(r.data.invdetail_qty)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invdetail_bydate_qty',
+                                header : 'Qty after',
+                                width : 75,
+                                renderer : function(v) { return String.format('<B>{0}</B>', parseInt( v)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                header : 'Invhist comments',
+                                width : 200,
+                                dataIndex : 'invhist_comments',
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 50
+            },
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            new Pman.Download({
+                                grid : _this.grid
+                            });
+                        }
+                    },
+                    text : "Download"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Close"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleInvc.bjs b/Pman.Dialog.XtupleInvc.bjs
new file mode 100644 (file)
index 0000000..7245ff4
--- /dev/null
@@ -0,0 +1,492 @@
+{
+    "id": "roo-file-9",
+    "name": "Pman.Dialog.XtupleInvc",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleInvc.bjs",
+    "items": [
+        {
+            "closable": true,
+            "collapsible": false,
+            "height": 600,
+            "modal": true,
+            "resizable": false,
+            "title": "View Invoice",
+            "width": 1000,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "*prop": "north",
+                    "height": 250,
+                    "split": true,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n   if (action.type == 'setdata') {\n        if (_this.data._id) {\n            this.load({ method: 'GET', params: { '_id' : _this.data._id }});\n           return;\n       }      \n       \n       \n       \n       _this.saveBtn.hide();\n            \n       \n       \n       \n    }\n    if (action.type == 'load') {\n        var d = action.result.data;\n        \n\n         _this.grid.ds.load({});\n        return;\n    }\n    if (action.type =='submit') {\n                \n        _this.dialog.hide();\n        return;    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/invchead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "width": 950,
+                                    "xtype": "Row",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "style": "float:left;",
+                                            "width": 300,
+                                            "xtype": "Column",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelWidth": 70,
+                                                    "legend": "Invoice Details",
+                                                    "style": "width:280px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "fieldLabel": "Invoiced",
+                                                            "format": "Y-m-d",
+                                                            "name": "invchead_invcdate",
+                                                            "width": 120,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Ordered",
+                                                            "format": "Y-m-d",
+                                                            "name": "invchead_orderdate",
+                                                            "width": 120,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Invoice#",
+                                                            "name": "invchead_invcnumber",
+                                                            "width": 120,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "PO#",
+                                                            "name": "invchead_ponumber",
+                                                            "width": 120,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Customer",
+                                                            "name": "cust_name",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "FOB",
+                                                            "name": "invchead_fob",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Shipvia",
+                                                            "name": "invchead_shipvia",
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "salesrep",
+                                                            "name": "invchead_salesrep_id",
+                                                            "width": 75,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Terms",
+                                                            "name": "invchead_terms_id",
+                                                            "width": 75,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "style": "margin-left:10px;float:left;",
+                                            "width": 370,
+                                            "xtype": "Column",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelAlign": "left",
+                                                    "labelWidth": 100,
+                                                    "legend": "Charges",
+                                                    "style": "width:350px",
+                                                    "xtype": "FieldSet",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "invc_curr_id",
+                                                            "editable": false,
+                                                            "emptyText": "Select curr_symbol",
+                                                            "fieldLabel": "Currency",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "invchead_curr_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "invchead_curr_id_curr_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select curr_symbol",
+                                                            "queryParam": "query[curr_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "id",
+                                                            "width": 220,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "xtype": "Store",
+                                                                    "|xns": "Roo.data",
+                                                                    "remoteSort": true,
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"curr_name\",\"type\":\"string\"}]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "right",
+                                                            "labelWidth": 250,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "style": "align:right;",
+                                                                    "fieldLabel": "Items Total",
+                                                                    "name": "invchead_invctotal",
+                                                                    "width": 75,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "right",
+                                                            "labelWidth": 250,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "style": "align:right;",
+                                                                    "fieldLabel": "Freight",
+                                                                    "name": "invchead_freight",
+                                                                    "width": 75,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 430,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Discount Description",
+                                                                    "name": "invchead_misc_descrip",
+                                                                    "width": 235,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "style": "align:right;",
+                                                                    "fieldLabel": "&nbsp;",
+                                                                    "name": "invchead_misc_amount",
+                                                                    "width": 75,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "right",
+                                                            "labelWidth": 250,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "style": "align:right;",
+                                                                    "fieldLabel": "Total",
+                                                                    "name": "invchead_total",
+                                                                    "width": 75,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "width": 430,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Payment Ref",
+                                                                    "name": "invchead_paymentref",
+                                                                    "width": 235,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "style": "align:right;",
+                                                                    "fieldLabel": "Paid",
+                                                                    "name": "invchead_payment",
+                                                                    "width": 75,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelAlign": "top",
+                                            "style": "margin-left:10px;float:left;",
+                                            "width": 250,
+                                            "xtype": "Column",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Invchead notes",
+                                                    "height": 60,
+                                                    "name": "invchead_notes",
+                                                    "width": 250,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "BillTo",
+                                                    "height": 60,
+                                                    "name": "invchead_billto",
+                                                    "width": 250,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "fieldLabel": "Shipto",
+                                                    "height": 60,
+                                                    "name": "invchead_shipto",
+                                                    "width": 250,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "invchead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "invchead_void",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "billitems",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n     \n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "invcitem",
+                    "title": "invcitem",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    \n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "invcitem_item_id_item_descrip1",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n        var id  = _this.form.findField('invchead_id').getValue();\n        if (!id){\n            return false;\n        }\n        o.params.invcitem_invchead_id = id;\n        o.params.limit = 999;\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'invcitem_linenumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/invcitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'invcitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_custpn',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_number',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_ordered',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_billed',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_custprice',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_price',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_salescat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_qty_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_qty_invuomratio',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_price_invuomratio',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_coitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_updateinv',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_taxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_taxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_taxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_taxtype_id_taxtype_sys',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_qty_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_qty_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_qty_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_qty_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_price_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_price_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_price_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_price_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_ordernumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_orderdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_printed',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_invcdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_ponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_name',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_address1',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_address2',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_address3',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_city',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_state',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_zipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_name',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_address1',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_address2',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_address3',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_city',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_state',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_zipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_misc_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_misc_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_payment',\n        'type': 'float'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_paymentref',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_billto_country',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipto_country',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_gldistdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_recurring',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_recurring_interval',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_recurring_type',\n        'type': 'string'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_recurring_until',\n        'type': 'date'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_recurring_invchead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_shipchrg_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invcitem_invchead_id_invchead_void',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invcitem_linenumber",
+                                    "header": "Line",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invcitem_item_id_item_number",
+                                    "header": "SKU#",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "invcitem_item_id_item_descrip1",
+                                    "header": "Description",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invcitem_price",
+                                    "header": "Price",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "invcitem_ordered",
+                                    "header": "Qty",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    var invchead_id = _this.form.findField('invchead_id').getValue();\n    if(invchead_id * 1 < 1){\n        Roo.MessageBox.alert(\"Error\", \"Error occur on getting the invchead_id\");\n        return;\n    }\n    new Pman.Download({\n        url : baseURL + '/Roo/invchead',\n        method : 'GET',\n        params : {\n            invchead_id : invchead_id,\n            _print : 1\n        },\n        success : function() {\n\n        }\n    })\n}"
+                    },
+                    "cls": "x-btn-text-icon",
+                    "*prop": "buttons[]",
+                    "text": "Print Invoice",
+                    "xtype": "Button",
+                    "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid : _this.grid\n    });\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Download items",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleInvc.js b/Pman.Dialog.XtupleInvc.js
new file mode 100644 (file)
index 0000000..0cb37c3
--- /dev/null
@@ -0,0 +1,922 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleInvc = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : true,
+            collapsible : false,
+            height : 600,
+            modal : true,
+            resizable : false,
+            title : "View Invoice",
+            width : 1000,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                   if (action.type == 'setdata') {
+                                        if (_this.data._id) {
+                                            this.load({ method: 'GET', params: { '_id' : _this.data._id }});
+                                           return;
+                                       }      
+                                       
+                                       
+                                       
+                                       _this.saveBtn.hide();
+                                            
+                                       
+                                       
+                                       
+                                    }
+                                    if (action.type == 'load') {
+                                        var d = action.result.data;
+                                        
+                                
+                                         _this.grid.ds.load({});
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                                
+                                        _this.dialog.hide();
+                                        return;    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/invchead.php',
+                            items : [
+                                {
+                                    xtype: 'Row',
+                                    xns: Roo.form,
+                                    width : 950,
+                                    items : [
+                                        {
+                                            xtype: 'Column',
+                                            xns: Roo.form,
+                                            style : 'float:left;',
+                                            width : 300,
+                                            items : [
+                                                {
+                                                    xtype: 'FieldSet',
+                                                    xns: Roo.form,
+                                                    labelWidth : 70,
+                                                    legend : "Invoice Details",
+                                                    style : 'width:280px',
+                                                    items : [
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Invoiced',
+                                                            format : 'Y-m-d',
+                                                            name : 'invchead_invcdate',
+                                                            width : 120
+                                                        },
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Ordered',
+                                                            format : 'Y-m-d',
+                                                            name : 'invchead_orderdate',
+                                                            width : 120
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Invoice#',
+                                                            name : 'invchead_invcnumber',
+                                                            width : 120
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'PO#',
+                                                            name : 'invchead_ponumber',
+                                                            width : 120
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Customer',
+                                                            name : 'cust_name',
+                                                            width : 200
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'FOB',
+                                                            name : 'invchead_fob',
+                                                            width : 200
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Shipvia',
+                                                            name : 'invchead_shipvia',
+                                                            width : 200
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'salesrep',
+                                                            name : 'invchead_salesrep_id',
+                                                            width : 75
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Terms',
+                                                            name : 'invchead_terms_id',
+                                                            width : 75
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Column',
+                                            xns: Roo.form,
+                                            style : 'margin-left:10px;float:left;',
+                                            width : 370,
+                                            items : [
+                                                {
+                                                    xtype: 'FieldSet',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'left',
+                                                    labelWidth : 100,
+                                                    legend : "Charges",
+                                                    style : 'width:350px',
+                                                    items : [
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            displayField : 'invc_curr_id',
+                                                            editable : false,
+                                                            emptyText : "Select curr_symbol",
+                                                            fieldLabel : 'Currency',
+                                                            forceSelection : true,
+                                                            hiddenName : 'invchead_curr_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'invchead_curr_id_curr_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select curr_symbol",
+                                                            queryParam : 'query[curr_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'id',
+                                                            width : 220,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                    }
+                                                                },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/curr_symbol.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"id","type":"int"},{"name":"curr_name","type":"string"}]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'right',
+                                                            labelWidth : 250,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    style : 'align:right;',
+                                                                    fieldLabel : 'Items Total',
+                                                                    name : 'invchead_invctotal',
+                                                                    width : 75
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'right',
+                                                            labelWidth : 250,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    style : 'align:right;',
+                                                                    fieldLabel : 'Freight',
+                                                                    name : 'invchead_freight',
+                                                                    width : 75
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 430,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    fieldLabel : 'Discount Description',
+                                                                    name : 'invchead_misc_descrip',
+                                                                    width : 235
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    style : 'align:right;',
+                                                                    fieldLabel : '&nbsp;',
+                                                                    name : 'invchead_misc_amount',
+                                                                    width : 75
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'right',
+                                                            labelWidth : 250,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    style : 'align:right;',
+                                                                    fieldLabel : 'Total',
+                                                                    name : 'invchead_total',
+                                                                    width : 75
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            width : 430,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    fieldLabel : 'Payment Ref',
+                                                                    name : 'invchead_paymentref',
+                                                                    width : 235
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    style : 'align:right;',
+                                                                    fieldLabel : 'Paid',
+                                                                    name : 'invchead_payment',
+                                                                    width : 75
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Column',
+                                            xns: Roo.form,
+                                            labelAlign : 'top',
+                                            style : 'margin-left:10px;float:left;',
+                                            width : 250,
+                                            items : [
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Invchead notes',
+                                                    height : 60,
+                                                    name : 'invchead_notes',
+                                                    width : 250
+                                                },
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'BillTo',
+                                                    height : 60,
+                                                    name : 'invchead_billto',
+                                                    width : 250
+                                                },
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Shipto',
+                                                    height : 60,
+                                                    name : 'invchead_shipto',
+                                                    width : 250
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'invchead_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'invchead_void'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'billitems'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                             
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'invcitem',
+                    title : "invcitem",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'invcitem_item_id_item_descrip1',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                    o.params = o.params || {};
+                                        var id  = _this.form.findField('invchead_id').getValue();
+                                        if (!id){
+                                            return false;
+                                        }
+                                        o.params.invcitem_invchead_id = id;
+                                        o.params.limit = 999;
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'invcitem_linenumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/invcitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'invcitem_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_item_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_warehous_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_custpn',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_ordered',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_billed',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_custprice',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_price',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_notes',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_salescat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_invuomratio',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_invuomratio',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_coitem_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_updateinv',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_taxtype_id_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_taxtype_id_taxtype_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_taxtype_id_taxtype_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_taxtype_id_taxtype_sys',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_uom_id_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_uom_id_uom_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_uom_id_uom_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_qty_uom_id_uom_item_weight',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_uom_id_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_uom_id_uom_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_uom_id_uom_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_price_uom_id_uom_item_weight',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_cust_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_ordernumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_orderdate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_posted',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_printed',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_invcnumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_invcdate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipdate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_ponumber',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipvia',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_fob',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_address1',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_address2',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_address3',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_city',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_state',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_zipcode',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_phone',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_address1',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_address2',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_address3',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_city',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_state',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_zipcode',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_phone',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_salesrep_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_commission',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_terms_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_freight',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_misc_amount',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_misc_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_misc_accnt_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_payment',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_paymentref',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_notes',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_billto_country',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipto_country',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_prj_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_curr_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_gldistdate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_recurring',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_recurring_interval',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_recurring_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_recurring_until',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_recurring_invchead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_shipchrg_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_taxzone_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'invcitem_invchead_id_invchead_void',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invcitem_linenumber',
+                                header : 'Line',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invcitem_item_id_item_number',
+                                header : 'SKU#',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'invcitem_item_id_item_descrip1',
+                                header : 'Description',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invcitem_price',
+                                header : 'Price',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'invcitem_ordered',
+                                header : 'Qty',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 250,
+                split : true
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            var invchead_id = _this.form.findField('invchead_id').getValue();
+                            if(invchead_id * 1 < 1){
+                                Roo.MessageBox.alert("Error", "Error occur on getting the invchead_id");
+                                return;
+                            }
+                            new Pman.Download({
+                                url : baseURL + '/Roo/invchead',
+                                method : 'GET',
+                                params : {
+                                    invchead_id : invchead_id,
+                                    _print : 1
+                                },
+                                success : function() {
+                        
+                                }
+                            })
+                        }
+                    },
+                    cls : 'x-btn-text-icon',
+                    text : "Print Invoice",
+                    icon : rootURL + '/Pman/templates/images/pdf.gif'
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            new Pman.Download({
+                                grid : _this.grid
+                            });
+                        }
+                    },
+                    text : "Download items"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleInvoice.bjs b/Pman.Dialog.XtupleInvoice.bjs
new file mode 100644 (file)
index 0000000..f2f8a5a
--- /dev/null
@@ -0,0 +1,674 @@
+{
+    "id": "roo-file-13",
+    "name": "Pman.Dialog.XtupleInvoice",
+    "parent": false,
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleInvoice.bjs",
+    "items": [
+        {
+            ".builderCfg": "{\"cols\":[{\"table\":\"cobmisc\",\"column\":\"cobmisc_shipvia\",\"columnshort\":\"cobmisc_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_freight\",\"columnshort\":\"cobmisc_freight\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_payment\",\"columnshort\":\"cobmisc_payment\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_notes\",\"columnshort\":\"cobmisc_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_shipdate\",\"columnshort\":\"cobmisc_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_invcdate\",\"columnshort\":\"cobmisc_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_misc_descrip\",\"columnshort\":\"cobmisc_misc_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_curr_id\",\"columnshort\":\"cobmisc_curr_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"curr_id\",\"deps\":[{\"table\":\"curr_symbol\",\"column\":\"cobmisc_curr_id_curr_base\",\"columnshort\":\"curr_base\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cobmisc_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cobmisc_curr_id_curr_symbol\",\"columnshort\":\"curr_symbol\",\"ctype\":\"varchar\",\"desc\":\"\"},{\"table\":\"curr_symbol\",\"column\":\"cobmisc_curr_id_curr_abbr\",\"columnshort\":\"curr_abbr\",\"ctype\":\"varchar\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\",\"display\":\"cobmisc_curr_id_curr_abbr\"},{\"table\":\"cobmisc\",\"column\":\"cobmisc_taxzone_id\",\"columnshort\":\"cobmisc_taxzone_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"taxzone_id\",\"deps\":[{\"table\":\"taxzone\",\"column\":\"cobmisc_taxzone_id_taxzone_code\",\"columnshort\":\"taxzone_code\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"taxzone\",\"column\":\"cobmisc_taxzone_id_taxzone_descrip\",\"columnshort\":\"taxzone_descrip\",\"ctype\":\"text\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\",\"display\":\"cobmisc_taxzone_id_taxzone_descrip\"}],\"cols_ex\":[\"cobmisc_curr_id_curr_abbr\",\"cobmisc_taxzone_id_taxzone_descrip\"],\"table\":\"cobmisc\",\"xtype\":\"LayoutDialog\",\"|xns\":\"Roo\"}",
+            "closable": true,
+            "collapsible": false,
+            "height": 600,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create Invoice",
+            "width": 900,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "*prop": "north",
+                    "height": 270,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "north",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "*prop": "east",
+                                    "titlebar": true,
+                                    "width": 250,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.cmpanel = this;\n\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "east",
+                                    "tableName": "cmhead",
+                                    "title": "Apply Credit Memos",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.cmgrid = this; \n    \n}",
+                                                "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n\n       if (columnIndex > 0 ) {\n           return;\n       } \n       var d = this.ds.getAt(rowIndex);\n       var f = this.cm.getDataIndex(columnIndex);\n       \n       // toggle it..\n    \n       d.set(f, d.data[f] * 1 ? 0 : 1);\n        \n        // sort out shipping.\n       _this.form.findField('cobapply_list').update();\n          \n       \n}",
+                                                "rowdblclick": "function (_self, rowIndex, e)\n{\n    var s = _this.cmgrid.ds.getAt(rowIndex);\n\n    Pman.Dialog.XtupleCreditMemo.show({\n        cmhead_id : s.data.join_aropen_cmhead_id\n    },function() {\n        _this.cmgrid.ds.load({});\n    \n    });\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "aropen_docnumber",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var postit = function(params){\n        new Pman.Request(\r\n        {\r\n            url : baseURL + '/Roo/Cmhead',\r\n            mask: params.mask,\r\n            method : 'POST',\r\n            params : params.postdata,\r\n            success : function(res)\r\n            {\r\n                 _this.cmgrid.ds.load({});\n                (function(){\n                    _this.cmgrid.ds.each(function(d){\n                        if(d.data.join_aropen_cmhead_id == res.data){\n                            d.set('toapply', 1);\n                            return false;\n                        }\n                    })\n                }).defer(500);\r\n            } \r\n        });\r\n    }\n    var opendialog  = function(data){\n        Pman.Dialog.XtupleCreditMemo.show( data , function(res) {\n            if(!res.has_item){\n               Roo.MessageBox.confirm(\r\n                    \"Confirm\",\r\n                    \"These is no any credit items in this credit memo! Press YES to reopen the dialog for editing, Press NO will delete this credit memo.\",\r\n                    function(r) {\r\n                        if (r != 'yes') {\n                            // delete the credit memo\n                            Roo.log('deleting');\n                            var params = {\n                                postdata : {\n                                    _delete : res.cmhead_id\n                                },\n                                mask : 'Deleting'\n                            };\n                            postit(params);\r\n                            return;\r\n                        }\n                        // reopen\r\n                        opendialog({cmhead_id : res.cmhead_id});\n                        return;\r\n                    }\r\n                ); \n                return;\n            }\n            \n            Roo.MessageBox.confirm(\r\n                \"Confirm Posting\",\r\n                \"Are you sure this credit memo is complete? <B>Voiding a Credit memo involves creating a sales order and invoice </b>, so make sure this is correct before posting! Press YES will post it, Press NO to reopen the dialog for editing.\",\r\n                function(r) {\r\n                    if (r != 'yes') {\n                        opendialog({cmhead_id : res.cmhead_id});\n                        return;\r\n                    }\r\n                    // postit\n                    var params = {\n                        postdata : {\n                            cmhead_id : res.cmhead_id,\n                            _post : 1\n                        },\n                        mask : 'Posting'\n                    };\n                    postit(params);\n                   \n                    return;\r\n                }\r\n            );\n            \n            \n            \n        })\n    }\n    \n    \n    \n    var cmdata = {\n            cmhead_cust_id : _this.data.cmdata.cm_cust_id,\n            cmhead_cust_id_cust_name : _this.data.cmdata.cm_cust_id_cust_name,\n            cmhead_curr_id : _this.data.cmdata.cm_curr_id,\n            cmhead_curr_id_curr_name : _this.data.cmdata.cm_curr_id_curr_name,\n            cmhead_terms_id : _this.data.cmdata.cm_terms_id,\n            cmhead_terms_id_terms_descrip : _this.data.cmdata.cm_terms_id_terms_descrip,\n            cmhead_salesrep_id : _this.data.cmdata.cm_salesrep_id,\n            cmhead_salesrep_id_salesrep_name : _this.data.cmdata.cm_salesrep_id_salesrep_name,\n            cmhead_docdate : new Date(),\n            cmhead_taxzone_id : _this.data.cmdata.cm_taxzone_id,\n            cmhead_taxzone_id_taxzone_descrip : _this.data.cmdata.cm_taxzone_id_taxzone_descrip,\n            cmhead_billto_cntct_id : _this.data.cmdata.cm_billto_cntct_id,\n            cmhead_billto_cntct_id_cntct_name : _this.data.cmdata.cm_billto_cntct_id_cntct_name,\n            cmhead_location_id : _this.data.cmdata.cm_location_src,\n            cmhead_location_id_location_name : _this.data.cmdata.cm_location_src_location_name,\n            billto_address : _this.data.cmdata.cm_billto_address\n            \n            \n    };\n    \n    opendialog(cmdata);\n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    o.params.limit = 999;\n    o.params._opencm = 1;\n    o.params._for_cohead = _this.form.findField('cobmisc_cohead_id').getValue();\n    o.params._for_cobmisc_id = _this.form.findField('cobmisc_id').getValue();\n}",
+                                                        "load": "function (_self, records, options)\n{\n     _this.form.findField('cobapply_list').update();\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'aropen_docnumber', direction: 'DESC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/aropen.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'cmhead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_custponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_docdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cmhead_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_shipto_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address1',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address2',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address3',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_city',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_state',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_zipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_misc',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_printed',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_billtoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_hold',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_misc_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_rsncode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_gldistdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cmhead_billtocountry',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_country',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_rahead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_taxzone_id_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_taxzone_id_taxzone_code',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_taxzone_id_taxzone_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_number',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_status',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_so',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_wo',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_po',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_owner_username',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_start_date',\n        'type': 'date'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_due_date',\n        'type': 'date'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_assigned_date',\n        'type': 'date'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_completed_date',\n        'type': 'date'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_username',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_prj_id_prj_recurring_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id_taxtype_sys',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "toapply",
+                                                    "header": "Apply",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n    return     '<img class=\"x-grid-check-icon' + \n                    (v*1 ? '-checked' : '')  + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                                        \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "aropen_docnumber",
+                                                    "header": "Number#",
+                                                    "width": 150,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "balance",
+                                                    "header": "Amount Avail",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    if (r.data.applied*1.0 > 0.0)  {\n        return String.format('{0}', r.data.applied*1.0); \n    }\n\n    return String.format('{0}', v); \n}",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "region": "center",
+                                    "xtype": "ContentPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|actioncomplete": "function (_self,action) {\n     if (action.type == 'setdata') {\n        if (_this.data.cobmisc_id) {\n            this.load({ method: 'GET', params: { '_id' : _this.data.cobmisc_id }});\n           return;\n       }      \n       \n           \n       \n       _this.saveBtn.show();\n       // see if we can create an invoice...\n       new Pman.Request({\n            url : baseURL + '/Roo/Cobmisc',\n            params : {\n                _canCreate : _this.data.cobmisc_cohead_id\n            },\n            method : 'GET',\n            success: function(r) {\n                if (r.data.canCreate * 1 > 0 ) {\n                    Roo.MessageBox.alert(\n                        \"Error\", \"An unposted Bill already exists for this order\"\n                    );\n                    _this.dialog.hide();\n                    return;\n                }\n\n               // _this.form.findField('cobmisc_misc').setValue(r.data.cohead.cohead_misc);\n                _this.form.findField('cobmisc_misc').setValue(r.data.cohead.cohead_pretax_discount);\n                _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').setValue(r.data.cohead.cohead_pretax_discount);\n                _this.form.findField('cobmisc_posttax_discount').setValue(\n                    (1* r.data.cohead.cohead_posttax_discount) //- (1*r.data.cohead.cohead_pretax_discount)\n                );\n               // _this.form.findField('cobmisc_cohead_id_cohead_posttax_discount').setValue(r.data.cohead.cohead_posttax_discount);\n                _this.form.findField('cobmisc_misc_descrip').setValue(r.data.cohead.cohead_misc_descrip);\n               _this.grid.ds.load({});\n            }\n        });\n             \n        \n    }\n    if (action.type == 'load') {\n        var d = action.result.data;\n        \n        \n        if(d.cobmisc_misc != 0 && d.cobmisc_posttax_discount == 0 && d.cobmisc_cohead_id_cohead_pretax_discount == 0){\n            _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').setValue(d.cobmisc_misc);\n        }\n        \n        _this.form.findField('cobmisc_posttax_discount').setValue(d.cobmisc_misc - d.cobmisc_cohead_id_cohead_pretax_discount);\n        \n        if (d.cobmisc_invchead_id *1 > 0) {\n                Roo.MessageBox.alert(\n                        \"Warning\", \"This invoice has been posted, you must void it before you can edit it\"\n                    );\n\n                _this.saveBtn.hide();\n            \n        } else {\n            _this.saveBtn.show();\n        }\n         _this.grid.ds.load({});\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n    \n}\n",
+                                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                                            },
+                                            "method": "POST",
+                                            "style": "margin:10px;",
+                                            "xtype": "Form",
+                                            "|recalc": "function() {\n    // recalc prices.\n    var error = 0;\n    var ic = 0.0;\n    var total_tax = 0.0;\n    _this.grid.ds.each(function(r) {\n        ic += ((r.data.cobill_qty * r.data.coitem_price).toFixed(2) * 1);\n        if (r.data.calc_tax) {\n            // either full, or a proportion of...\n            total_tax += (r.data.cobill_qty == r.data.coitem_qtyord) ? \n                (1*r.data.calc_tax) : (\n                    (1*r.data.calc_tax) * (r.data.cobill_qty / r.data.coitem_qtyord)\n                );\n        }\n    \n    });\n    \n    _this.form.findField('cobmisc_itemcost').setValue(ic.toFixed(2));    \n    _this.form.findField('cobmisc_total_tax').setValue( total_tax.toFixed(2));\n\n    \n    var total  = (_this.form.findField('cobmisc_itemcost').getValue() * 1.0) +\n         ( _this.form.findField('cobmisc_freight').getValue() * 1.0)  + \n \n         ( _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').getValue() * 1.0)  + \n         ( _this.form.findField('cobmisc_posttax_discount').getValue() * 1.0)  + \n         ( _this.form.findField('cobmisc_total_tax').getValue() * 1.0)   \n         ;\n\n    // special handling for credit memos.\n    \n    var val = 0.0;\r\n    var count = 0;\r\n    _this.cmgrid.ds.each(function(r) {\r\n        if (r.data.toapply *  1)  { \r\n            count = count + 1;\r\n            if (r.data.applied *1.0 > 0.0) {\r\n                val += parseFloat(r.data.applied);\r\n                return;\r\n            }\r\n            val += parseFloat(r.data.balance);\r\n        }\r\n       \r\n    });\r\n    if(count == 1 && total < val){\n        val = total;\n    }\n    \n    _this.form.findField('cobmisc_cm_total').setValue( (val * -1).toFixed(2));\n    _this.form.findField('cobmisc_total').setValue((total - val).toFixed(2));\n    _this.form.findField('cobapply_total').setValue((val * -1).toFixed(2));\n    \n    /*\n    if (total < 0.0) {\n        // this is an error condition.\n        _this.form.findField('cobmisc_total').setValue(total);\n        return;\n    \n    }\n \n   \n    var cmlist =  _this.form.findField('cobapply_list').getValue();\n    var cmval =  _this.form.findField('cobapply_total').getValue() * 1.0;\n    \n    if (total + cmval >= 0.0 ) {\n        _this.form.findField('cobmisc_total').setValue(((total + cmval) * 1.0).toFixed(2));\n        return; \n    }\n    if (cmlist.length || cmlist.split(',').length > 1) {\n        _this.form.findField('cobmisc_total').setValue(total + cmval);         \n        return;\n    }\n    // fixme we need to work out the correct value...\n    \n     _this.form.findField('cobmisc_cm_total').setValue( (total * -1).toFixed(2));\n    \n    _this.form.findField('cobmisc_total').setValue(0.0);         \n        \n    */\n    \n}\n",
+                                            "|url": "baseURL + '/Roo/cobmisc.php'",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "width": 750,
+                                                    "xtype": "Row",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "width": 250,
+                                                            "xtype": "Column",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "legend": "Invoice Details",
+                                                                    "style": "width:230px",
+                                                                    "xtype": "FieldSet",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "fieldLabel": "Invoice Date",
+                                                                            "format": "Y-m-d",
+                                                                            "name": "cobmisc_invcdate",
+                                                                            "width": 100,
+                                                                            "xtype": "DateField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "fieldLabel": "Shipment Date",
+                                                                            "format": "Y-m-d",
+                                                                            "name": "cobmisc_shipdate",
+                                                                            "width": 100,
+                                                                            "xtype": "DateField",
+                                                                            "|xns": "Roo.form"
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "labelAlign": "top",
+                                                                    "xtype": "Row",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "fieldLabel": "Notes",
+                                                                            "height": 100,
+                                                                            "name": "cobmisc_notes",
+                                                                            "width": 240,
+                                                                            "xtype": "TextArea",
+                                                                            "|xns": "Roo.form"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "left",
+                                                            "style": "margin-left:10px",
+                                                            "width": 350,
+                                                            "xtype": "Column",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "labelAlign": "right",
+                                                                    "labelWidth": 220,
+                                                                    "legend": "Charges",
+                                                                    "style": "width:330px",
+                                                                    "xtype": "FieldSet",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Item(s) Total",
+                                                                            "name": "cobmisc_itemcost",
+                                                                            "readOnly": true,
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "keyup": "function (_self, e)\n{\n   _this.form.recalc();\n}"
+                                                                            },
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Shipping",
+                                                                            "name": "cobmisc_freight",
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Pre Tax discount:",
+                                                                            "name": "cobmisc_cohead_id_cohead_pretax_discount",
+                                                                            "readOnly": true,
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "labelAlign": "top",
+                                                                            "width": 430,
+                                                                            "xtype": "Row",
+                                                                            "|xns": "Roo.form",
+                                                                            "items": [
+                                                                                {
+                                                                                    "fieldLabel": "Discount after Tax Description ",
+                                                                                    "name": "cobmisc_misc_descrip",
+                                                                                    "width": 205,
+                                                                                    "xtype": "TextField",
+                                                                                    "|xns": "Roo.form"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "keyup": "function (_self, e)\n{\n   _this.form.recalc();\n   _this.form.findField('cobmisc_misc').recalc();\n}"
+                                                                                    },
+                                                                                    "allowDecimals": true,
+                                                                                    "cls": "roo-align-right",
+                                                                                    "decimalPrecision": 3,
+                                                                                    "fieldLabel": "Amount",
+                                                                                    "name": "cobmisc_posttax_discount",
+                                                                                    "width": 80,
+                                                                                    "xtype": "NumberField",
+                                                                                    "|xns": "Roo.form"
+                                                                                }
+                                                                            ]
+                                                                        },
+                                                                        {
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Tax",
+                                                                            "name": "cobmisc_total_tax",
+                                                                            "readOnly": true,
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Credit Memos Applied",
+                                                                            "name": "cobmisc_cm_total",
+                                                                            "readOnly": true,
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        },
+                                                                        {
+                                                                            "allowDecimals": true,
+                                                                            "cls": "roo-align-right",
+                                                                            "decimalPrecision": 3,
+                                                                            "fieldLabel": "Total",
+                                                                            "minValue": 0,
+                                                                            "name": "cobmisc_total",
+                                                                            "readOnly": true,
+                                                                            "width": 80,
+                                                                            "xtype": "NumberField",
+                                                                            "|xns": "Roo.form"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "name": "cobmisc_misc",
+                                                    "xtype": "Hidden",
+                                                    "|recalc": "function() {\r\n    var d = _this.form.getValues();\r\n    this.setValue( \r\n        parseFloat(d.cobmisc_cohead_id_cohead_pretax_discount) + \r\n        parseFloat(d.cobmisc_posttax_discount) );\r\n}\r",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cobmisc_cohead_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cobmisc_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cobapply_total",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "cobapply_list",
+                                                    "xtype": "Hidden",
+                                                    "|update": "function() {\n   var ret = [];\n   var val = 0.0;\n   var count = 0;\n    _this.cmgrid.ds.each(function(r) {\n    \n        if (r.data.toapply *  1)  {\n            count = count + 1;\n            ret.push(r.data.aropen_id);\n            if (r.data.applied *1.0 > 0.0) {\n                val += parseFloat(r.data.applied);\n                return;\n            }\n\n            val += parseFloat(r.data.balance);\n        }\n    });\n    \n    var total  = (_this.form.findField('cobmisc_itemcost').getValue() * 1.0) +\r\n                 ( _this.form.findField('cobmisc_freight').getValue() * 1.0)  + \r\n         \r\n                 ( _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').getValue() * 1.0)  + \r\n                 ( _this.form.findField('cobmisc_posttax_discount').getValue() * 1.0)  + \r\n                 ( _this.form.findField('cobmisc_total_tax').getValue() * 1.0)   \r\n                 ;\r\n\r\n    if(count > 1 && total < val){\r\n        Roo.Msg.alert('Error', 'Credit memo total goes over the invoice total');\r\n    }\r\n    this.setValue(ret.join(','));\n    _this.form.findField('cobmisc_cm_total').setValue( (val * -1).toFixed(2));\n    _this.form.findField('cobapply_total').setValue( (val * -1).toFixed(2));\n    _this.form.recalc();\n}\n",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "billitems",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    \n    if (_this.isBuilder) {\n        return;\n    }\n    \n   \n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n}"
+                    },
+                    ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "coitem",
+                    "title": "Order Items",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    \n}\n",
+                                "afteredit": "function (e)\n{\n    //Roo.log('afteredit');\n   // Roo.log(e);\n    if (e.field == 'item_number') {\n        // afterselect handles this...\n        return;\n    }\n    e.record.commit();\n}"
+                            },
+                            "*prop": "grid",
+                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "autoExpandColumn": "item_descrip1",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "*prop": "sm",
+                                    "enter_is_tab": true,
+                                    "xtype": "CellSelectionModel",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "listeners": {
+                                        "|beforeload": "function (_self,o) {\n    if (! _this.form.findField('cobmisc_cohead_id').getValue()) {\n        return false;\n    }\n    o.params = o.params || {};\n    \n    o.params.coitem_cohead_id = _this.form.findField('cobmisc_cohead_id').getValue();\n    o.params.limit = 999;\n    o.params.cobmisc_id = _this.form.findField('cobmisc_id').getValue();\n    \n}",
+                                        "load": "function (_self, records, options)\n{\n   (function() { _this.form.recalc(); }).defer(100);\n   _this.cmgrid.ds.load({});\n}",
+                                        "update": "function (_self, record, operation)\n{\n  _this.form.recalc();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'coitem_linenumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/coitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'coitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyord'\n    },\n    {\n        'name': 'coitem_unitcost'\n    },\n    {\n        'name': 'coitem_price'\n    },\n    {\n        'name': 'coitem_custprice'\n    },\n    {\n        'name': 'coitem_qtyreturned'\n    },\n    {\n        'name': 'coitem_prcost'\n    },\n    {\n        'name': 'coitem_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyreserved'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    _this.grid.ds.each(function(r) {\n        r.set('cobill_qty', Math.max(0, r.data.coitem_qtyord - r.data.cobill_billed));\n    });\n}"
+                                            },
+                                            "text": "Invoice all",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "text": "Restore from : ",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|select": "function (combo, record, index)\n{\n  //_this.grid.footer.onClick('first');\n  \n   (function() { \n    combo.setValue('');\n   }).defer(100);\n   var data = record.json.data;\n   \n   _this.grid.ds.each(function (r) {\n        if (typeof(data[r.data.coitem_itemsite_id+'']) == 'undefined') {\n            return;\n        }\n        r.set('cobill_qty', parseInt(data[r.data.coitem_itemsite_id+'']));\n   \n   });\n   \n   \n   \n  \n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "name",
+                                            "editable": false,
+                                            "emptyText": "Restore from",
+                                            "forceSelection": true,
+                                            "listWidth": 300,
+                                            "loadingText": "Searching...",
+                                            "name": "name",
+                                            "pageSize": 20,
+                                            "qtip": "Select Action",
+                                            "queryParam": "query[action]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "name",
+                                            "width": 300,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n     \n    o.params._stash = _this.form.findField('cobmisc_cohead_id').getValue();\n\n}"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'action' , direction : 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/Cobmisc.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "name",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\n    {\n        'name': 'name',\n        'type': 'string'\n    }\n \n]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "xtype": "Fill",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     _this.grid.ds.each(function(r) {\n        r.set('cobill_qty', 0);\n    });\n}\n"
+                                            },
+                                            "text": "Reset",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "xtype": "ColumnModel",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"}",
+                                    "header": "Item#",
+                                    "width": 75,
+                                    "dataIndex": "coitem_linenumber",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "*prop": "colModel[]"
+                                },
+                                {
+                                    "xtype": "ColumnModel",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "header": "Item Code",
+                                    "width": 75,
+                                    "dataIndex": "item_number",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "*prop": "colModel[]"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Item Description",
+                                    "width": "150.00",
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v, x, r) {\n\n    var vv = v;\n    if (r.data.coitem_memo && r.data.coitem_memo.length) {\n        vv = r.data.coitem_memo;\n    }\n    return String.format('{0}', vv); \n \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_custprice",
+                                    "header": "List Price",
+                                    "width": 80,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_price",
+                                    "header": "Sell @",
+                                    "width": 80,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "calc_tax",
+                                    "header": "Tax",
+                                    "width": 80,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"}",
+                                    "align": "right",
+                                    "dataIndex": "coitem_qtyord",
+                                    "header": "Ordered Qty",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cobill_billed",
+                                    "header": "Not Billed Qty",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n\n     Roo.log(v);\n     return String.format('{0}', r.data.coitem_qtyord - v); \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"}",
+                                    "align": "right",
+                                    "dataIndex": "cobill_qty",
+                                    "header": "Bill Qty",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    var vv = parseInt(v);\n    vv = isNaN(vv) ? 0 : vv;\n    r.data.cobill_qty = vv; // get rid of decimal.\n    if (r.data.cobill_billed + vv > r.data.coitem_qtyord) {\n            return String.format('<b style=\"background-color:red;color:yellow\">{0}</b>', vv); \n    }\n    // not fully fullfilled\n    if (r.data.cobill_billed + vv != r.data.coitem_qtyord) {\n            return String.format('<b style=\"background-color:blue;color:yellow\">{0}</b>', vv); \n    }   \n    return String.format('{0}', vv); \n    \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "editor",
+                                            "xtype": "GridEditor",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowDecimals": true,
+                                                    "decimalPrecision": 0,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    var hasListDiscount = false;\n    var orderQty = 0;\n    var billQty = 0;\n    \n    var ar = [];\n    _this.grid.ds.each(function(r) {\n        if(r.data.item_number == 'Z-LIST-DISCOUNT'){\n            hasListDiscount = true;\n        }\n        orderQty += r.data.coitem_qtyord;\n        billQty += r.data.cobill_qty;\n        \n        ar.push({\n            cobill_coitem_id : r.data.coitem_id,\n            cobill_qty : r.data.cobill_qty \n        });\n    });\n    var doSubmit = function(){\n        _this.form.findField('billitems').setValue(JSON.stringify(ar));\n        _this.form.doAction(\"submit\");   \n    \n    }\n    if(hasListDiscount && orderQty != billQty){\n        Roo.MessageBox.confirm(\"Confirm\", \"This Invoice contains a pre-tax discount - you can still invoice the customer however the calculations for discount will be inaccurate.\",\n            function (res) {\n                if(res!='yes') {\n                    return;\n                }\n                doSubmit();\n         });\n         return;\n     }\n     \n    doSubmit();\n\n}",
+                        "render": "function (_self)\n{\n _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleInvoice.js b/Pman.Dialog.XtupleInvoice.js
new file mode 100644 (file)
index 0000000..bd71558
--- /dev/null
@@ -0,0 +1,1458 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleInvoice = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : true,
+            collapsible : false,
+            height : 600,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create Invoice",
+            width : 900,
+            items : [
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'north',
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.cmpanel = this;
+                                    
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'east',
+                                tableName : 'cmhead',
+                                title : "Apply Credit Memos",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.cmgrid = this; 
+                                            
+                                        },
+                                        cellclick : function (_self, rowIndex, columnIndex, e)
+                                        {
+                                        
+                                               if (columnIndex > 0 ) {
+                                                   return;
+                                               } 
+                                               var d = this.ds.getAt(rowIndex);
+                                               var f = this.cm.getDataIndex(columnIndex);
+                                               
+                                               // toggle it..
+                                            
+                                               d.set(f, d.data[f] * 1 ? 0 : 1);
+                                                
+                                                // sort out shipping.
+                                               _this.form.findField('cobapply_list').update();
+                                                  
+                                               
+                                        },
+                                        rowdblclick : function (_self, rowIndex, e)
+                                        {
+                                            var s = _this.cmgrid.ds.getAt(rowIndex);
+                                        
+                                            Pman.Dialog.XtupleCreditMemo.show({
+                                                cmhead_id : s.data.join_aropen_cmhead_id
+                                            },function() {
+                                                _this.cmgrid.ds.load({});
+                                            
+                                            });
+                                        }
+                                    },
+                                    autoExpandColumn : 'aropen_docnumber',
+                                    loadMask : true,
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var postit = function(params){
+                                                            new Pman.Request(
+                                                            {
+                                                                url : baseURL + '/Roo/Cmhead',
+                                                                mask: params.mask,
+                                                                method : 'POST',
+                                                                params : params.postdata,
+                                                                success : function(res)
+                                                                {
+                                                                     _this.cmgrid.ds.load({});
+                                                                    (function(){
+                                                                        _this.cmgrid.ds.each(function(d){
+                                                                            if(d.data.join_aropen_cmhead_id == res.data){
+                                                                                d.set('toapply', 1);
+                                                                                return false;
+                                                                            }
+                                                                        })
+                                                                    }).defer(500);
+                                                                } 
+                                                            });
+                                                        }
+                                                        var opendialog  = function(data){
+                                                            Pman.Dialog.XtupleCreditMemo.show( data , function(res) {
+                                                                if(!res.has_item){
+                                                                   Roo.MessageBox.confirm(
+                                                                        "Confirm",
+                                                                        "These is no any credit items in this credit memo! Press YES to reopen the dialog for editing, Press NO will delete this credit memo.",
+                                                                        function(r) {
+                                                                            if (r != 'yes') {
+                                                                                // delete the credit memo
+                                                                                Roo.log('deleting');
+                                                                                var params = {
+                                                                                    postdata : {
+                                                                                        _delete : res.cmhead_id
+                                                                                    },
+                                                                                    mask : 'Deleting'
+                                                                                };
+                                                                                postit(params);
+                                                                                return;
+                                                                            }
+                                                                            // reopen
+                                                                            opendialog({cmhead_id : res.cmhead_id});
+                                                                            return;
+                                                                        }
+                                                                    ); 
+                                                                    return;
+                                                                }
+                                                                
+                                                                Roo.MessageBox.confirm(
+                                                                    "Confirm Posting",
+                                                                    "Are you sure this credit memo is complete? <B>Voiding a Credit memo involves creating a sales order and invoice </b>, so make sure this is correct before posting! Press YES will post it, Press NO to reopen the dialog for editing.",
+                                                                    function(r) {
+                                                                        if (r != 'yes') {
+                                                                            opendialog({cmhead_id : res.cmhead_id});
+                                                                            return;
+                                                                        }
+                                                                        // postit
+                                                                        var params = {
+                                                                            postdata : {
+                                                                                cmhead_id : res.cmhead_id,
+                                                                                _post : 1
+                                                                            },
+                                                                            mask : 'Posting'
+                                                                        };
+                                                                        postit(params);
+                                                                       
+                                                                        return;
+                                                                    }
+                                                                );
+                                                                
+                                                                
+                                                                
+                                                            })
+                                                        }
+                                                        
+                                                        
+                                                        
+                                                        var cmdata = {
+                                                                cmhead_cust_id : _this.data.cmdata.cm_cust_id,
+                                                                cmhead_cust_id_cust_name : _this.data.cmdata.cm_cust_id_cust_name,
+                                                                cmhead_curr_id : _this.data.cmdata.cm_curr_id,
+                                                                cmhead_curr_id_curr_name : _this.data.cmdata.cm_curr_id_curr_name,
+                                                                cmhead_terms_id : _this.data.cmdata.cm_terms_id,
+                                                                cmhead_terms_id_terms_descrip : _this.data.cmdata.cm_terms_id_terms_descrip,
+                                                                cmhead_salesrep_id : _this.data.cmdata.cm_salesrep_id,
+                                                                cmhead_salesrep_id_salesrep_name : _this.data.cmdata.cm_salesrep_id_salesrep_name,
+                                                                cmhead_docdate : new Date(),
+                                                                cmhead_taxzone_id : _this.data.cmdata.cm_taxzone_id,
+                                                                cmhead_taxzone_id_taxzone_descrip : _this.data.cmdata.cm_taxzone_id_taxzone_descrip,
+                                                                cmhead_billto_cntct_id : _this.data.cmdata.cm_billto_cntct_id,
+                                                                cmhead_billto_cntct_id_cntct_name : _this.data.cmdata.cm_billto_cntct_id_cntct_name,
+                                                                cmhead_location_id : _this.data.cmdata.cm_location_src,
+                                                                cmhead_location_id_location_name : _this.data.cmdata.cm_location_src_location_name,
+                                                                billto_address : _this.data.cmdata.cm_billto_address
+                                                                
+                                                                
+                                                        };
+                                                        
+                                                        opendialog(cmdata);
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            }
+                                        ]
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params = o.params || {};
+                                                o.params.limit = 999;
+                                                o.params._opencm = 1;
+                                                o.params._for_cohead = _this.form.findField('cobmisc_cohead_id').getValue();
+                                                o.params._for_cobmisc_id = _this.form.findField('cobmisc_id').getValue();
+                                            },
+                                            load : function (_self, records, options)
+                                            {
+                                                 _this.form.findField('cobapply_list').update();
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'aropen_docnumber', direction: 'DESC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/aropen.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'cmhead_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_number',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_posted',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_invcnumber',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_custponumber',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_cust_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_docdate',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_address1',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_address2',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_address3',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_city',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_state',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_zipcode',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_salesrep_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freight',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'cmhead_misc',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'cmhead_comments',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_printed',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtoname',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtoaddress1',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtoaddress2',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtoaddress3',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtocity',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtostate',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtozip',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_hold',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_commission',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'cmhead_misc_accnt_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_misc_descrip',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_rsncode_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freighttaxtype_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_gldistdate',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'cmhead_billtocountry',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_shipto_country',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_rahead_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_taxzone_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id_curr_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id_curr_base',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id_curr_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id_curr_symbol',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_curr_id_curr_abbr',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_taxzone_id_taxzone_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_taxzone_id_taxzone_code',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_taxzone_id_taxzone_descrip',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_number',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_descrip',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_status',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_so',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_wo',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_po',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_owner_username',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_start_date',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_due_date',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_assigned_date',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_completed_date',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_username',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_prj_id_prj_recurring_prj_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freighttaxtype_id_taxtype_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freighttaxtype_id_taxtype_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freighttaxtype_id_taxtype_descrip',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'cmhead_freighttaxtype_id_taxtype_sys',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'toapply',
+                                            header : 'Apply',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                return     '<img class="x-grid-check-icon' + 
+                                                                (v*1 ? '-checked' : '')  + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                                                    
+                                                
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'aropen_docnumber',
+                                            header : 'Number#',
+                                            width : 150,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'balance',
+                                            header : 'Amount Avail',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                                if (r.data.applied*1.0 > 0.0)  {
+                                                    return String.format('{0}', r.data.applied*1.0); 
+                                                }
+                                            
+                                                return String.format('{0}', v); 
+                                            }
+                                        }
+                                    ]
+                                }
+                            },
+                            {
+                                xtype: 'ContentPanel',
+                                xns: Roo,
+                                region : 'center',
+                                items : [
+                                    {
+                                        xtype: 'Form',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            actioncomplete : function (_self,action) {
+                                                 if (action.type == 'setdata') {
+                                                    if (_this.data.cobmisc_id) {
+                                                        this.load({ method: 'GET', params: { '_id' : _this.data.cobmisc_id }});
+                                                       return;
+                                                   }      
+                                                   
+                                                       
+                                                   
+                                                   _this.saveBtn.show();
+                                                   // see if we can create an invoice...
+                                                   new Pman.Request({
+                                                        url : baseURL + '/Roo/Cobmisc',
+                                                        params : {
+                                                            _canCreate : _this.data.cobmisc_cohead_id
+                                                        },
+                                                        method : 'GET',
+                                                        success: function(r) {
+                                                            if (r.data.canCreate * 1 > 0 ) {
+                                                                Roo.MessageBox.alert(
+                                                                    "Error", "An unposted Bill already exists for this order"
+                                                                );
+                                                                _this.dialog.hide();
+                                                                return;
+                                                            }
+                                            
+                                                           // _this.form.findField('cobmisc_misc').setValue(r.data.cohead.cohead_misc);
+                                                            _this.form.findField('cobmisc_misc').setValue(r.data.cohead.cohead_pretax_discount);
+                                                            _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').setValue(r.data.cohead.cohead_pretax_discount);
+                                                            _this.form.findField('cobmisc_posttax_discount').setValue(
+                                                                (1* r.data.cohead.cohead_posttax_discount) //- (1*r.data.cohead.cohead_pretax_discount)
+                                                            );
+                                                           // _this.form.findField('cobmisc_cohead_id_cohead_posttax_discount').setValue(r.data.cohead.cohead_posttax_discount);
+                                                            _this.form.findField('cobmisc_misc_descrip').setValue(r.data.cohead.cohead_misc_descrip);
+                                                           _this.grid.ds.load({});
+                                                        }
+                                                    });
+                                                         
+                                                    
+                                                }
+                                                if (action.type == 'load') {
+                                                    var d = action.result.data;
+                                                    
+                                                    
+                                                    if(d.cobmisc_misc != 0 && d.cobmisc_posttax_discount == 0 && d.cobmisc_cohead_id_cohead_pretax_discount == 0){
+                                                        _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').setValue(d.cobmisc_misc);
+                                                    }
+                                                    
+                                                    _this.form.findField('cobmisc_posttax_discount').setValue(d.cobmisc_misc - d.cobmisc_cohead_id_cohead_pretax_discount);
+                                                    
+                                                    if (d.cobmisc_invchead_id *1 > 0) {
+                                                            Roo.MessageBox.alert(
+                                                                    "Warning", "This invoice has been posted, you must void it before you can edit it"
+                                                                );
+                                            
+                                                            _this.saveBtn.hide();
+                                                        
+                                                    } else {
+                                                        _this.saveBtn.show();
+                                                    }
+                                                     _this.grid.ds.load({});
+                                                    return;
+                                                }
+                                                if (action.type =='submit') {
+                                                
+                                                    _this.dialog.hide();
+                                                
+                                                     if (_this.callback) {
+                                                        _this.callback.call(_this, _this.form.getValues());
+                                                     }
+                                                     _this.form.reset();
+                                                     return;
+                                                }
+                                                
+                                            },
+                                            rendered : function (form)
+                                            {
+                                                _this.form= form;
+                                            }
+                                        },
+                                        method : 'POST',
+                                        style : 'margin:10px;',
+                                        recalc : function() {
+                                            // recalc prices.
+                                            var error = 0;
+                                            var ic = 0.0;
+                                            var total_tax = 0.0;
+                                            _this.grid.ds.each(function(r) {
+                                                ic += ((r.data.cobill_qty * r.data.coitem_price).toFixed(2) * 1);
+                                                if (r.data.calc_tax) {
+                                                    // either full, or a proportion of...
+                                                    total_tax += (r.data.cobill_qty == r.data.coitem_qtyord) ? 
+                                                        (1*r.data.calc_tax) : (
+                                                            (1*r.data.calc_tax) * (r.data.cobill_qty / r.data.coitem_qtyord)
+                                                        );
+                                                }
+                                            
+                                            });
+                                            
+                                            _this.form.findField('cobmisc_itemcost').setValue(ic.toFixed(2));    
+                                            _this.form.findField('cobmisc_total_tax').setValue( total_tax.toFixed(2));
+                                        
+                                            
+                                            var total  = (_this.form.findField('cobmisc_itemcost').getValue() * 1.0) +
+                                                 ( _this.form.findField('cobmisc_freight').getValue() * 1.0)  + 
+                                         
+                                                 ( _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').getValue() * 1.0)  + 
+                                                 ( _this.form.findField('cobmisc_posttax_discount').getValue() * 1.0)  + 
+                                                 ( _this.form.findField('cobmisc_total_tax').getValue() * 1.0)   
+                                                 ;
+                                        
+                                            // special handling for credit memos.
+                                            
+                                            var val = 0.0;
+                                            var count = 0;
+                                            _this.cmgrid.ds.each(function(r) {
+                                                if (r.data.toapply *  1)  { 
+                                                    count = count + 1;
+                                                    if (r.data.applied *1.0 > 0.0) {
+                                                        val += parseFloat(r.data.applied);
+                                                        return;
+                                                    }
+                                                    val += parseFloat(r.data.balance);
+                                                }
+                                               
+                                            });
+                                            if(count == 1 && total < val){
+                                                val = total;
+                                            }
+                                            
+                                            _this.form.findField('cobmisc_cm_total').setValue( (val * -1).toFixed(2));
+                                            _this.form.findField('cobmisc_total').setValue((total - val).toFixed(2));
+                                            _this.form.findField('cobapply_total').setValue((val * -1).toFixed(2));
+                                            
+                                            /*
+                                            if (total < 0.0) {
+                                                // this is an error condition.
+                                                _this.form.findField('cobmisc_total').setValue(total);
+                                                return;
+                                            
+                                            }
+                                         
+                                           
+                                            var cmlist =  _this.form.findField('cobapply_list').getValue();
+                                            var cmval =  _this.form.findField('cobapply_total').getValue() * 1.0;
+                                            
+                                            if (total + cmval >= 0.0 ) {
+                                                _this.form.findField('cobmisc_total').setValue(((total + cmval) * 1.0).toFixed(2));
+                                                return; 
+                                            }
+                                            if (cmlist.length || cmlist.split(',').length > 1) {
+                                                _this.form.findField('cobmisc_total').setValue(total + cmval);         
+                                                return;
+                                            }
+                                            // fixme we need to work out the correct value...
+                                            
+                                             _this.form.findField('cobmisc_cm_total').setValue( (total * -1).toFixed(2));
+                                            
+                                            _this.form.findField('cobmisc_total').setValue(0.0);         
+                                                
+                                            */
+                                            
+                                        },
+                                        url : baseURL + '/Roo/cobmisc.php',
+                                        items : [
+                                            {
+                                                xtype: 'Row',
+                                                xns: Roo.form,
+                                                width : 750,
+                                                items : [
+                                                    {
+                                                        xtype: 'Column',
+                                                        xns: Roo.form,
+                                                        width : 250,
+                                                        items : [
+                                                            {
+                                                                xtype: 'FieldSet',
+                                                                xns: Roo.form,
+                                                                legend : "Invoice Details",
+                                                                style : 'width:230px',
+                                                                items : [
+                                                                    {
+                                                                        xtype: 'DateField',
+                                                                        xns: Roo.form,
+                                                                        fieldLabel : 'Invoice Date',
+                                                                        format : 'Y-m-d',
+                                                                        name : 'cobmisc_invcdate',
+                                                                        width : 100
+                                                                    },
+                                                                    {
+                                                                        xtype: 'DateField',
+                                                                        xns: Roo.form,
+                                                                        fieldLabel : 'Shipment Date',
+                                                                        format : 'Y-m-d',
+                                                                        name : 'cobmisc_shipdate',
+                                                                        width : 100
+                                                                    }
+                                                                ]
+                                                            },
+                                                            {
+                                                                xtype: 'Row',
+                                                                xns: Roo.form,
+                                                                labelAlign : 'top',
+                                                                items : [
+                                                                    {
+                                                                        xtype: 'TextArea',
+                                                                        xns: Roo.form,
+                                                                        fieldLabel : 'Notes',
+                                                                        height : 100,
+                                                                        name : 'cobmisc_notes',
+                                                                        width : 240
+                                                                    }
+                                                                ]
+                                                            }
+                                                        ]
+                                                    },
+                                                    {
+                                                        xtype: 'Column',
+                                                        xns: Roo.form,
+                                                        labelAlign : 'left',
+                                                        style : 'margin-left:10px',
+                                                        width : 350,
+                                                        items : [
+                                                            {
+                                                                xtype: 'FieldSet',
+                                                                xns: Roo.form,
+                                                                labelAlign : 'right',
+                                                                labelWidth : 220,
+                                                                legend : "Charges",
+                                                                style : 'width:330px',
+                                                                items : [
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Item(s) Total',
+                                                                        name : 'cobmisc_itemcost',
+                                                                        readOnly : true,
+                                                                        width : 80
+                                                                    },
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        listeners : {
+                                                                            keyup : function (_self, e)
+                                                                            {
+                                                                               _this.form.recalc();
+                                                                            }
+                                                                        },
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Shipping',
+                                                                        name : 'cobmisc_freight',
+                                                                        width : 80
+                                                                    },
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Pre Tax discount:',
+                                                                        name : 'cobmisc_cohead_id_cohead_pretax_discount',
+                                                                        readOnly : true,
+                                                                        width : 80
+                                                                    },
+                                                                    {
+                                                                        xtype: 'Row',
+                                                                        xns: Roo.form,
+                                                                        labelAlign : 'top',
+                                                                        width : 430,
+                                                                        items : [
+                                                                            {
+                                                                                xtype: 'TextField',
+                                                                                xns: Roo.form,
+                                                                                fieldLabel : 'Discount after Tax Description ',
+                                                                                name : 'cobmisc_misc_descrip',
+                                                                                width : 205
+                                                                            },
+                                                                            {
+                                                                                xtype: 'NumberField',
+                                                                                xns: Roo.form,
+                                                                                listeners : {
+                                                                                    keyup : function (_self, e)
+                                                                                    {
+                                                                                       _this.form.recalc();
+                                                                                       _this.form.findField('cobmisc_misc').recalc();
+                                                                                    }
+                                                                                },
+                                                                                allowDecimals : true,
+                                                                                cls : 'roo-align-right',
+                                                                                decimalPrecision : 3,
+                                                                                fieldLabel : 'Amount',
+                                                                                name : 'cobmisc_posttax_discount',
+                                                                                width : 80
+                                                                            }
+                                                                        ]
+                                                                    },
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Tax',
+                                                                        name : 'cobmisc_total_tax',
+                                                                        readOnly : true,
+                                                                        width : 80
+                                                                    },
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Credit Memos Applied',
+                                                                        name : 'cobmisc_cm_total',
+                                                                        readOnly : true,
+                                                                        width : 80
+                                                                    },
+                                                                    {
+                                                                        xtype: 'NumberField',
+                                                                        xns: Roo.form,
+                                                                        allowDecimals : true,
+                                                                        cls : 'roo-align-right',
+                                                                        decimalPrecision : 3,
+                                                                        fieldLabel : 'Total',
+                                                                        minValue : 0,
+                                                                        name : 'cobmisc_total',
+                                                                        readOnly : true,
+                                                                        width : 80
+                                                                    }
+                                                                ]
+                                                            }
+                                                        ]
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cobmisc_misc',
+                                                recalc : function() {
+                                                    var d = _this.form.getValues();
+                                                    this.setValue( 
+                                                        parseFloat(d.cobmisc_cohead_id_cohead_pretax_discount) + 
+                                                        parseFloat(d.cobmisc_posttax_discount) );
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cobmisc_cohead_id'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cobmisc_id'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cobapply_total'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'cobapply_list',
+                                                update : function() {
+                                                   var ret = [];
+                                                   var val = 0.0;
+                                                   var count = 0;
+                                                    _this.cmgrid.ds.each(function(r) {
+                                                    
+                                                        if (r.data.toapply *  1)  {
+                                                            count = count + 1;
+                                                            ret.push(r.data.aropen_id);
+                                                            if (r.data.applied *1.0 > 0.0) {
+                                                                val += parseFloat(r.data.applied);
+                                                                return;
+                                                            }
+                                                
+                                                            val += parseFloat(r.data.balance);
+                                                        }
+                                                    });
+                                                    
+                                                    var total  = (_this.form.findField('cobmisc_itemcost').getValue() * 1.0) +
+                                                                 ( _this.form.findField('cobmisc_freight').getValue() * 1.0)  + 
+                                                         
+                                                                 ( _this.form.findField('cobmisc_cohead_id_cohead_pretax_discount').getValue() * 1.0)  + 
+                                                                 ( _this.form.findField('cobmisc_posttax_discount').getValue() * 1.0)  + 
+                                                                 ( _this.form.findField('cobmisc_total_tax').getValue() * 1.0)   
+                                                                 ;
+                                                
+                                                    if(count > 1 && total < val){
+                                                        Roo.Msg.alert('Error', 'Credit memo total goes over the invoice total');
+                                                    }
+                                                    this.setValue(ret.join(','));
+                                                    _this.form.findField('cobmisc_cm_total').setValue( (val * -1).toFixed(2));
+                                                    _this.form.findField('cobapply_total').setValue( (val * -1).toFixed(2));
+                                                    _this.form.recalc();
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'billitems'
+                                            }
+                                        ]
+                                    }
+                                ]
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        },
+                        east : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            titlebar : true,
+                            width : 250
+                        }
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            
+                            if (_this.isBuilder) {
+                                return;
+                            }
+                            
+                           
+                            if (_this.grid) {
+                                _this.grid.ds.load({});
+                            }
+                        }
+                    },
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'coitem',
+                    title : "Order Items",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.ds.load({});
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                
+                            },
+                            afteredit : function (e)
+                            {
+                                //Roo.log('afteredit');
+                               // Roo.log(e);
+                                if (e.field == 'item_number') {
+                                    // afterselect handles this...
+                                    return;
+                                }
+                                e.record.commit();
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        sm : {
+                            xtype: 'CellSelectionModel',
+                            xns: Roo.grid,
+                            enter_is_tab : true
+                        },
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                    if (! _this.form.findField('cobmisc_cohead_id').getValue()) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    
+                                    o.params.coitem_cohead_id = _this.form.findField('cobmisc_cohead_id').getValue();
+                                    o.params.limit = 999;
+                                    o.params.cobmisc_id = _this.form.findField('cobmisc_id').getValue();
+                                    
+                                },
+                                load : function (_self, records, options)
+                                {
+                                   (function() { _this.form.recalc(); }).defer(100);
+                                   _this.cmgrid.ds.load({});
+                                },
+                                update : function (_self, record, operation)
+                                {
+                                  _this.form.recalc();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'coitem_linenumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/coitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'coitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyord'
+                                    },
+                                    {
+                                        'name': 'coitem_unitcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price'
+                                    },
+                                    {
+                                        'name': 'coitem_custprice'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreturned'
+                                    },
+                                    {
+                                        'name': 'coitem_prcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreserved'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.grid.ds.each(function(r) {
+                                                r.set('cobill_qty', Math.max(0, r.data.coitem_qtyord - r.data.cobill_billed));
+                                            });
+                                        }
+                                    },
+                                    text : "Invoice all"
+                                },
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "Restore from : "
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        select : function (combo, record, index)
+                                        {
+                                          //_this.grid.footer.onClick('first');
+                                          
+                                           (function() { 
+                                            combo.setValue('');
+                                           }).defer(100);
+                                           var data = record.json.data;
+                                           
+                                           _this.grid.ds.each(function (r) {
+                                                if (typeof(data[r.data.coitem_itemsite_id+'']) == 'undefined') {
+                                                    return;
+                                                }
+                                                r.set('cobill_qty', parseInt(data[r.data.coitem_itemsite_id+'']));
+                                           
+                                           });
+                                           
+                                           
+                                           
+                                          
+                                        }
+                                    },
+                                    allowBlank : true,
+                                    displayField : 'name',
+                                    editable : false,
+                                    emptyText : "Restore from",
+                                    forceSelection : true,
+                                    listWidth : 300,
+                                    loadingText : "Searching...",
+                                    name : 'name',
+                                    pageSize : 20,
+                                    qtip : "Select Action",
+                                    queryParam : 'query[action]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'name',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params = o.params || {};
+                                                // staff can see all logs, other companies can only see their own.
+                                                 
+                                                o.params._stash = _this.form.findField('cobmisc_cohead_id').getValue();
+                                            
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'action' , direction : 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Cobmisc.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'name',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {
+                                                    'name': 'name',
+                                                    'type': 'string'
+                                                }
+                                             
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             _this.grid.ds.each(function(r) {
+                                                r.set('cobill_qty', 0);
+                                            });
+                                        }
+                                    },
+                                    text : "Reset"
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                header : 'Item#',
+                                width : 75,
+                                dataIndex : 'coitem_linenumber',
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                header : 'Item Code',
+                                width : 75,
+                                dataIndex : 'item_number',
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Item Description',
+                                width : '150.00',
+                                renderer : function(v, x, r) {
+                                
+                                    var vv = v;
+                                    if (r.data.coitem_memo && r.data.coitem_memo.length) {
+                                        vv = r.data.coitem_memo;
+                                    }
+                                    return String.format('{0}', vv); 
+                                 
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_custprice',
+                                header : 'List Price',
+                                width : 80,
+                                renderer : function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_price',
+                                header : 'Sell @',
+                                width : 80,
+                                renderer : function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'calc_tax',
+                                header : 'Tax',
+                                width : 80,
+                                renderer : function(v) { return String.format('{0}', (v *1.0).toFixed(2)); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_qtyord',
+                                header : 'Ordered Qty',
+                                width : 70,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cobill_billed',
+                                header : 'Not Billed Qty',
+                                width : 70,
+                                renderer : function(v,x,r) {
+                                
+                                     Roo.log(v);
+                                     return String.format('{0}', r.data.coitem_qtyord - v); 
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cobill_qty',
+                                header : 'Bill Qty',
+                                width : 100,
+                                renderer : function(v,x,r) { 
+                                    
+                                    var vv = parseInt(v);
+                                    vv = isNaN(vv) ? 0 : vv;
+                                    r.data.cobill_qty = vv; // get rid of decimal.
+                                    if (r.data.cobill_billed + vv > r.data.coitem_qtyord) {
+                                            return String.format('<b style="background-color:red;color:yellow">{0}</b>', vv); 
+                                    }
+                                    // not fully fullfilled
+                                    if (r.data.cobill_billed + vv != r.data.coitem_qtyord) {
+                                            return String.format('<b style="background-color:blue;color:yellow">{0}</b>', vv); 
+                                    }   
+                                    return String.format('{0}', vv); 
+                                    
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        allowDecimals : true,
+                                        decimalPrecision : 0,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 270
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            var hasListDiscount = false;
+                            var orderQty = 0;
+                            var billQty = 0;
+                            
+                            var ar = [];
+                            _this.grid.ds.each(function(r) {
+                                if(r.data.item_number == 'Z-LIST-DISCOUNT'){
+                                    hasListDiscount = true;
+                                }
+                                orderQty += r.data.coitem_qtyord;
+                                billQty += r.data.cobill_qty;
+                                
+                                ar.push({
+                                    cobill_coitem_id : r.data.coitem_id,
+                                    cobill_qty : r.data.cobill_qty 
+                                });
+                            });
+                            var doSubmit = function(){
+                                _this.form.findField('billitems').setValue(JSON.stringify(ar));
+                                _this.form.doAction("submit");   
+                            
+                            }
+                            if(hasListDiscount && orderQty != billQty){
+                                Roo.MessageBox.confirm("Confirm", "This Invoice contains a pre-tax discount - you can still invoice the customer however the calculations for discount will be inaccurate.",
+                                    function (res) {
+                                        if(res!='yes') {
+                                            return;
+                                        }
+                                        doSubmit();
+                                 });
+                                 return;
+                             }
+                             
+                            doSubmit();
+                        
+                        },
+                        render : function (_self)
+                        {
+                         _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleItem.bjs b/Pman.Dialog.XtupleItem.bjs
new file mode 100644 (file)
index 0000000..2a65b6f
--- /dev/null
@@ -0,0 +1,618 @@
+{
+    "id": "roo-file-14",
+    "name": "Pman.Dialog.XtupleItem",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleItem.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 520,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create item",
+            "width": 800,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       _this.form.findField('item_number').el.dom.readOnly = true;\n       _this.form.findField('item_type').disabled = true; \n       \n       if(_this.data.item_id * 1 > 0){\n            \n            this.load({ \n                method: 'GET', \n                params: {\n                     '_id' : _this.data.item_id,\n                     '_with_itemsite' : 1,\n                     '_with_itemcost' : 1,\n                     '_with_prodcat' : 1 ,\n                     '_with_salesaccnt' : 1 \n                }\n            });\n            return;\n       }\n       // if it's new..\n       _this.form.findField('item_number').el.dom.readOnly = false;\n       _this.form.findField('item_type').disabled = false; \n       _this.form.findField('item_salesaccnt').setValue('');\n       \n       return;\n    }\n    if (action.type == 'load') {\n       _this.form.findField('item_type').showHide();\n        return;\n    }\n    if (action.type =='submit') {\n    \n         \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "labelWidth": 120,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/item.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "SKU",
+                                    "name": "item_number",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Description",
+                                    "name": "item_descrip1",
+                                    "width": 400,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Description (2)",
+                                    "name": "item_descrip2",
+                                    "width": 400,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "labelWidth": 120,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeselect": "function (combo, record, index)\n{\n    (function() { combo.showHide(); }).defer(100);\n}"
+                                            },
+                                            "allowBlank": false,
+                                            "displayField": "fname",
+                                            "editable": false,
+                                            "emptyText": "Select Type",
+                                            "fieldLabel": "Type",
+                                            "hiddenName": "item_type",
+                                            "listWidth": 200,
+                                            "mode": "local",
+                                            "name": "item_type_name",
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{fname}</b> </div>",
+                                            "triggerAction": "all",
+                                            "valueField": "ftype",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|showHide": "function() {\n\n    var it = this.getValue();\n   \n    var p_req = [ \n        'item_itemcost_id_itemcost_curr_id',\n        'item_itemcost_id_itemcost_actcost',\n        'item_itemsite_id_itemsite_reorderlevel',\n        'item_itemsite_id_itemsite_leadtime',\n        'item_itemsite_id_itemsite_location_id',\n        'item_itemsite_id_itemsite_loccntrl',\n        'item_listprice',\n        'item_itemsite_id_itemsite_stocked',\n        'item_itemsite_id_itemsite_perishable'\n        \n    ];\n    \n    var state = true;\n    \n    \n   _this.saveBtn.show();    \n   \n   \n    switch(it) {\n        case 'K':\n           _this.saveBtn.hide();\n            return;\n            \n        case 'R': // refrence\n            state = false;\n            break;\n            \n        case 'P': // purchased..\n\n            // must have\n            break;\n    }\n            \n            \n    Roo.each(p_req, function(n) {\n        var ff = _this.form.findField(n);\n        ff.allowBlank = !state;\n        ff.actionMode = 'fieldEl';\n        ff.hideMode = 'display';\n        state ? ff.show() : ff.hide(); \n        \n    });\n           \n           \n}\n",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "xtype": "SimpleStore",
+                                                    "|data": "[ \n    [ 'P', \"Purchased (eg. a standard product)\"],\n    [ 'R' , \"Reference (Non-Product)\"],\n    [ 'K', \"Kit (made up of products)\"]  \n]\n",
+                                                    "|fields": "[  'ftype', 'fname']",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "displayField": "classcode_code",
+                                            "editable": false,
+                                            "emptyText": "Select classcode",
+                                            "fieldLabel": "Class",
+                                            "forceSelection": true,
+                                            "hiddenName": "item_classcode_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "item_classcode_id_classcode_code",
+                                            "pageSize": 20,
+                                            "qtip": "Select classcode",
+                                            "queryParam": "",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{classcode_code}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "classcode_id",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/classcode.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"classcode_code\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "fieldLabel": "Item comments",
+                                            "height": 100,
+                                            "name": "item_comments",
+                                            "width": 200,
+                                            "xtype": "TextArea",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Item sold",
+                                            "inputValue": "true",
+                                            "name": "item_sold",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Item active",
+                                            "inputValue": "true",
+                                            "name": "item_active",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "add": "function (combo)\n{\n    Pman.Dialog.XtupleProdcat.show({prodcat_id : 0});\n}",
+                                                "edit": "function (combo, record)\n{\n    var s = _this.form.findField('item_prodcat_id').getValue() * 1;\n    if(s < 1){\n        Roo.MessageBox.alert('Error','Please select a account assignment');\n        return;\n    }\n    Pman.Dialog.XtupleProdcat.show({prodcat_id : s});\n}"
+                                            },
+                                            "allowBlank": false,
+                                            "alwaysQuery": true,
+                                            "displayField": "prodcat_code",
+                                            "editable": false,
+                                            "emptyText": "Select Category",
+                                            "fieldLabel": "Product Category",
+                                            "forceSelection": true,
+                                            "hiddenName": "item_prodcat_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "item_prodcat_id_prodcat_code",
+                                            "pageSize": 20,
+                                            "qtip": "Select prodcat",
+                                            "queryParam": "",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{prodcat_code}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "prodcat_id",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "xtype": "Store",
+                                                    "|xns": "Roo.data",
+                                                    "remoteSort": true,
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/prodcat.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"prodcat_code\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "fieldLabel": "Sales Account",
+                                            "name": "item_salesaccnt",
+                                            "xtype": "DisplayField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Item listprice",
+                                            "name": "item_listprice",
+                                            "width": 200,
+                                            "xtype": "NumberField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "legend": "Standard Cost",
+                                            "style": "width:320px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "allowBlank": false,
+                                                    "displayField": "curr_name",
+                                                    "editable": false,
+                                                    "emptyText": "Select Currency",
+                                                    "fieldLabel": "Currency",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "item_itemcost_id_itemcost_curr_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "curr_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select Currency",
+                                                    "queryParam": "query[curr_name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "curr_id",
+                                                    "width": 200,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "xtype": "HttpProxy",
+                                                                    "method": "GET",
+                                                                    "|xns": "Roo.data",
+                                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "xtype": "JsonReader",
+                                                                    "|xns": "Roo.data",
+                                                                    "id": "curr_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "allowBlank": false,
+                                                    "fieldLabel": "Value",
+                                                    "name": "item_itemcost_id_itemcost_actcost",
+                                                    "width": 200,
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "labelWidth": 120,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "allowBlank": false,
+                                            "fieldLabel": "Reorder Level",
+                                            "name": "item_itemsite_id_itemsite_reorderlevel",
+                                            "width": 200,
+                                            "xtype": "NumberField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "fieldLabel": "Lead time (Days)",
+                                            "name": "item_itemsite_id_itemsite_leadtime",
+                                            "width": 200,
+                                            "xtype": "NumberField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "displayField": "fname",
+                                            "editable": false,
+                                            "fieldLabel": "Control Method",
+                                            "hiddenName": "item_itemsite_id_itemsite_controlmethod",
+                                            "listWidth": 200,
+                                            "mode": "local",
+                                            "name": "item_itemsite_id_itemsite_controlmethod_name",
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{fname}</b> </div>",
+                                            "triggerAction": "all",
+                                            "valueField": "ftype",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "xtype": "SimpleStore",
+                                                    "|data": "[ \n    [ 'N', \"None\"],\n    [ 'R' , \"Regular\"]\n]\n",
+                                                    "|fields": "[  'ftype', 'fname']",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "displayField": "plancode_name",
+                                            "editable": false,
+                                            "emptyText": "Select plancode",
+                                            "fieldLabel": "Planner Code",
+                                            "forceSelection": true,
+                                            "hiddenName": "item_itemsite_id_itemsite_plancode_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "plancode_name",
+                                            "pageSize": 20,
+                                            "qtip": "Select plancode",
+                                            "queryParam": "",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{plancode_name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "plancode_id",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "xtype": "Store",
+                                                    "|xns": "Roo.data",
+                                                    "remoteSort": true,
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/plancode.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"plancode_code\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "displayField": "costcat_code",
+                                            "editable": false,
+                                            "emptyText": "Select costcat",
+                                            "fieldLabel": "Costcat",
+                                            "forceSelection": true,
+                                            "hiddenName": "item_itemsite_id_itemsite_costcat_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "costcat_code",
+                                            "pageSize": 20,
+                                            "qtip": "Select costcat",
+                                            "queryParam": "",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{costcat_code}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "costcat_id",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "xtype": "Store",
+                                                    "|xns": "Roo.data",
+                                                    "remoteSort": true,
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/costcat.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"costcat_code\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "fieldLabel": "Active",
+                                            "inputValue": "true",
+                                            "name": "item_itemsite_id_itemsite_active",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Sold",
+                                            "inputValue": "true",
+                                            "name": "item_itemsite_id_itemsite_sold",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Stocked",
+                                            "inputValue": "true",
+                                            "name": "item_itemsite_id_itemsite_stocked",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Perishable",
+                                            "inputValue": "true",
+                                            "name": "item_itemsite_id_itemsite_perishable",
+                                            "valueOff": 0,
+                                            "width": 75,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Multi Location",
+                                            "inputValue": "true",
+                                            "name": "item_itemsite_id_itemsite_loccntrl",
+                                            "valueOff": 0,
+                                            "width": 100,
+                                            "xtype": "Checkbox",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "displayField": "location_name",
+                                            "editable": true,
+                                            "emptyText": "Default Location",
+                                            "fieldLabel": "Default Location",
+                                            "forceSelection": true,
+                                            "hiddenName": "item_itemsite_id_itemsite_location_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "location_name",
+                                            "pageSize": 200,
+                                            "qtip": "Select terms",
+                                            "queryParam": "query[location_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": false,
+                                            "valueField": "location_id",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n     o.params._notinternalcompany = 1;\n     o.params.location_restrict = 0;\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "location_id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "item_id",
+                                    "width": 75,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "_update_related",
+                                    "value": 1,
+                                    "width": 75,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n  //  _this.dialog.el.mask(\"Saving\");\n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = this;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleItem.js b/Pman.Dialog.XtupleItem.js
new file mode 100644 (file)
index 0000000..8d67874
--- /dev/null
@@ -0,0 +1,740 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleItem = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 520,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create item",
+            width : 800,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       _this.form.findField('item_number').el.dom.readOnly = true;
+                                       _this.form.findField('item_type').disabled = true; 
+                                       
+                                       if(_this.data.item_id * 1 > 0){
+                                            
+                                            this.load({ 
+                                                method: 'GET', 
+                                                params: {
+                                                     '_id' : _this.data.item_id,
+                                                     '_with_itemsite' : 1,
+                                                     '_with_itemcost' : 1,
+                                                     '_with_prodcat' : 1 ,
+                                                     '_with_salesaccnt' : 1 
+                                                }
+                                            });
+                                            return;
+                                       }
+                                       // if it's new..
+                                       _this.form.findField('item_number').el.dom.readOnly = false;
+                                       _this.form.findField('item_type').disabled = false; 
+                                       _this.form.findField('item_salesaccnt').setValue('');
+                                       
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                       _this.form.findField('item_type').showHide();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                         
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            labelWidth : 120,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/item.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'SKU',
+                                    name : 'item_number',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Description',
+                                    name : 'item_descrip1',
+                                    width : 400
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Description (2)',
+                                    name : 'item_descrip2',
+                                    width : 400
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    labelWidth : 120,
+                                    items : [
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                beforeselect : function (combo, record, index)
+                                                {
+                                                    (function() { combo.showHide(); }).defer(100);
+                                                }
+                                            },
+                                            allowBlank : false,
+                                            displayField : 'fname',
+                                            editable : false,
+                                            emptyText : "Select Type",
+                                            fieldLabel : 'Type',
+                                            hiddenName : 'item_type',
+                                            listWidth : 200,
+                                            mode : 'local',
+                                            name : 'item_type_name',
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{fname}</b> </div>',
+                                            triggerAction : 'all',
+                                            valueField : 'ftype',
+                                            width : 200,
+                                            showHide : function() {
+                                            
+                                                var it = this.getValue();
+                                               
+                                                var p_req = [ 
+                                                    'item_itemcost_id_itemcost_curr_id',
+                                                    'item_itemcost_id_itemcost_actcost',
+                                                    'item_itemsite_id_itemsite_reorderlevel',
+                                                    'item_itemsite_id_itemsite_leadtime',
+                                                    'item_itemsite_id_itemsite_location_id',
+                                                    'item_itemsite_id_itemsite_loccntrl',
+                                                    'item_listprice',
+                                                    'item_itemsite_id_itemsite_stocked',
+                                                    'item_itemsite_id_itemsite_perishable'
+                                                    
+                                                ];
+                                                
+                                                var state = true;
+                                                
+                                                
+                                               _this.saveBtn.show();    
+                                               
+                                               
+                                                switch(it) {
+                                                    case 'K':
+                                                       _this.saveBtn.hide();
+                                                        return;
+                                                        
+                                                    case 'R': // refrence
+                                                        state = false;
+                                                        break;
+                                                        
+                                                    case 'P': // purchased..
+                                            
+                                                        // must have
+                                                        break;
+                                                }
+                                                        
+                                                        
+                                                Roo.each(p_req, function(n) {
+                                                    var ff = _this.form.findField(n);
+                                                    ff.allowBlank = !state;
+                                                    ff.actionMode = 'fieldEl';
+                                                    ff.hideMode = 'display';
+                                                    state ? ff.show() : ff.hide(); 
+                                                    
+                                                });
+                                                       
+                                                       
+                                            },
+                                            store : {
+                                                xtype: 'SimpleStore',
+                                                xns: Roo.data,
+                                                data : [ 
+                                                    [ 'P', "Purchased (eg. a standard product)"],
+                                                    [ 'R' , "Reference (Non-Product)"],
+                                                    [ 'K', "Kit (made up of products)"]  
+                                                ],
+                                                fields : [  'ftype', 'fname']
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            displayField : 'classcode_code',
+                                            editable : false,
+                                            emptyText : "Select classcode",
+                                            fieldLabel : 'Class',
+                                            forceSelection : true,
+                                            hiddenName : 'item_classcode_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'item_classcode_id_classcode_code',
+                                            pageSize : 20,
+                                            qtip : "Select classcode",
+                                            queryParam : '',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{classcode_code}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'classcode_id',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/classcode.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"classcode_code","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'TextArea',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Item comments',
+                                            height : 100,
+                                            name : 'item_comments',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Item sold',
+                                            inputValue : 'true',
+                                            name : 'item_sold',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Item active',
+                                            inputValue : 'true',
+                                            name : 'item_active',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                add : function (combo)
+                                                {
+                                                    Pman.Dialog.XtupleProdcat.show({prodcat_id : 0});
+                                                },
+                                                edit : function (combo, record)
+                                                {
+                                                    var s = _this.form.findField('item_prodcat_id').getValue() * 1;
+                                                    if(s < 1){
+                                                        Roo.MessageBox.alert('Error','Please select a account assignment');
+                                                        return;
+                                                    }
+                                                    Pman.Dialog.XtupleProdcat.show({prodcat_id : s});
+                                                }
+                                            },
+                                            allowBlank : false,
+                                            alwaysQuery : true,
+                                            displayField : 'prodcat_code',
+                                            editable : false,
+                                            emptyText : "Select Category",
+                                            fieldLabel : 'Product Category',
+                                            forceSelection : true,
+                                            hiddenName : 'item_prodcat_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'item_prodcat_id_prodcat_code',
+                                            pageSize : 20,
+                                            qtip : "Select prodcat",
+                                            queryParam : '',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{prodcat_code}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'prodcat_id',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/prodcat.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"prodcat_code","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'DisplayField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Sales Account',
+                                            name : 'item_salesaccnt'
+                                        },
+                                        {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Item listprice',
+                                            name : 'item_listprice',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Standard Cost",
+                                            style : 'width:320px',
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    allowBlank : false,
+                                                    displayField : 'curr_name',
+                                                    editable : false,
+                                                    emptyText : "Select Currency",
+                                                    fieldLabel : 'Currency',
+                                                    forceSelection : true,
+                                                    hiddenName : 'item_itemcost_id_itemcost_curr_id',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'curr_name',
+                                                    pageSize : 20,
+                                                    qtip : "Select Currency",
+                                                    queryParam : 'query[curr_name]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                                    triggerAction : 'all',
+                                                    typeAhead : true,
+                                                    valueField : 'curr_id',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                // set more here
+                                                               
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/curr_symbol.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'curr_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                                        }
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'NumberField',
+                                                    xns: Roo.form,
+                                                    allowBlank : false,
+                                                    fieldLabel : 'Value',
+                                                    name : 'item_itemcost_id_itemcost_actcost',
+                                                    width : 200
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    labelWidth : 120,
+                                    items : [
+                                        {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            fieldLabel : 'Reorder Level',
+                                            name : 'item_itemsite_id_itemsite_reorderlevel',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            fieldLabel : 'Lead time (Days)',
+                                            name : 'item_itemsite_id_itemsite_leadtime',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            displayField : 'fname',
+                                            editable : false,
+                                            fieldLabel : 'Control Method',
+                                            hiddenName : 'item_itemsite_id_itemsite_controlmethod',
+                                            listWidth : 200,
+                                            mode : 'local',
+                                            name : 'item_itemsite_id_itemsite_controlmethod_name',
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{fname}</b> </div>',
+                                            triggerAction : 'all',
+                                            valueField : 'ftype',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'SimpleStore',
+                                                xns: Roo.data,
+                                                data : [ 
+                                                    [ 'N', "None"],
+                                                    [ 'R' , "Regular"]
+                                                ],
+                                                fields : [  'ftype', 'fname']
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            displayField : 'plancode_name',
+                                            editable : false,
+                                            emptyText : "Select plancode",
+                                            fieldLabel : 'Planner Code',
+                                            forceSelection : true,
+                                            hiddenName : 'item_itemsite_id_itemsite_plancode_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'plancode_name',
+                                            pageSize : 20,
+                                            qtip : "Select plancode",
+                                            queryParam : '',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{plancode_name}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'plancode_id',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/plancode.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"plancode_code","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            displayField : 'costcat_code',
+                                            editable : false,
+                                            emptyText : "Select costcat",
+                                            fieldLabel : 'Costcat',
+                                            forceSelection : true,
+                                            hiddenName : 'item_itemsite_id_itemsite_costcat_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'costcat_code',
+                                            pageSize : 20,
+                                            qtip : "Select costcat",
+                                            queryParam : '',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{costcat_code}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'costcat_id',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'id' },
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                    }
+                                                },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/costcat.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"id","type":"int"},{"name":"costcat_code","type":"string"}]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Active',
+                                            inputValue : 'true',
+                                            name : 'item_itemsite_id_itemsite_active',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Sold',
+                                            inputValue : 'true',
+                                            name : 'item_itemsite_id_itemsite_sold',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Stocked',
+                                            inputValue : 'true',
+                                            name : 'item_itemsite_id_itemsite_stocked',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Perishable',
+                                            inputValue : 'true',
+                                            name : 'item_itemsite_id_itemsite_perishable',
+                                            valueOff : 0,
+                                            width : 75
+                                        },
+                                        {
+                                            xtype: 'Checkbox',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Multi Location',
+                                            inputValue : 'true',
+                                            name : 'item_itemsite_id_itemsite_loccntrl',
+                                            valueOff : 0,
+                                            width : 100
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            displayField : 'location_name',
+                                            editable : true,
+                                            emptyText : "Default Location",
+                                            fieldLabel : 'Default Location',
+                                            forceSelection : true,
+                                            hiddenName : 'item_itemsite_id_itemsite_location_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'location_name',
+                                            pageSize : 200,
+                                            qtip : "Select terms",
+                                            queryParam : 'query[location_name]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : false,
+                                            valueField : 'location_id',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                         o.params.location_netable = 1;
+                                                         o.params._notinternalcompany = 1;
+                                                         o.params.location_restrict = 0;
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/location.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'location_id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"location_id","type":"int"},"location_name"]
+                                                }
+                                            }
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'item_id',
+                                    width : 75
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : '_update_related',
+                                    value : 1,
+                                    width : 75
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                          //  _this.dialog.el.mask("Saving");
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = this;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleLocation.bjs b/Pman.Dialog.XtupleLocation.bjs
new file mode 100644 (file)
index 0000000..3427d28
--- /dev/null
@@ -0,0 +1,139 @@
+{
+    "id": "roo-file-259",
+    "name": "Pman.Dialog.XtupleLocation",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleLocation.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 200,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create location",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n \n        if (_this.data.location_id) {\n            this.load({ method: 'GET', params: { '_id' : _this.data.location_id }});\n        }\n        \n       return;\n    }\n    if (action.type == 'load') {\n \n        return;\n    }\n    if (action.type =='submit') {\n    \n \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/location.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "fieldLabel": "Name",
+                                    "name": "location_name",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Description",
+                                    "name": "location_descrip",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "emptyText": "Select custinfo",
+                                    "fieldLabel": "Customer",
+                                    "forceSelection": true,
+                                    "hiddenName": "location_cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "location_cust_id_cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select custinfo",
+                                    "queryParam": "query[cust_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> ({cust_number}) </div>",
+                                    "triggerAction": "all",
+                                    "valueField": "cust_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"cust_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "location_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n \n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleLocation.js b/Pman.Dialog.XtupleLocation.js
new file mode 100644 (file)
index 0000000..1cac018
--- /dev/null
@@ -0,0 +1,193 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleLocation = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 200,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create location",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                 
+                                        if (_this.data.location_id) {
+                                            this.load({ method: 'GET', params: { '_id' : _this.data.location_id }});
+                                        }
+                                        
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                 
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                 
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/location.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Name',
+                                    name : 'location_name',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Description',
+                                    name : 'location_descrip',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'cust_name',
+                                    editable : true,
+                                    emptyText : "Select custinfo",
+                                    fieldLabel : 'Customer',
+                                    forceSelection : true,
+                                    hiddenName : 'location_cust_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'location_cust_id_cust_name',
+                                    pageSize : 20,
+                                    qtip : "Select custinfo",
+                                    queryParam : 'query[cust_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> ({cust_number}) </div>',
+                                    triggerAction : 'all',
+                                    valueField : 'cust_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/custinfo.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"id","type":"int"},{"name":"cust_name","type":"string"}]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'location_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                         
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleMiscellaneousCheck.bjs b/Pman.Dialog.XtupleMiscellaneousCheck.bjs
new file mode 100644 (file)
index 0000000..d8f7f8c
--- /dev/null
@@ -0,0 +1,268 @@
+{
+    "id": "roo-file-15",
+    "name": "Pman.Dialog.XtupleMiscellaneousCheck",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleMiscellaneousCheck.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 350,
+            "modal": true,
+            "resizable": false,
+            "title": "Create Miscellaneous Check",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       if(_this.data.checkhead_id){\n           _this.dialog.el.mask(\"Loading\");\n           this.load({ method: 'GET', params: { '_id' : _this.data.checkhead_id }});\n           return;\n       }\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "labelWidth": 150,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/checkhead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Customer",
+                                    "name": "cust_name",
+                                    "readOnly": true,
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Apply To Credit Memo",
+                                    "name": "cmhead_number",
+                                    "readOnly": true,
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "disabled": true,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select Currency",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "checkhead_curr_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "checkhead_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Currency",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "curr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "allowDecimals": true,
+                                    "decimalPrecision": 2,
+                                    "fieldLabel": "Amount",
+                                    "name": "checkhead_amount",
+                                    "width": 200,
+                                    "xtype": "NumberField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "bankaccnt_name",
+                                    "editable": false,
+                                    "emptyText": "Select Bank Accnt",
+                                    "fieldLabel": "Post to",
+                                    "forceSelection": true,
+                                    "hiddenName": "checkhead_bankaccnt_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "checkhead_bankaccnt_id_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Bank Accnt",
+                                    "queryParam": "query[bankaccnt_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{bankaccnt_name} - {bankaccnt_descrip}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "bankaccnt_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'DESC', field: 'bankaccnt_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/bankaccnt.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "bankaccnt_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"bankaccnt_id\",\"type\":\"int\"},\"bankaccnt_name\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Date",
+                                    "format": "Y-m-d",
+                                    "name": "checkhead_checkdate",
+                                    "width": 200,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Memo",
+                                    "name": "checkhead_for",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Notes",
+                                    "name": "checkhead_notes",
+                                    "width": 300,
+                                    "xtype": "TextArea",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "checkhead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "checkhead_recip_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "checkhead_recip_type",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "aropen_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "checkhead_misc",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "_create_and_post",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "remaining_total",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n   // _this.dialog.el.mask(\"Saving\");\n   var a = _this.form.findField('checkhead_amount').getValue();\n   var r = _this.form.findField('remaining_total').getValue();\n   \n   if(a - r > 0){\n        Roo.MessageBox.alert(\"Error\", \"You must enter an amount less than or equal to the credit memo! The amount remaining of this credit memo is \" + r);\n        _this.form.findField('checkhead_amount').setValue(r);\n        return;\n   }\n   \n   _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleMiscellaneousCheck.js b/Pman.Dialog.XtupleMiscellaneousCheck.js
new file mode 100644 (file)
index 0000000..a4e3914
--- /dev/null
@@ -0,0 +1,332 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleMiscellaneousCheck = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 350,
+            modal : true,
+            resizable : false,
+            title : "Create Miscellaneous Check",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       if(_this.data.checkhead_id){
+                                           _this.dialog.el.mask("Loading");
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.checkhead_id }});
+                                           return;
+                                       }
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            labelWidth : 150,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/checkhead.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Customer',
+                                    name : 'cust_name',
+                                    readOnly : true,
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Apply To Credit Memo',
+                                    name : 'cmhead_number',
+                                    readOnly : true,
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    disabled : true,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select Currency",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'checkhead_curr_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'checkhead_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select Currency",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                               
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'curr_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'NumberField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    allowDecimals : true,
+                                    decimalPrecision : 2,
+                                    fieldLabel : 'Amount',
+                                    name : 'checkhead_amount',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'bankaccnt_name',
+                                    editable : false,
+                                    emptyText : "Select Bank Accnt",
+                                    fieldLabel : 'Post to',
+                                    forceSelection : true,
+                                    hiddenName : 'checkhead_bankaccnt_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'checkhead_bankaccnt_id_name',
+                                    pageSize : 20,
+                                    qtip : "Select Bank Accnt",
+                                    queryParam : 'query[bankaccnt_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{bankaccnt_name} - {bankaccnt_descrip}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'bankaccnt_id',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                               
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'DESC', field: 'bankaccnt_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/bankaccnt.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'bankaccnt_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"bankaccnt_id","type":"int"},"bankaccnt_name"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Date',
+                                    format : 'Y-m-d',
+                                    name : 'checkhead_checkdate',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Memo',
+                                    name : 'checkhead_for',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextArea',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Notes',
+                                    name : 'checkhead_notes',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'checkhead_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'checkhead_recip_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'checkhead_recip_type'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'aropen_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'checkhead_misc'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : '_create_and_post'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'remaining_total'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                           // _this.dialog.el.mask("Saving");
+                           var a = _this.form.findField('checkhead_amount').getValue();
+                           var r = _this.form.findField('remaining_total').getValue();
+                           
+                           if(a - r > 0){
+                                Roo.MessageBox.alert("Error", "You must enter an amount less than or equal to the credit memo! The amount remaining of this credit memo is " + r);
+                                _this.form.findField('checkhead_amount').setValue(r);
+                                return;
+                           }
+                           
+                           _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtuplePriceList.bjs b/Pman.Dialog.XtuplePriceList.bjs
new file mode 100644 (file)
index 0000000..4db90f1
--- /dev/null
@@ -0,0 +1,159 @@
+{
+    "id": "roo-file-13",
+    "name": "Pman.Dialog.XtuplePriceList",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtuplePriceList.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 300,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create Price List",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n\n       \n       if (_this.data.ipshead_id) { \n           this.load({ method: 'GET', params: { '_id' : _this.data.ipshead_id }});\n           return;\n       }\n       this.setValues({\n            ipshead_effective : new Date(1970,1,1),\n            ipshead_expires :new Date(2100,1,1)\n\n       });\n       \n       \n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/ipshead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Name",
+                                    "name": "ipshead_name",
+                                    "width": 250,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Description",
+                                    "height": 80,
+                                    "name": "ipshead_descrip",
+                                    "width": 250,
+                                    "xtype": "TextArea",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select currency",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "ipshead_curr_id",
+                                    "listWidth": 150,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "ipshead_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select curr_symbol",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "Store",
+                                            "|xns": "Roo.data",
+                                            "remoteSort": true,
+                                            "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"curr_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "altFormats": "Y-m-d",
+                                    "fieldLabel": "Effective",
+                                    "format": "d/M/Y",
+                                    "name": "ipshead_effective",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|useIso": "true",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "altFormats": "Y-m-d",
+                                    "fieldLabel": "Expires",
+                                    "format": "d/M/Y",
+                                    "name": "ipshead_expires",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|useIso": "true\n",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n    //_this.dialog.el.mask(\"Saving\");\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtuplePriceList.js b/Pman.Dialog.XtuplePriceList.js
new file mode 100644 (file)
index 0000000..bf1b42b
--- /dev/null
@@ -0,0 +1,222 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtuplePriceList = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 300,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create Price List",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                
+                                       
+                                       if (_this.data.ipshead_id) { 
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.ipshead_id }});
+                                           return;
+                                       }
+                                       this.setValues({
+                                            ipshead_effective : new Date(1970,1,1),
+                                            ipshead_expires :new Date(2100,1,1)
+                                
+                                       });
+                                       
+                                       
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/ipshead.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Name',
+                                    name : 'ipshead_name',
+                                    width : 250
+                                },
+                                {
+                                    xtype: 'TextArea',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Description',
+                                    height : 80,
+                                    name : 'ipshead_descrip',
+                                    width : 250
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select currency",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'ipshead_curr_id',
+                                    listWidth : 150,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'ipshead_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select curr_symbol",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 150,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'id' },
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                            }
+                                        },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"id","type":"int"},{"name":"curr_name","type":"string"}]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    altFormats : 'Y-m-d',
+                                    fieldLabel : 'Effective',
+                                    format : 'd/M/Y',
+                                    name : 'ipshead_effective',
+                                    width : 150,
+                                    useIso : true
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    altFormats : 'Y-m-d',
+                                    fieldLabel : 'Expires',
+                                    format : 'd/M/Y',
+                                    name : 'ipshead_expires',
+                                    width : 150,
+                                    useIso : true
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                            //_this.dialog.el.mask("Saving");
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleProdcat.bjs b/Pman.Dialog.XtupleProdcat.bjs
new file mode 100644 (file)
index 0000000..57f590e
--- /dev/null
@@ -0,0 +1,347 @@
+{
+    "id": "roo-file-18",
+    "name": "Pman.Dialog.XtupleProdcat",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleProdcat.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 400,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create Product Category",
+            "width": 450,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if(_this.data.prodcat_id){\n            _this.dialog.el.mask(\"Loading\");\n            this.load({ method: 'GET', params: { '_id' : _this.data.prodcat_id, '_with_salesaccnt' : 1 }}); \n        }\n       \n       _this.form.findField('salesaccnt_sales_accnt_id_descrip').setValue('');\n       _this.form.findField('salesaccnt_credit_accnt_id_descrip').setValue('');\n       _this.form.findField('salesaccnt_cos_accnt_id_descrip').setValue('');\n       return;\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "labelWidth": 150,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/Prodcat.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "legend": "Product Category Detail",
+                                    "style": "width:380px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "allowBlank": false,
+                                            "fieldLabel": "Category Code",
+                                            "name": "prodcat_code",
+                                            "width": 200,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": false,
+                                            "fieldLabel": "Category Description",
+                                            "name": "prodcat_descrip",
+                                            "width": 200,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "legend": "Account Setting",
+                                    "style": "width:380px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "labelWidth": 150,
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n    _this.form.findField('salesaccnt_sales_accnt_id_descrip').setValue(record.data.accnt_descrip);\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "accnt_name",
+                                                    "editable": true,
+                                                    "emptyText": "Select Account",
+                                                    "fieldLabel": "Inventory Sales Account",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "salesaccnt_sales_accnt_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "salesaccnt_sales_accnt_id_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select Account",
+                                                    "queryParam": "search[name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{accnt_name} ( {accnt_descrip} )</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "accnt_id",
+                                                    "width": 200,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.accnt_active = 1;\n    o.params.accnt_type = 'R';\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'accnt_id' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/accnt.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "accnt_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"accnt_id\",\"type\":\"int\"},{\"name\":\"accnt_descrip\",\"type\":\"string\"}]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "height": 30,
+                                            "hideLabels": true,
+                                            "style": "margin-left:155px;",
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "name": "salesaccnt_sales_accnt_id_descrip",
+                                                    "width": 200,
+                                                    "xtype": "DisplayField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelWidth": 150,
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n    _this.form.findField('salesaccnt_credit_accnt_id_descrip').setValue(record.data.accnt_descrip);\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "accnt_name",
+                                                    "editable": true,
+                                                    "emptyText": "Select Account",
+                                                    "fieldLabel": "Credit Memo Account",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "salesaccnt_credit_accnt_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "salesaccnt_credit_accnt_id_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select Account",
+                                                    "queryParam": "search[name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{accnt_name} ( {accnt_descrip} )</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "accnt_id",
+                                                    "width": 200,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.accnt_active = 1;\n    o.params.accnt_type = 'R';\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'accnt_id' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/accnt.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "accnt_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"accnt_id\",\"type\":\"int\"},{\"name\":\"accnt_descrip\",\"type\":\"string\"}]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "height": 30,
+                                            "hideLabels": true,
+                                            "style": "margin-left:155px;",
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "name": "salesaccnt_credit_accnt_id_descrip",
+                                                    "width": 200,
+                                                    "xtype": "DisplayField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelWidth": 150,
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n    _this.form.findField('salesaccnt_cos_accnt_id_descrip').setValue(record.data.accnt_descrip);\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "accnt_name",
+                                                    "editable": true,
+                                                    "emptyText": "Select Account",
+                                                    "fieldLabel": "Cost of Sales Account",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "salesaccnt_cos_accnt_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "salesaccnt_cos_accnt_id_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select Account",
+                                                    "queryParam": "search[name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{accnt_name} ( {accnt_descrip} )</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "accnt_id",
+                                                    "width": 200,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.accnt_active = 1;\n    o.params.accnt_type = 'E';\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'accnt_id' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/accnt.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "accnt_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"accnt_id\",\"type\":\"int\"},{\"name\":\"accnt_descrip\",\"type\":\"string\"}]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "height": 30,
+                                            "hideLabels": true,
+                                            "style": "margin-left:155px;",
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "name": "salesaccnt_cos_accnt_id_descrip",
+                                                    "width": 200,
+                                                    "xtype": "DisplayField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "prodcat_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "salesaccnt_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n   // _this.dialog.el.mask(\"Saving\");\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleProdcat.js b/Pman.Dialog.XtupleProdcat.js
new file mode 100644 (file)
index 0000000..117f17b
--- /dev/null
@@ -0,0 +1,411 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleProdcat = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 400,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create Product Category",
+            width : 450,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if(_this.data.prodcat_id){
+                                            _this.dialog.el.mask("Loading");
+                                            this.load({ method: 'GET', params: { '_id' : _this.data.prodcat_id, '_with_salesaccnt' : 1 }}); 
+                                        }
+                                       
+                                       _this.form.findField('salesaccnt_sales_accnt_id_descrip').setValue('');
+                                       _this.form.findField('salesaccnt_credit_accnt_id_descrip').setValue('');
+                                       _this.form.findField('salesaccnt_cos_accnt_id_descrip').setValue('');
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            labelWidth : 150,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/Prodcat.php',
+                            items : [
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Product Category Detail",
+                                    style : 'width:380px',
+                                    items : [
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            fieldLabel : 'Category Code',
+                                            name : 'prodcat_code',
+                                            width : 200
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            allowBlank : false,
+                                            fieldLabel : 'Category Description',
+                                            name : 'prodcat_descrip',
+                                            width : 200
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Account Setting",
+                                    style : 'width:380px',
+                                    items : [
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            labelWidth : 150,
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        beforeselect : function (combo, record, index)
+                                                        {
+                                                            _this.form.findField('salesaccnt_sales_accnt_id_descrip').setValue(record.data.accnt_descrip);
+                                                        }
+                                                    },
+                                                    allowBlank : false,
+                                                    displayField : 'accnt_name',
+                                                    editable : true,
+                                                    emptyText : "Select Account",
+                                                    fieldLabel : 'Inventory Sales Account',
+                                                    forceSelection : true,
+                                                    hiddenName : 'salesaccnt_sales_accnt_id',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'salesaccnt_sales_accnt_id_name',
+                                                    pageSize : 20,
+                                                    qtip : "Select Account",
+                                                    queryParam : 'search[name]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{accnt_name} ( {accnt_descrip} )</b> </div>',
+                                                    triggerAction : 'all',
+                                                    typeAhead : true,
+                                                    valueField : 'accnt_id',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                // set more here
+                                                                o.params.accnt_active = 1;
+                                                                o.params.accnt_type = 'R';
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'accnt_id' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/accnt.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'accnt_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"accnt_id","type":"int"},{"name":"accnt_descrip","type":"string"}]
+                                                        }
+                                                    }
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            height : 30,
+                                            hideLabels : true,
+                                            style : 'margin-left:155px;',
+                                            items : [
+                                                {
+                                                    xtype: 'DisplayField',
+                                                    xns: Roo.form,
+                                                    name : 'salesaccnt_sales_accnt_id_descrip',
+                                                    width : 200
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            labelWidth : 150,
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        beforeselect : function (combo, record, index)
+                                                        {
+                                                            _this.form.findField('salesaccnt_credit_accnt_id_descrip').setValue(record.data.accnt_descrip);
+                                                        }
+                                                    },
+                                                    allowBlank : false,
+                                                    displayField : 'accnt_name',
+                                                    editable : true,
+                                                    emptyText : "Select Account",
+                                                    fieldLabel : 'Credit Memo Account',
+                                                    forceSelection : true,
+                                                    hiddenName : 'salesaccnt_credit_accnt_id',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'salesaccnt_credit_accnt_id_name',
+                                                    pageSize : 20,
+                                                    qtip : "Select Account",
+                                                    queryParam : 'search[name]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{accnt_name} ( {accnt_descrip} )</b> </div>',
+                                                    triggerAction : 'all',
+                                                    typeAhead : true,
+                                                    valueField : 'accnt_id',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                // set more here
+                                                                o.params.accnt_active = 1;
+                                                                o.params.accnt_type = 'R';
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'accnt_id' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/accnt.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'accnt_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"accnt_id","type":"int"},{"name":"accnt_descrip","type":"string"}]
+                                                        }
+                                                    }
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            height : 30,
+                                            hideLabels : true,
+                                            style : 'margin-left:155px;',
+                                            items : [
+                                                {
+                                                    xtype: 'DisplayField',
+                                                    xns: Roo.form,
+                                                    name : 'salesaccnt_credit_accnt_id_descrip',
+                                                    width : 200
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            labelWidth : 150,
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        beforeselect : function (combo, record, index)
+                                                        {
+                                                            _this.form.findField('salesaccnt_cos_accnt_id_descrip').setValue(record.data.accnt_descrip);
+                                                        }
+                                                    },
+                                                    allowBlank : false,
+                                                    displayField : 'accnt_name',
+                                                    editable : true,
+                                                    emptyText : "Select Account",
+                                                    fieldLabel : 'Cost of Sales Account',
+                                                    forceSelection : true,
+                                                    hiddenName : 'salesaccnt_cos_accnt_id',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'salesaccnt_cos_accnt_id_name',
+                                                    pageSize : 20,
+                                                    qtip : "Select Account",
+                                                    queryParam : 'search[name]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{accnt_name} ( {accnt_descrip} )</b> </div>',
+                                                    triggerAction : 'all',
+                                                    typeAhead : true,
+                                                    valueField : 'accnt_id',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                // set more here
+                                                                o.params.accnt_active = 1;
+                                                                o.params.accnt_type = 'E';
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'accnt_id' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/accnt.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'accnt_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"accnt_id","type":"int"},{"name":"accnt_descrip","type":"string"}]
+                                                        }
+                                                    }
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            height : 30,
+                                            hideLabels : true,
+                                            style : 'margin-left:155px;',
+                                            items : [
+                                                {
+                                                    xtype: 'DisplayField',
+                                                    xns: Roo.form,
+                                                    name : 'salesaccnt_cos_accnt_id_descrip',
+                                                    width : 200
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'prodcat_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'salesaccnt_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                           // _this.dialog.el.mask("Saving");
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtuplePurchaseOrder.bjs b/Pman.Dialog.XtuplePurchaseOrder.bjs
new file mode 100644 (file)
index 0000000..37c10a7
--- /dev/null
@@ -0,0 +1,961 @@
+{
+    "id": "roo-file-19",
+    "name": "Pman.Dialog.XtuplePurchaseOrder",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtuplePurchaseOrder.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function () \n{\n       this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 550,
+            "modal": true,
+            "resizable": false,
+            "title": "New Purchase Order",
+            "width": 900,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center",
+                    "alwaysShowTabs": true,
+                    "tabPosition": "top",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "Toolbar",
+                            "*prop": "toolbar",
+                            "items": [
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{\n    var hid = _this.form.findField('pohead_id').getValue();\n\n    if(!hid.length){\n        Roo.MessageBox.alert(\"Error\", \"Please save your purchase order first\"); \n        return false;\n    }\n\n    \n    if (!_this.grid) {\n        _dialog.layout.showPanel(1);\n        doit.defer(500);\n        return;\n    }\n    \n    \n    \n    var doit = function () { \n        new Pman.Download({\n            grid : _this.grid\n        });\n    }\n    doit();\n            \n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Download Purchase Order Items (Excel)",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/save.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.uploadBtn = _self;\n}"
+                                    },
+                                    "text": "Upload Purchase Order",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var hid = _this.form.findField('pohead_id').getValue();\n    \n    if(!hid.length){\n        Roo.MessageBox.alert(\"Error\", \"Please save your purchase order first\"); \n        return false;\n    }\n    Pman.Dialog.Image.show(\n       {\n            timeout : 60000,\n            _url : baseURL+'/Xtuple/Import/PurchaseOrder?' + Roo.urlEncode({'pohead_id' : hid})\n        \n       },\n       function () {\n            if(_this.grid){\n                _this.grid.footer.onClick('first');\n            }\n            Roo.MessageBox.alert(\"Notice\", 'UPLOADED');\n       }\n   );\n}"
+                                                    },
+                                                    "text": "Upload Standard Excel",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n\n    var hid = _this.form.findField('pohead_id').getValue();\n    \n    if(!hid.length){\n        Roo.MessageBox.alert(\"Error\", \"Please save your purchase order first\"); \n        return false;\n    }\n    \n   Pman.Dialog.Image.show(\n   {\n        _url : baseURL+'/Xtuple/Import/AUPurchaseOrder?' + Roo.urlEncode({'pohead_id' :hid})\n        \n   },\n   function (data) {\n       if(_this.grid){\n            _this.grid.footer.onClick('first');\n       }\n       Roo.MessageBox.alert(\"Notice\", 'IMPORTED');\n\n   });\n}"
+                                                    },
+                                                    "text": "Upload AU Import Excel",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "region": "center",
+                    "title": "Order Details",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        _this.uploadBtn.disabled = false;\n        if(!_this.data.pohead_id && Pman.Login.authUser.name.length){\n            _this.saveBtn.show();\n            _this.form.findField('pohead_agent_username').setValue(Pman.Login.authUser.name);\n            _this.form.findField('pohead_orderdate').setValue(new Date());\n            return;\n        }\n        _this.dialog.setTitle(\"Edit Purchase Order\");\n        var params = {\n            '_id' : _this.data.pohead_id\n        }\n        if(_this.data.office){\n            params['_roo_office'] = _this.data.office;\n        }\n        \n        this.load({ method: 'GET', params: params});\n        return;\n    }\n    if (action.type == 'load') {\n        if(_this.data.office){\n            _this.uploadBtn.disabled = true;\n        }\n        _this.saveBtn.hide();\n        if (action.result.data.pohead_status == 'U') {\n            _this.saveBtn.show();\n        }\n        var cn = _this.form.findField('pohead_curr_id');\n        cn.setDisabled(true);\n        if (action.result.data.pohead_id * 1 < 1) {\n            cn.setDisabled(false);\n        }\n        \n        \n        return;\n    }\n    if (action.type =='submit') {\n    \n\n        var cid = this.findField('pohead_id').getValue()*1;\n        if (cid) {\n        \n          _this.dialog.hide();\n        \n             if (_this.callback) {\n                _this.callback.call(_this, _this.form.getValues());\n             }\n             _this.form.reset();\n             return;\n         }\n         Roo.log(action);\n         _this.data.pohead_id = action.result.data.pohead_id;\n         this.fireEvent('actioncomplete', this,   { \n                type: 'setdata', \n                data: { \n                    pohead_id : action.result.data.pohead_id\n                 } \n         });\n\n         \n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n",
+                                "actionfailed": "function (_self, action)\n{\n    _this.dialog.el.unmask();\n    if (action.failureType == 'client') {\n        Roo.MessageBox.alert(\"Error\", \"Please fill in all the required fields\");\n    }\n    if (action.failureType == 'server') {\n        Roo.MessageBox.alert(\"Error\", action.result.errorMsg);\n    }\n    _this.dialog.layout.getRegion('center').showPanel(0);\n\n}"
+                            },
+                            "labelWidth": 200,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Xtuple/Roo/Pohead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "emptyText": "Automatic",
+                                    "fieldLabel": "Order #",
+                                    "name": "pohead_number",
+                                    "readOnly": true,
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Order Date",
+                                    "format": "Y-m-d",
+                                    "name": "pohead_orderdate",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Estimated Arrival Date",
+                                    "format": "Y-m-d",
+                                    "name": "pohead_bg_arrival_est_day",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Estimated Available Date",
+                                    "format": "Y-m-d",
+                                    "name": "pohead_bg_available_est_day",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Latest Estimated Available Date",
+                                    "format": "Y-m-d",
+                                    "name": "pohead_bg_available_latest_day",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "VA",
+                                    "name": "pohead_bg_va",
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Vendor",
+                                    "name": "pohead_vend_id_vend_name",
+                                    "readOnly": true,
+                                    "width": 250,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Status",
+                                    "hiddenName": "pohead_status",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "pohead_status",
+                                    "readOnly": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{fname}</b> </div>",
+                                    "triggerAction": "all",
+                                    "value": "U",
+                                    "valueField": "ftype",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'U', \"Unreleased\"],\n    [ 'O', \"Open\"],\n    [ 'C' , \"Closed\"]\n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select Currency",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_curr_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Currency",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "curr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"curr_id\",\"type\":\"int\"},\n    {\"name\":\"curr_name\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "location_name",
+                                    "editable": true,
+                                    "emptyText": "Select a location",
+                                    "fieldLabel": "Location",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_location_id_location_name",
+                                    "pageSize": 200,
+                                    "qtip": "Select terms",
+                                    "queryParam": "query[location_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "location_id",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "location_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "terms_descrip",
+                                    "editable": false,
+                                    "emptyText": "Select Terms",
+                                    "fieldLabel": "Terms",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_terms_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_terms_id_terms_descrip",
+                                    "pageSize": 20,
+                                    "qtip": "Select Terms",
+                                    "queryParam": "query[terms_descrip]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{terms_descrip}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "terms_id",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'terms_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Terms.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "terms_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"terms_id\",\"type\":\"int\"},\n    {\"name\":\"terms_descrip\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "taxzone_descrip",
+                                    "editable": false,
+                                    "emptyText": "Select Tax Zone",
+                                    "fieldLabel": "Tax Zone",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_taxzone_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_taxzone_id_taxzone_descrip",
+                                    "pageSize": 20,
+                                    "qtip": "Select Tax Zone",
+                                    "queryParam": "query[taxzone_descrip]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxzone_descrip}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "taxzone_id",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'taxzone_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Taxzone.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "taxzone_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"taxzone_id\",\"type\":\"int\"},\n    {\"name\":\"taxzone_descrip\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "displayField": "emp_name",
+                                    "editable": false,
+                                    "emptyText": "Select Purchasing Agent",
+                                    "fieldLabel": "Purchase Agent",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_agent_username",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_agent_username",
+                                    "pageSize": 20,
+                                    "qtip": "Select Purchasing Agent",
+                                    "queryParam": "query[emp_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{emp_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "emp_name",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'emp_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Emp.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "emp_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"emp_id\",\"type\":\"int\"},\n    {\"name\":\"emp_name\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "fieldLabel": "Comments",
+                                    "height": 100,
+                                    "name": "pohead_comments",
+                                    "width": 400,
+                                    "xtype": "TextArea",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "pohead_vend_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "pohead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    \n    \n    var pid = _this.form.findField('pohead_id').getValue() * 1;\n    if (pid < 1) {\n        Roo.MessageBox.alert(\"Save First\", \"Please save the purchase order first, before adding items\");\n        _this.dialog.layout.getRegion('center').showPanel(0);\n        return;\n    }\n    \n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "poitem",
+                    "title": "Order Items",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_descrip1",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o){\n    o.params = o.params || {};\n    var hid = _this.form.findField('pohead_id').getValue();\n    \n    if(!hid.length){\n        return false;\n    }\n    \n    o.params.poitem_pohead_id = hid;\n    o.params._with_item = 1;\n    \n\n    o.params._roo_office = _this.data.office ? _this.data.office:  baseURL.split('/').pop().substr(0,2);\n\n}\n",
+                                        "load": "function (_self, records, options)\n{\n    _this.grid.footer.updateSummary();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'poitem_id', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "timeout": 90000,
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Xtuple/Roo/Poitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            "id": "poitem_id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'poitem_id',\n        'type': 'int'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "emptyMsg": "No Item found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|updateSummary": "function() {\n\r\n    var f = this;\r\n    new Pman.Request({\r\n        url : baseURL + '/Xtuple/Roo/Poitem',\r\n        method : 'GET',\r\n        params : {\n            _roo_office : _this.data.office,\r\n            _totals : 1,\r\n            poitem_pohead_id : _this.form.findField('pohead_id').getValue()\r\n        },\r\n        success : function(d) {\n            Roo.log(d);\r\n            f.displayEl.update(String.format(\r\n                \"{0} items | Total : {1} {2}\",\r\n                d.data[0].count_item,\r\n                _this.form.findField('pohead_curr_id').el.dom.value,\r\n                d.data[0].totals\r\n            ));\r\n                \r\n        }\r\n    });\r\n\n}\n",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item code",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Item description",
+                                    "width": 150,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "poitem_duedate",
+                                    "header": "Due date",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "poitem_linenumber",
+                                    "header": "Line number",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "poitem_qty_ordered",
+                                    "header": "Ordered",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "poitem_unitprice",
+                                    "header": "Unit price",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? parseFloat(v).toFixed(3) : ''); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "region": "center",
+                    "title": "TX",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "*prop": "east",
+                                    "split": true,
+                                    "width": 550,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.itempanel = this;\n    \n    \n    if (_this.itemgrid) {\n        _this.itemgrid.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "poitem",
+                                    "title": "Items",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.itemgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.itempanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                                "rowclick": "function (_self, rowIndex, e)\n{\n    \n    _this.gltransgrid.footer.onClick('first');\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "item_number",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 600000,\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'byorder',\n            'pohead_number:text' : _this.form.findField('pohead_number').getValue(),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                            },
+                                                            "text": "PO analysis",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "sm",
+                                                    "singleSelect": true,
+                                                    "xtype": "RowSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    var hid = _this.form.findField('pohead_id').getValue();\n    \n    if(!hid.length){\n        return false;\n    }\n    \n    o.params.poitem_pohead_id = hid;\n    \n    o.params._with_item = 1;\n    \n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'poitem_id', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/poitem.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": false,
+                                                    "displayMsg": "Displaying poitem{0} - {1} of {2}",
+                                                    "emptyMsg": "No item found",
+                                                    "pageSize": 25,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "poitem_linenumber",
+                                                    "header": "Line #",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "item_number",
+                                                    "header": "Item #",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "poitem_qty_ordered",
+                                                    "header": "Ordered",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "poitem_qty_received",
+                                                    "header": "Received",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{\n    return String.format('{0}', (v- r.data.poitem_qty_returned)) ;  \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "poitem_unitprice",
+                                                    "header": "Unit Price",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{\n     \n    return String.format('{0}', (v- r.data.poitem_qty_returned) ? parseFloat(v- r.data.poitem_qty_returned).toFixed(3) : '') ;  \n    \n}",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.gltranspanel = this;\n    //if (_this.gltransgrid) {\n    //    _this.gltransgrid.footer.onClick('first');\n    // }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "east",
+                                    "tableName": "Gltrans",
+                                    "title": "Gltrans",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.gltransgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n  //  if (_this.gltranspanel.active) {\n  //     this.footer.onClick('first');\n  //  }\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "gltrans_notes",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "*prop": "sm",
+                                                    "singleSelect": true,
+                                                    "xtype": "RowSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    \n    var s = _this.itemgrid.getSelectionModel().getSelected();\n    if(!s){\n        Roo.MessageBox.alert('Error', 'Please select a item');\n        return false;\n    }\n    \n    o.params._poview = 1;\n    o.params.gltrans_deleted = 0;\n    o.params.gltrans_doctype = 'PO';\n    o.params._linenumber = s.data.poitem_linenumber;\n    o.params._item = s.data.item_number;\n    o.params._ponumber = _this.form.findField('pohead_number').getValue();\n    \n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'gltrans_id', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/gltrans.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": true,
+                                                    "displayMsg": "Displaying gltrans{0} - {1} of {2}",
+                                                    "emptyMsg": "No gltrans found",
+                                                    "pageSize": 25,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo"
+                                                },
+                                                {
+                                                    "*prop": "toolbar",
+                                                    "xtype": "Toolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var pohead_number = _this.form.findField('pohead_number').getValue();\n    var pohead_id = _this.form.findField('pohead_id').getValue();\n        \n    var addv = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/pohead.php',\n            method :'POST',\n            params : {\n                pohead_id : pohead_id,\n                _variance : 1\n                \n            },\n            success : function(res) {\n                Roo.MessageBox.alert('Notice', 'DONE');\n            }\n        });\n    }\n    \n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to add all the variance for \" + pohead_number + \" ?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n\n            addv();\n            return;\n        }\n    ); \n    \n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add All Variance",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var s = _this.gltransgrid.getSelectionModel().getSelected();\n    \n    if(!s){\n        Roo.MessageBox.alert('Error','Please select a transaction');\n        return;\n    }\n    \n    if(s.data.gltrans_misc_id == -1){\n        Roo.MessageBox.alert('Error','Please select a transaction not variance');\n        return;\n    }\n    \n    var addit = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Gltrans.php',\n            method :'POST',\n            params : {\n                gltrans_id : s.data.gltrans_id,\n                _variance : 1\n                \n            },\n            success : function(res) {\n                if(res.data == 0){\n                    Roo.MessageBox.alert('Error','Variance already exist');\n                }\n                _this.gltransgrid.footer.onClick('refresh');\n                \n            }\n        });\n    }\n    \n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to add a variance ?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n\n            addit();\n            return;\n        }\n    ); \n    \n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add Variance",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var s = _this.gltransgrid.getSelectionModel().getSelected();\n    \n    if(!s){\n        Roo.MessageBox.alert('Error','Please select a transaction');\n        return;\n    }\n    \n    if(s.data.gltrans_misc_id != -1){\n        Roo.MessageBox.alert('Error','Just allow to delete the variance');\n        return;\n    }\n    \n    var delit = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Gltrans.php',\n            method :'POST',\n            params : {\n                gltrans_id : s.data.gltrans_id,\n                _del : 1\n                \n            },\n            success : function(res) {\n                _this.gltransgrid.footer.onClick('refresh');\n                \n            }\n        });\n    }\n    \n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to delete ?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n\n            delit();\n            return;\n        }\n    ); \n    \n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Delete Variance",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var pohead_number = _this.form.findField('pohead_number').getValue();\n    var pohead_id = _this.form.findField('pohead_id').getValue();\n        \n    var fixit = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/pohead.php',\n            method :'POST',\n            params : {\n                pohead_id : pohead_id,\n                _unitcost : 1\n                \n            },\n            success : function(res) {\n                Roo.MessageBox.alert('Notice', 'DONE');\n            }\n        });\n    }\n    \n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to fix the unit cost of \" + pohead_number + \" ?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n\n            fixit();\n            return;\n        }\n    ); \n    \n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Fix Unit Cost",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var pohead_number = _this.form.findField('pohead_number').getValue();\n    var pohead_id = _this.form.findField('pohead_id').getValue();\n        \n    var delv = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/pohead.php',\n            method :'POST',\n            params : {\n                pohead_id : pohead_id,\n                _del : 1\n                \n            },\n            success : function(res) {\n                Roo.MessageBox.alert('Notice', 'DONE');\n            }\n        });\n    }\n    \n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to delete the variance on voucher of \" + pohead_number + \" ?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n\n            delv();\n            return;\n        }\n    ); \n    \n    \n}\n"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Delete Varinace on voucher",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_id",
+                                                    "header": "ID",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_date",
+                                                    "header": "Date",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_docnumber",
+                                                    "header": "doc #",
+                                                    "width": 80,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_amount",
+                                                    "header": "Amount",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_notes",
+                                                    "header": "Notes",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n     \n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtuplePurchaseOrder.js b/Pman.Dialog.XtuplePurchaseOrder.js
new file mode 100644 (file)
index 0000000..aa18e6a
--- /dev/null
@@ -0,0 +1,1685 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtuplePurchaseOrder = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function () 
+                {
+                       this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 550,
+            modal : true,
+            resizable : false,
+            title : "New Purchase Order",
+            width : 900,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    title : "Order Details",
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        _this.uploadBtn.disabled = false;
+                                        if(!_this.data.pohead_id && Pman.Login.authUser.name.length){
+                                            _this.saveBtn.show();
+                                            _this.form.findField('pohead_agent_username').setValue(Pman.Login.authUser.name);
+                                            _this.form.findField('pohead_orderdate').setValue(new Date());
+                                            return;
+                                        }
+                                        _this.dialog.setTitle("Edit Purchase Order");
+                                        var params = {
+                                            '_id' : _this.data.pohead_id
+                                        }
+                                        if(_this.data.office){
+                                            params['_roo_office'] = _this.data.office;
+                                        }
+                                        
+                                        this.load({ method: 'GET', params: params});
+                                        return;
+                                    }
+                                    if (action.type == 'load') {
+                                        if(_this.data.office){
+                                            _this.uploadBtn.disabled = true;
+                                        }
+                                        _this.saveBtn.hide();
+                                        if (action.result.data.pohead_status == 'U') {
+                                            _this.saveBtn.show();
+                                        }
+                                        var cn = _this.form.findField('pohead_curr_id');
+                                        cn.setDisabled(true);
+                                        if (action.result.data.pohead_id * 1 < 1) {
+                                            cn.setDisabled(false);
+                                        }
+                                        
+                                        
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                
+                                        var cid = this.findField('pohead_id').getValue()*1;
+                                        if (cid) {
+                                        
+                                          _this.dialog.hide();
+                                        
+                                             if (_this.callback) {
+                                                _this.callback.call(_this, _this.form.getValues());
+                                             }
+                                             _this.form.reset();
+                                             return;
+                                         }
+                                         Roo.log(action);
+                                         _this.data.pohead_id = action.result.data.pohead_id;
+                                         this.fireEvent('actioncomplete', this,   { 
+                                                type: 'setdata', 
+                                                data: { 
+                                                    pohead_id : action.result.data.pohead_id
+                                                 } 
+                                         });
+                                
+                                         
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                },
+                                actionfailed : function (_self, action)
+                                {
+                                    _this.dialog.el.unmask();
+                                    if (action.failureType == 'client') {
+                                        Roo.MessageBox.alert("Error", "Please fill in all the required fields");
+                                    }
+                                    if (action.failureType == 'server') {
+                                        Roo.MessageBox.alert("Error", action.result.errorMsg);
+                                    }
+                                    _this.dialog.layout.getRegion('center').showPanel(0);
+                                
+                                }
+                            },
+                            labelWidth : 200,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Xtuple/Roo/Pohead.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    emptyText : "Automatic",
+                                    fieldLabel : 'Order #',
+                                    name : 'pohead_number',
+                                    readOnly : true,
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Order Date',
+                                    format : 'Y-m-d',
+                                    name : 'pohead_orderdate',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Estimated Arrival Date',
+                                    format : 'Y-m-d',
+                                    name : 'pohead_bg_arrival_est_day',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Estimated Available Date',
+                                    format : 'Y-m-d',
+                                    name : 'pohead_bg_available_est_day',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Latest Estimated Available Date',
+                                    format : 'Y-m-d',
+                                    name : 'pohead_bg_available_latest_day',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'VA',
+                                    name : 'pohead_bg_va',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Vendor',
+                                    name : 'pohead_vend_id_vend_name',
+                                    readOnly : true,
+                                    width : 250
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'fname',
+                                    editable : false,
+                                    fieldLabel : 'Status',
+                                    hiddenName : 'pohead_status',
+                                    listWidth : 200,
+                                    mode : 'local',
+                                    name : 'pohead_status',
+                                    readOnly : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{fname}</b> </div>',
+                                    triggerAction : 'all',
+                                    value : "U",
+                                    valueField : 'ftype',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'SimpleStore',
+                                        xns: Roo.data,
+                                        data : [ 
+                                            [ 'U', "Unreleased"],
+                                            [ 'O', "Open"],
+                                            [ 'C' , "Closed"]
+                                        ],
+                                        fields : [  'ftype', 'fname']
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select Currency",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_curr_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select Currency",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'curr_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'curr_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"curr_id","type":"int"},
+                                                {"name":"curr_name","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'location_name',
+                                    editable : true,
+                                    emptyText : "Select a location",
+                                    fieldLabel : 'Location',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_location_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_location_id_location_name',
+                                    pageSize : 200,
+                                    qtip : "Select terms",
+                                    queryParam : 'query[location_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : false,
+                                    valueField : 'location_id',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                                 o.params.location_netable = 1;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'location_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/location.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'location_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"location_id","type":"int"},"location_name"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'terms_descrip',
+                                    editable : false,
+                                    emptyText : "Select Terms",
+                                    fieldLabel : 'Terms',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_terms_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_terms_id_terms_descrip',
+                                    pageSize : 20,
+                                    qtip : "Select Terms",
+                                    queryParam : 'query[terms_descrip]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{terms_descrip}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'terms_id',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'terms_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Terms.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'terms_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"terms_id","type":"int"},
+                                                {"name":"terms_descrip","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'taxzone_descrip',
+                                    editable : false,
+                                    emptyText : "Select Tax Zone",
+                                    fieldLabel : 'Tax Zone',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_taxzone_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_taxzone_id_taxzone_descrip',
+                                    pageSize : 20,
+                                    qtip : "Select Tax Zone",
+                                    queryParam : 'query[taxzone_descrip]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxzone_descrip}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'taxzone_id',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'taxzone_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Taxzone.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'taxzone_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"taxzone_id","type":"int"},
+                                                {"name":"taxzone_descrip","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    displayField : 'emp_name',
+                                    editable : false,
+                                    emptyText : "Select Purchasing Agent",
+                                    fieldLabel : 'Purchase Agent',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_agent_username',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_agent_username',
+                                    pageSize : 20,
+                                    qtip : "Select Purchasing Agent",
+                                    queryParam : 'query[emp_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{emp_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'emp_name',
+                                    width : 250,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'emp_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Emp.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'emp_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"emp_id","type":"int"},
+                                                {"name":"emp_name","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'TextArea',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Comments',
+                                    height : 100,
+                                    name : 'pohead_comments',
+                                    width : 400
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'pohead_vend_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'pohead_id'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            
+                            
+                            var pid = _this.form.findField('pohead_id').getValue() * 1;
+                            if (pid < 1) {
+                                Roo.MessageBox.alert("Save First", "Please save the purchase order first, before adding items");
+                                _this.dialog.layout.getRegion('center').showPanel(0);
+                                return;
+                            }
+                            
+                            if (_this.grid) {
+                                _this.grid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'poitem',
+                    title : "Order Items",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o){
+                                    o.params = o.params || {};
+                                    var hid = _this.form.findField('pohead_id').getValue();
+                                    
+                                    if(!hid.length){
+                                        return false;
+                                    }
+                                    
+                                    o.params.poitem_pohead_id = hid;
+                                    o.params._with_item = 1;
+                                    
+                                
+                                    o.params._roo_office = _this.data.office ? _this.data.office:  baseURL.split('/').pop().substr(0,2);
+                                
+                                },
+                                load : function (_self, records, options)
+                                {
+                                    _this.grid.footer.updateSummary();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'poitem_id', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                timeout : 90000,
+                                url : baseURL + '/Xtuple/Roo/Poitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'poitem_id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'poitem_id',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            emptyMsg : "No Item found",
+                            pageSize : 25,
+                            updateSummary : function() {
+                            
+                                var f = this;
+                                new Pman.Request({
+                                    url : baseURL + '/Xtuple/Roo/Poitem',
+                                    method : 'GET',
+                                    params : {
+                                        _roo_office : _this.data.office,
+                                        _totals : 1,
+                                        poitem_pohead_id : _this.form.findField('pohead_id').getValue()
+                                    },
+                                    success : function(d) {
+                                        Roo.log(d);
+                                        f.displayEl.update(String.format(
+                                            "{0} items | Total : {1} {2}",
+                                            d.data[0].count_item,
+                                            _this.form.findField('pohead_curr_id').el.dom.value,
+                                            d.data[0].totals
+                                        ));
+                                            
+                                    }
+                                });
+                            
+                            }
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item code',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Item description',
+                                width : 150,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'poitem_duedate',
+                                header : 'Due date',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'poitem_linenumber',
+                                header : 'Line number',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'poitem_qty_ordered',
+                                header : 'Ordered',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'poitem_unitprice',
+                                header : 'Unit price',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v ? parseFloat(v).toFixed(3) : ''); }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'center',
+                    title : "TX",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.itempanel = this;
+                                        
+                                        
+                                        if (_this.itemgrid) {
+                                            _this.itemgrid.footer.onClick('first');
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'poitem',
+                                title : "Items",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.itemgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.itempanel.active) {
+                                               this.footer.onClick('first');
+                                            }
+                                        },
+                                        rowclick : function (_self, rowIndex, e)
+                                        {
+                                            
+                                            _this.gltransgrid.footer.onClick('first');
+                                        }
+                                    },
+                                    autoExpandColumn : 'item_number',
+                                    loadMask : true,
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        
+                                                         new Pman.Download({
+                                                            url : baseURL + '/Roo/Metasql',
+                                                            method : 'GET',
+                                                            timeout: 600000,
+                                                            params : {
+                                                                _group : 'gltrans_stock',
+                                                                _name : 'byorder',
+                                                                'pohead_number:text' : _this.form.findField('pohead_number').getValue(),
+                                                                csvCols : '*',
+                                                                csvTitles : '*', 
+                                                                limit : 9999       
+                                                            }
+                                                        });
+                                                    }
+                                                },
+                                                text : "PO analysis"
+                                            }
+                                        ]
+                                    },
+                                    sm : {
+                                        xtype: 'RowSelectionModel',
+                                        xns: Roo.grid,
+                                        singleSelect : true
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params = o.params || {};
+                                                var hid = _this.form.findField('pohead_id').getValue();
+                                                
+                                                if(!hid.length){
+                                                    return false;
+                                                }
+                                                
+                                                o.params.poitem_pohead_id = hid;
+                                                
+                                                o.params._with_item = 1;
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'poitem_id', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/poitem.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'type',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_office_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_phone',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_fax',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_email',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_company_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_role',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_active',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_remarks',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_passwd',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_owner_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_lang',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_no_reset_sent',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_action_type',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_project_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_deleted_by',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_deleted_dt',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'leader_firstname',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_lastname',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_name_facebook',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_blog',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_twitter',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_linkedin',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_lead_percentage',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_industry_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_updated_action_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_created_action_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_type_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : false,
+                                        displayMsg : "Displaying poitem{0} - {1} of {2}",
+                                        emptyMsg : "No item found",
+                                        pageSize : 25
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'poitem_linenumber',
+                                            header : 'Line #',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'item_number',
+                                            header : 'Item #',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'poitem_qty_ordered',
+                                            header : 'Ordered',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'poitem_qty_received',
+                                            header : 'Received',
+                                            width : 50,
+                                            renderer : function(v,x,r) 
+                                            {
+                                                return String.format('{0}', (v- r.data.poitem_qty_returned)) ;  
+                                                
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'poitem_unitprice',
+                                            header : 'Unit Price',
+                                            width : 75,
+                                            renderer : function(v,x,r) 
+                                            {
+                                                 
+                                                return String.format('{0}', (v- r.data.poitem_qty_returned) ? parseFloat(v- r.data.poitem_qty_returned).toFixed(3) : '') ;  
+                                                
+                                            }
+                                        }
+                                    ]
+                                }
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.gltranspanel = this;
+                                        //if (_this.gltransgrid) {
+                                        //    _this.gltransgrid.footer.onClick('first');
+                                        // }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'east',
+                                tableName : 'Gltrans',
+                                title : "Gltrans",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.gltransgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                          //  if (_this.gltranspanel.active) {
+                                          //     this.footer.onClick('first');
+                                          //  }
+                                        }
+                                    },
+                                    autoExpandColumn : 'gltrans_notes',
+                                    loadMask : true,
+                                    sm : {
+                                        xtype: 'RowSelectionModel',
+                                        xns: Roo.grid,
+                                        singleSelect : true
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params = o.params || {};
+                                                
+                                                var s = _this.itemgrid.getSelectionModel().getSelected();
+                                                if(!s){
+                                                    Roo.MessageBox.alert('Error', 'Please select a item');
+                                                    return false;
+                                                }
+                                                
+                                                o.params._poview = 1;
+                                                o.params.gltrans_deleted = 0;
+                                                o.params.gltrans_doctype = 'PO';
+                                                o.params._linenumber = s.data.poitem_linenumber;
+                                                o.params._item = s.data.item_number;
+                                                o.params._ponumber = _this.form.findField('pohead_number').getValue();
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'gltrans_id', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/gltrans.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'type',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_office_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_name',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_phone',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_fax',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_email',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_company_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_role',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_active',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_remarks',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_passwd',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_owner_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_lang',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_no_reset_sent',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_action_type',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_project_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_deleted_by',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_deleted_dt',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'leader_firstname',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_lastname',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_name_facebook',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_blog',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_twitter',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_url_linkedin',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_lead_percentage',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_industry_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_updated_action_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_created_action_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'leader_crm_type_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : true,
+                                        displayMsg : "Displaying gltrans{0} - {1} of {2}",
+                                        emptyMsg : "No gltrans found",
+                                        pageSize : 25
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var pohead_number = _this.form.findField('pohead_number').getValue();
+                                                        var pohead_id = _this.form.findField('pohead_id').getValue();
+                                                            
+                                                        var addv = function(){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead.php',
+                                                                method :'POST',
+                                                                params : {
+                                                                    pohead_id : pohead_id,
+                                                                    _variance : 1
+                                                                    
+                                                                },
+                                                                success : function(res) {
+                                                                    Roo.MessageBox.alert('Notice', 'DONE');
+                                                                }
+                                                            });
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm",
+                                                            "Are you sure to add all the variance for " + pohead_number + " ?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                    
+                                                                addv();
+                                                                return;
+                                                            }
+                                                        ); 
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add All Variance",
+                                                icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var s = _this.gltransgrid.getSelectionModel().getSelected();
+                                                        
+                                                        if(!s){
+                                                            Roo.MessageBox.alert('Error','Please select a transaction');
+                                                            return;
+                                                        }
+                                                        
+                                                        if(s.data.gltrans_misc_id == -1){
+                                                            Roo.MessageBox.alert('Error','Please select a transaction not variance');
+                                                            return;
+                                                        }
+                                                        
+                                                        var addit = function(){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/Gltrans.php',
+                                                                method :'POST',
+                                                                params : {
+                                                                    gltrans_id : s.data.gltrans_id,
+                                                                    _variance : 1
+                                                                    
+                                                                },
+                                                                success : function(res) {
+                                                                    if(res.data == 0){
+                                                                        Roo.MessageBox.alert('Error','Variance already exist');
+                                                                    }
+                                                                    _this.gltransgrid.footer.onClick('refresh');
+                                                                    
+                                                                }
+                                                            });
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm",
+                                                            "Are you sure to add a variance ?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                    
+                                                                addit();
+                                                                return;
+                                                            }
+                                                        ); 
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add Variance",
+                                                icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var s = _this.gltransgrid.getSelectionModel().getSelected();
+                                                        
+                                                        if(!s){
+                                                            Roo.MessageBox.alert('Error','Please select a transaction');
+                                                            return;
+                                                        }
+                                                        
+                                                        if(s.data.gltrans_misc_id != -1){
+                                                            Roo.MessageBox.alert('Error','Just allow to delete the variance');
+                                                            return;
+                                                        }
+                                                        
+                                                        var delit = function(){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/Gltrans.php',
+                                                                method :'POST',
+                                                                params : {
+                                                                    gltrans_id : s.data.gltrans_id,
+                                                                    _del : 1
+                                                                    
+                                                                },
+                                                                success : function(res) {
+                                                                    _this.gltransgrid.footer.onClick('refresh');
+                                                                    
+                                                                }
+                                                            });
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm",
+                                                            "Are you sure to delete ?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                    
+                                                                delit();
+                                                                return;
+                                                            }
+                                                        ); 
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Delete Variance",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var pohead_number = _this.form.findField('pohead_number').getValue();
+                                                        var pohead_id = _this.form.findField('pohead_id').getValue();
+                                                            
+                                                        var fixit = function(){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead.php',
+                                                                method :'POST',
+                                                                params : {
+                                                                    pohead_id : pohead_id,
+                                                                    _unitcost : 1
+                                                                    
+                                                                },
+                                                                success : function(res) {
+                                                                    Roo.MessageBox.alert('Notice', 'DONE');
+                                                                }
+                                                            });
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm",
+                                                            "Are you sure to fix the unit cost of " + pohead_number + " ?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                    
+                                                                fixit();
+                                                                return;
+                                                            }
+                                                        ); 
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Fix Unit Cost",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var pohead_number = _this.form.findField('pohead_number').getValue();
+                                                        var pohead_id = _this.form.findField('pohead_id').getValue();
+                                                            
+                                                        var delv = function(){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead.php',
+                                                                method :'POST',
+                                                                params : {
+                                                                    pohead_id : pohead_id,
+                                                                    _del : 1
+                                                                    
+                                                                },
+                                                                success : function(res) {
+                                                                    Roo.MessageBox.alert('Notice', 'DONE');
+                                                                }
+                                                            });
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm",
+                                                            "Are you sure to delete the variance on voucher of " + pohead_number + " ?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                    
+                                                                delv();
+                                                                return;
+                                                            }
+                                                        ); 
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Delete Varinace on voucher",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_id',
+                                            header : 'ID',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_date',
+                                            header : 'Date',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_docnumber',
+                                            header : 'doc #',
+                                            width : 80,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_amount',
+                                            header : 'Amount',
+                                            width : 100,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_notes',
+                                            header : 'Notes',
+                                            width : 100,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        },
+                        east : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            split : true,
+                            width : 550
+                        }
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                alwaysShowTabs : true,
+                tabPosition : 'top',
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                    var hid = _this.form.findField('pohead_id').getValue();
+                                
+                                    if(!hid.length){
+                                        Roo.MessageBox.alert("Error", "Please save your purchase order first"); 
+                                        return false;
+                                    }
+                                
+                                    
+                                    if (!_this.grid) {
+                                        _dialog.layout.showPanel(1);
+                                        doit.defer(500);
+                                        return;
+                                    }
+                                    
+                                    
+                                    
+                                    var doit = function () { 
+                                        new Pman.Download({
+                                            grid : _this.grid
+                                        });
+                                    }
+                                    doit();
+                                            
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Download Purchase Order Items (Excel)",
+                            icon : rootURL + '/Pman/templates/images/save.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.uploadBtn = _self;
+                                }
+                            },
+                            text : "Upload Purchase Order",
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var hid = _this.form.findField('pohead_id').getValue();
+                                                
+                                                if(!hid.length){
+                                                    Roo.MessageBox.alert("Error", "Please save your purchase order first"); 
+                                                    return false;
+                                                }
+                                                Pman.Dialog.Image.show(
+                                                   {
+                                                        timeout : 60000,
+                                                        _url : baseURL+'/Xtuple/Import/PurchaseOrder?' + Roo.urlEncode({'pohead_id' : hid})
+                                                    
+                                                   },
+                                                   function () {
+                                                        if(_this.grid){
+                                                            _this.grid.footer.onClick('first');
+                                                        }
+                                                        Roo.MessageBox.alert("Notice", 'UPLOADED');
+                                                   }
+                                               );
+                                            }
+                                        },
+                                        text : "Upload Standard Excel"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            
+                                                var hid = _this.form.findField('pohead_id').getValue();
+                                                
+                                                if(!hid.length){
+                                                    Roo.MessageBox.alert("Error", "Please save your purchase order first"); 
+                                                    return false;
+                                                }
+                                                
+                                               Pman.Dialog.Image.show(
+                                               {
+                                                    _url : baseURL+'/Xtuple/Import/AUPurchaseOrder?' + Roo.urlEncode({'pohead_id' :hid})
+                                                    
+                                               },
+                                               function (data) {
+                                                   if(_this.grid){
+                                                        _this.grid.footer.onClick('first');
+                                                   }
+                                                   Roo.MessageBox.alert("Notice", 'IMPORTED');
+                                            
+                                               });
+                                            }
+                                        },
+                                        text : "Upload AU Import Excel"
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                }
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                             
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtuplePurchaseOrderEdit.bjs b/Pman.Dialog.XtuplePurchaseOrderEdit.bjs
new file mode 100644 (file)
index 0000000..b81207d
--- /dev/null
@@ -0,0 +1,163 @@
+{
+    "id": "roo-file-15",
+    "name": "Pman.Dialog.XtuplePurchaseOrderEdit",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtuplePurchaseOrderEdit.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function () {\n       this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 200,
+            "modal": true,
+            "resizable": false,
+            "title": "Change Location",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if(_this.data.pohead_id){\n           _this.dialog.el.mask(\"Loading\");\n           this.load({ method: 'GET', params: { '_id' : _this.data.pohead_id }});\n           return;\n       }\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/pohead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "fieldLabel": "PO#",
+                                    "name": "pohead_number",
+                                    "readOnly": true,
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Change Type",
+                                    "hiddenName": "change_type",
+                                    "listWidth": 400,
+                                    "mode": "local",
+                                    "name": "change_type_name",
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{fname}</b> </div>",
+                                    "triggerAction": "all",
+                                    "value": "A",
+                                    "valueField": "ftype",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'A', \"Change All Location\"],\n    [ 'E', \"Change The Location Of PO And un-signed Item\"]\n    \n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "location_name",
+                                    "editable": true,
+                                    "emptyText": "Select a location",
+                                    "fieldLabel": "Location",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_location_id_location_name",
+                                    "pageSize": 200,
+                                    "qtip": "Select terms",
+                                    "queryParam": "query[location_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "location_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "location_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "pohead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n   // _this.dialog.el.mask(\"Saving\");\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtuplePurchaseOrderEdit.js b/Pman.Dialog.XtuplePurchaseOrderEdit.js
new file mode 100644 (file)
index 0000000..ac3e7ef
--- /dev/null
@@ -0,0 +1,220 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtuplePurchaseOrderEdit = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function () {
+                       this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 200,
+            modal : true,
+            resizable : false,
+            title : "Change Location",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if(_this.data.pohead_id){
+                                           _this.dialog.el.mask("Loading");
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.pohead_id }});
+                                           return;
+                                       }
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/pohead.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'PO#',
+                                    name : 'pohead_number',
+                                    readOnly : true,
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'fname',
+                                    editable : false,
+                                    fieldLabel : 'Change Type',
+                                    hiddenName : 'change_type',
+                                    listWidth : 400,
+                                    mode : 'local',
+                                    name : 'change_type_name',
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{fname}</b> </div>',
+                                    triggerAction : 'all',
+                                    value : "A",
+                                    valueField : 'ftype',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'SimpleStore',
+                                        xns: Roo.data,
+                                        data : [ 
+                                            [ 'A', "Change All Location"],
+                                            [ 'E', "Change The Location Of PO And un-signed Item"]
+                                            
+                                        ],
+                                        fields : [  'ftype', 'fname']
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'location_name',
+                                    editable : true,
+                                    emptyText : "Select a location",
+                                    fieldLabel : 'Location',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_location_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_location_id_location_name',
+                                    pageSize : 200,
+                                    qtip : "Select terms",
+                                    queryParam : 'query[location_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : false,
+                                    valueField : 'location_id',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                                 o.params.location_netable = 1;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'location_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/location.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'location_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"location_id","type":"int"},"location_name"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'pohead_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                           // _this.dialog.el.mask("Saving");
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtuplePurchaseOrderNew.bjs b/Pman.Dialog.XtuplePurchaseOrderNew.bjs
new file mode 100644 (file)
index 0000000..4fcda3c
--- /dev/null
@@ -0,0 +1,175 @@
+{
+    "id": "roo-file-16",
+    "name": "Pman.Dialog.XtuplePurchaseOrderNew",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtuplePurchaseOrderNew.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    _this.form.findField('pohead_vend_id').focus();\n}"
+            },
+            "closable": false,
+            "height": 180,
+            "modal": true,
+            "resizable": false,
+            "title": "Pick Vendor",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}"
+                            },
+                            "xtype": "Form",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, record, index)\n{\n   \n   Roo.log(record);\n    _this.form.setValues({\n        pohead_curr_id : record.data.vend_curr_id,\n        pohead_curr_id_curr_name : record.data.vend_curr_id_curr_name\n    \n    });\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "vend_name",
+                                    "editable": true,
+                                    "fieldLabel": "Select Vendor",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_vend_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_vend_id_vend_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select a vendor",
+                                    "queryParam": "query[vend_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{vend_name}</b></div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "vend_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'vend_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Vendinfo.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "vend_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"vend_id\",\"type\":\"int\"},\n    {\"name\":\"vend_name\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select Currency",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "pohead_curr_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "pohead_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Currency",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "curr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\"name\":\"curr_id\",\"type\":\"int\"},\n    {\"name\":\"curr_name\",\"type\":\"string\"}\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    if (_this.form.findField('pohead_vend_id').getValue() < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a vendor\");\n        return;\n    }\n   \n    var data = _this.form.getFieldValues();\n    Roo.log(data);\n    _this.dialog.hide();\n    _this.callback(data);\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtuplePurchaseOrderNew.js b/Pman.Dialog.XtuplePurchaseOrderNew.js
new file mode 100644 (file)
index 0000000..c6deee9
--- /dev/null
@@ -0,0 +1,221 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtuplePurchaseOrderNew = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    _this.form.findField('pohead_vend_id').focus();
+                }
+            },
+            closable : false,
+            height : 180,
+            modal : true,
+            resizable : false,
+            title : "Pick Vendor",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                }
+                            },
+                            items : [
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        select : function (combo, record, index)
+                                        {
+                                           
+                                           Roo.log(record);
+                                            _this.form.setValues({
+                                                pohead_curr_id : record.data.vend_curr_id,
+                                                pohead_curr_id_curr_name : record.data.vend_curr_id_curr_name
+                                            
+                                            });
+                                        }
+                                    },
+                                    allowBlank : false,
+                                    displayField : 'vend_name',
+                                    editable : true,
+                                    fieldLabel : 'Select Vendor',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_vend_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_vend_id_vend_name',
+                                    pageSize : 20,
+                                    qtip : "Select a vendor",
+                                    queryParam : 'query[vend_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{vend_name}</b></div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'vend_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'vend_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Vendinfo.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'vend_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"vend_id","type":"int"},
+                                                {"name":"vend_name","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select Currency",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'pohead_curr_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'pohead_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select Currency",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'curr_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'curr_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {"name":"curr_id","type":"int"},
+                                                {"name":"curr_name","type":"string"}
+                                            ]
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            if (_this.form.findField('pohead_vend_id').getValue() < 1) {
+                                Roo.MessageBox.alert("Error", "Select a vendor");
+                                return;
+                            }
+                           
+                            var data = _this.form.getFieldValues();
+                            Roo.log(data);
+                            _this.dialog.hide();
+                            _this.callback(data);
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleQuickContact.bjs b/Pman.Dialog.XtupleQuickContact.bjs
new file mode 100644 (file)
index 0000000..9aedb0d
--- /dev/null
@@ -0,0 +1,266 @@
+{
+    "id": "roo-file-17",
+    "name": "Pman.Dialog.XtupleQuickContact",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleQuickContact.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 400,
+            "modal": true,
+            "resizable": false,
+            "title": "Quick enter Contact /  Address",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if (_this.data._id) { \n            this.load({ method: 'GET', params: { \n                _id : _this.data._id , \n                _with_addr : 1\n            }});\n        }\n       return;\n    }\n    if (action.type == 'load') {\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n             _this.form.setValues(action.result.data);\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cntct.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "First Name",
+                                    "name": "cntct_first_name",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Last Name",
+                                    "name": "cntct_last_name",
+                                    "width": 300,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Phone",
+                                    "name": "cntct_phone",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|regex": "/^[0-9 +-]+$/",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Email",
+                                    "name": "cntct_email",
+                                    "vtype": "email",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "legend": "Address",
+                                    "style": "width:420px",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "keyup": "function (_self, e)\n{\n    _this.form.findField('addr_number').sync();\n}"
+                                            },
+                                            "allowBlank": false,
+                                            "fieldLabel": "Line 1",
+                                            "name": "cntct_addr_id_addr_line1",
+                                            "width": 300,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Line 2",
+                                            "name": "cntct_addr_id_addr_line2",
+                                            "width": 300,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Line 3",
+                                            "name": "cntct_addr_id_addr_line3",
+                                            "width": 300,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": true,
+                                            "displayField": "addr_state",
+                                            "editable": true,
+                                            "emptyText": "State",
+                                            "fieldLabel": "State",
+                                            "hiddenName": "cntct_addr_id_addr_state",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "cntct_addr_id_addr_state",
+                                            "qtip": "Select State",
+                                            "queryParam": "query[addr_state]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_state}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "addr_state",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n   // o.params.state_country_id_country_name = _this.form.findField('addr_country').getValue();\n    //if (!o.params.state_country_id_country_name.length) {\n    //    Roo.MessageBox.alert(\"Select Country First\");\n//        return false;\n  //  }\n  \n   o.params._distinct = 'addr_state';\n   o.params._columns = 'addr_state';\n   o.params.limit = 999;\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'addr_state' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/addr.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "addr_state",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[ \"addr_state\"]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "fieldLabel": "City",
+                                            "name": "cntct_addr_id_addr_city",
+                                            "width": 300,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "fieldLabel": "Zip code",
+                                            "name": "cntct_addr_id_addr_postalcode",
+                                            "width": 300,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "allowBlank": true,
+                                            "displayField": "country_name",
+                                            "editable": true,
+                                            "emptyText": "Country",
+                                            "fieldLabel": "Country",
+                                            "hiddenName": "cntct_addr_id_addr_country",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "cntct_addr_id_addr_country",
+                                            "qtip": "Select Country",
+                                            "queryParam": "query[country_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{country_name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "country_name",
+                                            "width": 200,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.limit = 999;\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'country_name' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/country.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "country_id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[{\"name\":\"country_id\",\"type\":\"int\"},\"county_name\"]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "customer_id",
+                                    "width": 100,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_addr_id",
+                                    "width": 100,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cntct_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n \n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleQuickContact.js b/Pman.Dialog.XtupleQuickContact.js
new file mode 100644 (file)
index 0000000..4d77903
--- /dev/null
@@ -0,0 +1,330 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleQuickContact = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 400,
+            modal : true,
+            resizable : false,
+            title : "Quick enter Contact /  Address",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if (_this.data._id) { 
+                                            this.load({ method: 'GET', params: { 
+                                                _id : _this.data._id , 
+                                                _with_addr : 1
+                                            }});
+                                        }
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                             _this.form.setValues(action.result.data);
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/cntct.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'First Name',
+                                    name : 'cntct_first_name',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Last Name',
+                                    name : 'cntct_last_name',
+                                    width : 300
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Phone',
+                                    name : 'cntct_phone',
+                                    width : 200,
+                                    regex : /^[0-9 +-]+$/
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Email',
+                                    name : 'cntct_email',
+                                    vtype : 'email',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Address",
+                                    style : 'width:420px',
+                                    items : [
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                keyup : function (_self, e)
+                                                {
+                                                    _this.form.findField('addr_number').sync();
+                                                }
+                                            },
+                                            allowBlank : false,
+                                            fieldLabel : 'Line 1',
+                                            name : 'cntct_addr_id_addr_line1',
+                                            width : 300
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Line 2',
+                                            name : 'cntct_addr_id_addr_line2',
+                                            width : 300
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Line 3',
+                                            name : 'cntct_addr_id_addr_line3',
+                                            width : 300
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : true,
+                                            displayField : 'addr_state',
+                                            editable : true,
+                                            emptyText : "State",
+                                            fieldLabel : 'State',
+                                            hiddenName : 'cntct_addr_id_addr_state',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'cntct_addr_id_addr_state',
+                                            qtip : "Select State",
+                                            queryParam : 'query[addr_state]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_state}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'addr_state',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        
+                                                       // o.params.state_country_id_country_name = _this.form.findField('addr_country').getValue();
+                                                        //if (!o.params.state_country_id_country_name.length) {
+                                                        //    Roo.MessageBox.alert("Select Country First");
+                                                    //        return false;
+                                                      //  }
+                                                      
+                                                       o.params._distinct = 'addr_state';
+                                                       o.params._columns = 'addr_state';
+                                                       o.params.limit = 999;
+                                                        // set more here
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'addr_state' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/addr.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'addr_state',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [ "addr_state"]
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'City',
+                                            name : 'cntct_addr_id_addr_city',
+                                            width : 300
+                                        },
+                                        {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            fieldLabel : 'Zip code',
+                                            name : 'cntct_addr_id_addr_postalcode',
+                                            width : 300
+                                        },
+                                        {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : true,
+                                            displayField : 'country_name',
+                                            editable : true,
+                                            emptyText : "Country",
+                                            fieldLabel : 'Country',
+                                            hiddenName : 'cntct_addr_id_addr_country',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'cntct_addr_id_addr_country',
+                                            qtip : "Select Country",
+                                            queryParam : 'query[country_name]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{country_name}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : true,
+                                            valueField : 'country_name',
+                                            width : 200,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        // set more here
+                                                        o.params.limit = 999;
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'country_name' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/country.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'country_id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"country_id","type":"int"},"county_name"]
+                                                }
+                                            }
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'customer_id',
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_addr_id',
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cntct_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                         
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleReceivePayment.bjs b/Pman.Dialog.XtupleReceivePayment.bjs
new file mode 100644 (file)
index 0000000..661c922
--- /dev/null
@@ -0,0 +1,286 @@
+{
+    "id": "roo-file-20",
+    "name": "Pman.Dialog.XtupleReceivePayment",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleReceivePayment.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 400,
+            "modal": true,
+            "resizable": false,
+            "title": "Create Receive Payment",
+            "width": 600,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        if(_this.data.cashrcpt_id){\n           _this.dialog.el.mask(\"Loading\");\n           this.load({ method: 'GET', params: { '_id' : _this.data.cashrcpt_id }});\n           return;\n       }\n    }\n    if (action.type == 'load') {\n        _this.dialog.el.unmask();\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.el.unmask();\n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "labelWidth": 150,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cashrcpt.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "allowDecimals": true,
+                                    "decimalPrecision": 2,
+                                    "fieldLabel": "Amount Received",
+                                    "name": "cashrcpt_amount",
+                                    "readOnly": true,
+                                    "width": 200,
+                                    "xtype": "NumberField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "disabled": true,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select curr_name",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "cashrcpt_curr_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cashrcpt_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Currency",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "curr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Funds Type",
+                                    "hiddenName": "cashrcpt_fundstype",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "cashrcpt_fundstype_name",
+                                    "triggerAction": "all",
+                                    "valueField": "ftype",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'C', \"Check\"],\n    [ 'K' , \"Cash\"]\n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": true,
+                                    "fieldLabel": "Check / Document #",
+                                    "name": "cashrcpt_docnumber",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Check / Document Date",
+                                    "format": "Y-m-d",
+                                    "name": "cashrcpt_docdate",
+                                    "width": 200,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Distribution Date",
+                                    "format": "Y-m-d",
+                                    "name": "cashrcpt_distdate",
+                                    "width": 200,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Application Date",
+                                    "format": "Y-m-d",
+                                    "name": "cashrcpt_applydate",
+                                    "width": 200,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "bankaccnt_name",
+                                    "editable": false,
+                                    "emptyText": "Select Bank Accnt",
+                                    "fieldLabel": "Post to",
+                                    "forceSelection": true,
+                                    "hiddenName": "cashrcpt_bankaccnt_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cashrcpt_bankaccnt_id_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Bank Accnt",
+                                    "queryParam": "query[bankaccnt_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{bankaccnt_name} - {bankaccnt_descrip}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "bankaccnt_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'DESC', field: 'bankaccnt_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/bankaccnt.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "bankaccnt_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"bankaccnt_id\",\"type\":\"int\"},\"bankaccnt_name\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "fieldLabel": "Notes",
+                                    "name": "cashrcpt_notes",
+                                    "xtype": "TextArea",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_aropen_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_cust_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_salescat_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_discount",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cashrcpt_usecustdeposit",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n  //  _this.dialog.el.mask(\"Saving\");\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleReceivePayment.js b/Pman.Dialog.XtupleReceivePayment.js
new file mode 100644 (file)
index 0000000..34b5f70
--- /dev/null
@@ -0,0 +1,340 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleReceivePayment = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 400,
+            modal : true,
+            resizable : false,
+            title : "Create Receive Payment",
+            width : 600,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        if(_this.data.cashrcpt_id){
+                                           _this.dialog.el.mask("Loading");
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.cashrcpt_id }});
+                                           return;
+                                       }
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.dialog.el.unmask();
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.el.unmask();
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            labelWidth : 150,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/cashrcpt.php',
+                            items : [
+                                {
+                                    xtype: 'NumberField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    allowDecimals : true,
+                                    decimalPrecision : 2,
+                                    fieldLabel : 'Amount Received',
+                                    name : 'cashrcpt_amount',
+                                    readOnly : true,
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    disabled : true,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select curr_name",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'cashrcpt_curr_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'cashrcpt_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select Currency",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                               
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'curr_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'fname',
+                                    editable : false,
+                                    fieldLabel : 'Funds Type',
+                                    hiddenName : 'cashrcpt_fundstype',
+                                    listWidth : 200,
+                                    mode : 'local',
+                                    name : 'cashrcpt_fundstype_name',
+                                    triggerAction : 'all',
+                                    valueField : 'ftype',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'SimpleStore',
+                                        xns: Roo.data,
+                                        data : [ 
+                                            [ 'C', "Check"],
+                                            [ 'K' , "Cash"]
+                                        ],
+                                        fields : [  'ftype', 'fname']
+                                    }
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : true,
+                                    fieldLabel : 'Check / Document #',
+                                    name : 'cashrcpt_docnumber',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Check / Document Date',
+                                    format : 'Y-m-d',
+                                    name : 'cashrcpt_docdate',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Distribution Date',
+                                    format : 'Y-m-d',
+                                    name : 'cashrcpt_distdate',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Application Date',
+                                    format : 'Y-m-d',
+                                    name : 'cashrcpt_applydate',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'bankaccnt_name',
+                                    editable : false,
+                                    emptyText : "Select Bank Accnt",
+                                    fieldLabel : 'Post to',
+                                    forceSelection : true,
+                                    hiddenName : 'cashrcpt_bankaccnt_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'cashrcpt_bankaccnt_id_name',
+                                    pageSize : 20,
+                                    qtip : "Select Bank Accnt",
+                                    queryParam : 'query[bankaccnt_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{bankaccnt_name} - {bankaccnt_descrip}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'bankaccnt_id',
+                                    width : 200,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                               
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'DESC', field: 'bankaccnt_id' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/bankaccnt.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'bankaccnt_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"bankaccnt_id","type":"int"},"bankaccnt_name"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'TextArea',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Notes',
+                                    name : 'cashrcpt_notes'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_aropen_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_cust_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_salescat_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_discount'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cashrcpt_usecustdeposit'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                          //  _this.dialog.el.mask("Saving");
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleReconcile.bjs b/Pman.Dialog.XtupleReconcile.bjs
new file mode 100644 (file)
index 0000000..df43efc
--- /dev/null
@@ -0,0 +1,138 @@
+{
+    "id": "roo-file-22",
+    "name": "Pman.Dialog.XtupleReconcile",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleReconcile.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 260,
+            "modal": true,
+            "resizable": false,
+            "title": "Reconcile account",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n\n       this.load({ method: 'GET', params: { '_closedata' : _this.data.bankaccnt_id }});\n       return;\n    }\n    if (action.type == 'load') {\n \n        return;\n    }\n    if (action.type =='submit') {\n    \n \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n",
+                                "actionfailed": "function (_self, action)\n{\n\n    Roo.MessageBox.alert(\"Error\", \n        action.result ? action.result.errorMsg : \"Error posting\"\n    );\n        \n    if (action.type == 'load') {\n        _this.dialog.hide();\n        return;\n    }\n\n\n    \n}"
+                            },
+                            "labelAlign": "right",
+                            "labelWidth": 150,
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/bankrec.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "fieldLabel": "Bank Account",
+                                    "name": "bankrec_bankaccnt_id_bankaccnt_descrip",
+                                    "readOnly": true,
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "From date",
+                                    "format": "Y-m-d",
+                                    "name": "bankrec_opendate",
+                                    "readOnly": true,
+                                    "width": 100,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "End Date",
+                                    "format": "Y-m-d",
+                                    "name": "bankrec_enddate",
+                                    "readOnly": true,
+                                    "width": 100,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Opening Balance",
+                                    "name": "bankrec_openbal",
+                                    "readOnly": true,
+                                    "width": 75,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "System close balance",
+                                    "name": "bankrec_endbal_prop",
+                                    "readOnly": true,
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "fieldLabel": "Real close balance",
+                                    "name": "bankrec_endbal",
+                                    "width": 150,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "_post",
+                                    "value": 1,
+                                    "width": 150,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "bankrec_bankaccnt_id",
+                                    "width": 150,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "bankrec_id",
+                                    "width": 150,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n \n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleReconcile.js b/Pman.Dialog.XtupleReconcile.js
new file mode 100644 (file)
index 0000000..84eeb96
--- /dev/null
@@ -0,0 +1,207 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleReconcile = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 260,
+            modal : true,
+            resizable : false,
+            title : "Reconcile account",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                
+                                       this.load({ method: 'GET', params: { '_closedata' : _this.data.bankaccnt_id }});
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                 
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                 
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                },
+                                actionfailed : function (_self, action)
+                                {
+                                
+                                    Roo.MessageBox.alert("Error", 
+                                        action.result ? action.result.errorMsg : "Error posting"
+                                    );
+                                        
+                                    if (action.type == 'load') {
+                                        _this.dialog.hide();
+                                        return;
+                                    }
+                                
+                                
+                                    
+                                }
+                            },
+                            labelAlign : 'right',
+                            labelWidth : 150,
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/bankrec.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Bank Account',
+                                    name : 'bankrec_bankaccnt_id_bankaccnt_descrip',
+                                    readOnly : true,
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'From date',
+                                    format : 'Y-m-d',
+                                    name : 'bankrec_opendate',
+                                    readOnly : true,
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'End Date',
+                                    format : 'Y-m-d',
+                                    name : 'bankrec_enddate',
+                                    readOnly : true,
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Opening Balance',
+                                    name : 'bankrec_openbal',
+                                    readOnly : true,
+                                    width : 75
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'System close balance',
+                                    name : 'bankrec_endbal_prop',
+                                    readOnly : true,
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    fieldLabel : 'Real close balance',
+                                    name : 'bankrec_endbal',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : '_post',
+                                    value : 1,
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'bankrec_bankaccnt_id',
+                                    width : 150
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'bankrec_id',
+                                    width : 150
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                         
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleRecvGrp.bjs b/Pman.Dialog.XtupleRecvGrp.bjs
new file mode 100644 (file)
index 0000000..209c180
--- /dev/null
@@ -0,0 +1,383 @@
+{
+    "id": "roo-file-23",
+    "name": "Pman.Dialog.XtupleRecvGrp",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleRecvGrp.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 600,
+            "modal": true,
+            "resizable": false,
+            "title": "Enter Item Reciept",
+            "width": 900,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "*prop": "north",
+                    "height": 150,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       \n       if (_this.data.recvgrp_id) {\n           this.load({ method: 'GET', params: { '_id' : _this.data.recvgrp_id }});\n           return;\n       }\n       \n       if (!_this.data.recv_id) {\n           _this.data.recv_date = new Date();\n       }\n       _this.form.setValues(_this.data);\n\n        _this.grid.ds.load({});\n       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});\n       return;\n    }\n    if (action.type == 'load') {\n        _this.grid.ds.load({});\n        \n        \n        \n        \n        \n        return;\n    }\n    if (action.type =='submit') {\n    \n         \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "timeout": 120000,
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/recvgrp.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "legend": "Receipt Details",
+                                    "xtype": "FieldSet",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "width": 800,
+                                            "xtype": "Row",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "width": 450,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "fieldLabel": "Order number",
+                                                            "name": "recvgrp_pohead_id_pohead_number",
+                                                            "readOnly": true,
+                                                            "width": 200,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "altFormats": "Y-m-d",
+                                                            "fieldLabel": "Recv date",
+                                                            "format": "d/M/Y",
+                                                            "name": "recvgrp_date",
+                                                            "width": 100,
+                                                            "xtype": "DateField",
+                                                            "|useIso": "true",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "location_name",
+                                                            "editable": true,
+                                                            "emptyText": "Select location",
+                                                            "fieldLabel": "Delivered to",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "recvgrp_location_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "recvgrp_location_id_location_name",
+                                                            "pageSize": 200,
+                                                            "qtip": "Select terms",
+                                                            "queryParam": "query[location_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": false,
+                                                            "valueField": "location_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n    o.params.location_netable = 1;\n    o.params._notinternalcompany = 1; \n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "location_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Notes",
+                                                            "name": "recv_notes",
+                                                            "width": 300,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "labelAlign": "top",
+                                                    "width": 350,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Goods Receipt Number",
+                                                            "name": "recvgrp_receipt_number",
+                                                            "width": 300,
+                                                            "xtype": "TextArea",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "recvgrp_pohead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "recvgrp_id",
+                                    "value": 0,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "recvgrp_void",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "recv_qtys",
+                                    "value": 0,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n     \n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "poitem",
+                    "title": "poitem",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n     \n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                                "beforeedit": "function (e)\n{\n     if (_this.form.findField('recvgrp_id').getValue() * 1 > 0) {\n        Roo.MessageBox.alert(\"Error\", \"you can not modify the stock\");\n        e.cancel = true;\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_descrip1",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n    if (!_this.form ) {\n        return false;\n    }\n     o.params=  o.params || {};\n     \n    o.params.poitem_pohead_id = _this.form.findField('recvgrp_pohead_id').getValue();\n    o.params._with_item = 1;\n    o.params.item_type = 'P';    \n    o.params.recvgrp_id = _this.form.findField('recvgrp_id').getValue();\n    o.params.limit = 3000;\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'poitem_linenumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "timeout": 90000,
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/poitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'poitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_status',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_pohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'poitem_wohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_invvenduomratio',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_qty_ordered',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_qty_received',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_qty_returned',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_qty_vouchered',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_unitprice',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_qty_toreceive',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_expcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_freight_received',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_freight_vouchered',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_soitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_stdcost',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_bom_rev_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_boo_rev_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_manuf_name',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_manuf_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_manuf_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_tax_recoverable',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_rlsd_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_number',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_subnumber',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_status',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_startdate',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_ordtype',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_ordid',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_qtyord',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_qtyrcv',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_adhoc',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_itemcfg_series',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_wipvalue',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_postedvalue',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_prodnotes',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_priority',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_brdvalue',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_bom_rev_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_boo_rev_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_cosmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_womatl_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_wohead_id_wo_username',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_taxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_taxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_taxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_taxtype_id_taxtype_sys',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id_prj_number',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_name',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_status',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_so',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id_prj_wo',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id_prj_po',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_prj_id_prj_owner_username',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_start_date',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_prj_id_prj_due_date',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_prj_id_prj_assigned_date',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_prj_id_prj_completed_date',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_prj_id_prj_username',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_prj_id_prj_recurring_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_invvendoruomratio',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_minordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_multordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_leadtime',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_ranking',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_active',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_manuf_name',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_manuf_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_manuf_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_default',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsrc_id_itemsrc_upccode',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_qtyonhand',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_reorderlevel',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_ordertoqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_cyclecountfreq',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_datelastcount',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_datelastused',\n        'type': 'date'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_loccntrl',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_safetystock',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_minordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_multordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_leadtime',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_abcclass',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_issuemethod',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_controlmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_active',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_plancode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_costcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_eventfence',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_sold',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_stocked',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_freeze',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_useparams',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_useparamsmanual',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_soldranking',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_createpr',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_location',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_location_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_perishable',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_nnqoh',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_autoabcclass',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_ordergroup',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_disallowblankwip',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_maxordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_mps_timefence',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_createwo',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_warrpurc',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_autoreg',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_value',\n        'type': 'float'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_ordergroup_first',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_supply_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_planning_type',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_wosupply',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_posupply',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_lsseq_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_cosdefault',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_createsopr',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_createsopo',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_itemsite_id_itemsite_dropship',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_code',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_exp_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_liability_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_active',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_purchprice_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'poitem_expcat_id_expcat_freight_accnt_id',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     // reset..\n     _this.grid.load({});\n}\n"
+                                            },
+                                            "text": "Reset",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Fill"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     if (_this.form.findField('recvgrp_id').getValue() * 1 > 0) {\n        Roo.MessageBox.alert(\"Error\", \"you can not modify the stock\");\n        return;\n    }\n     // reset..\n     _this.grid.ds.each(function(r) {\n        r.set('recv_qty',  r.data.poitem_qty_ordered - \n          r.data.poitem_qty_received + r.data.poitem_qty_returned\n        );\n    });\n    \n}\n"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Recieve All",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "poitem_linenumber",
+                                    "header": "Line#",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item No.",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Description",
+                                    "width": 150,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "poitem_qty_ordered",
+                                    "header": "Ordered",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "poitem_qty_received",
+                                    "header": "Remaining",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n\n     var vv = r.data.poitem_qty_ordered - \n        r.data.poitem_qty_received + r.data.poitem_qty_returned;\n     return String.format('{0}', parseInt(vv)); \n          \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "recv_qty",
+                                    "header": "Recieved",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { \n\n    var voided = _this.form.findField('recvgrp_void').getValue() * 1;\n    var format = voided ? '<s>{0}</s>' : '{0}';\n    return String.format(format , parseInt(v)); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "cls": "align-right",
+                                                    "decimalPrecision": 0,
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    if (!_this.form.findField('recvgrp_id').getValue()) {\n        Roo.MessageBox.alert(\"Error\", \"Can not void this as it has not been saved\");\n        return;\n    }\n   \n     if (1 * _this.form.findField('recvgrp_void').getValue()) {\n        Roo.MessageBox.alert(\"Error\", \"This record is already void.\");\n        return;\n    }\n    new Pman.Request({\n        mask : 'Voiding',\n        method : 'POST',\n        url : baseURL + '/Roo/Recvgrp',\n        params : {\n            recvgrp_id : _this.form.findField('recvgrp_id').getValue(),\n            _void : 1\n        },\n        success : function() {\n              if (_this.callback) {\n                _this.callback.call(_this, _this.form.getValues());\n             }\n            _this.dialog.hide();\n        }\n    });\n    \n   \n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "VOID",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n    \n    var c = [];\n    var t = 0;\n    _this.grid.ds.each(function(r) {\n        var q = r.data.recv_qty * 1;\n        if (q < 1) {\n            return;\n        }\n        c.push({\n            recv_orderitem_id : r.data.poitem_id,\n            recv_qty : r.data.recv_qty\n        });\n        t += r.data.recv_qty * 1;\n    });\n    if (t < 1) {\n        Roo.MessageBox.alert(\"Error\", \"nothing to recieve\");\n        return;\n    }\n    \n    _this.form.findField('recv_qtys').setValue( Roo.encode(c));\n    _this.form.doAction(\"submit\");\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleRecvGrp.js b/Pman.Dialog.XtupleRecvGrp.js
new file mode 100644 (file)
index 0000000..f973a46
--- /dev/null
@@ -0,0 +1,1180 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleRecvGrp = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 600,
+            modal : true,
+            resizable : false,
+            title : "Enter Item Reciept",
+            width : 900,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       //_this.dialog.el.mask("Loading");
+                                       
+                                       if (_this.data.recvgrp_id) {
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.recvgrp_id }});
+                                           return;
+                                       }
+                                       
+                                       if (!_this.data.recv_id) {
+                                           _this.data.recv_date = new Date();
+                                       }
+                                       _this.form.setValues(_this.data);
+                                
+                                        _this.grid.ds.load({});
+                                       //this.load({ method: 'GET', params: { '_id' : _this.data.id }});
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        _this.grid.ds.load({});
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                         
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            timeout : 120000,
+                            url : baseURL + '/Roo/recvgrp.php',
+                            items : [
+                                {
+                                    xtype: 'FieldSet',
+                                    xns: Roo.form,
+                                    legend : "Receipt Details",
+                                    items : [
+                                        {
+                                            xtype: 'Row',
+                                            xns: Roo.form,
+                                            width : 800,
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    width : 450,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Order number',
+                                                            name : 'recvgrp_pohead_id_pohead_number',
+                                                            readOnly : true,
+                                                            width : 200
+                                                        },
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            altFormats : 'Y-m-d',
+                                                            fieldLabel : 'Recv date',
+                                                            format : 'd/M/Y',
+                                                            name : 'recvgrp_date',
+                                                            width : 100,
+                                                            useIso : true
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            displayField : 'location_name',
+                                                            editable : true,
+                                                            emptyText : "Select location",
+                                                            fieldLabel : 'Delivered to',
+                                                            forceSelection : true,
+                                                            hiddenName : 'recvgrp_location_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'recvgrp_location_id_location_name',
+                                                            pageSize : 200,
+                                                            qtip : "Select terms",
+                                                            queryParam : 'query[location_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : false,
+                                                            valueField : 'location_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        
+                                                                        o.params.location_netable = 1;
+                                                                        o.params._notinternalcompany = 1; 
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/location.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'location_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"location_id","type":"int"},"location_name"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Notes',
+                                                            name : 'recv_notes',
+                                                            width : 300
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'top',
+                                                    width : 350,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            fieldLabel : 'Goods Receipt Number',
+                                                            name : 'recvgrp_receipt_number',
+                                                            width : 300
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'recvgrp_pohead_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'recvgrp_id',
+                                    value : 0
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'recvgrp_void'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'recv_qtys',
+                                    value : 0
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                             
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'poitem',
+                    title : "poitem",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                 
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            },
+                            beforeedit : function (e)
+                            {
+                                 if (_this.form.findField('recvgrp_id').getValue() * 1 > 0) {
+                                    Roo.MessageBox.alert("Error", "you can not modify the stock");
+                                    e.cancel = true;
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                    if (!_this.form ) {
+                                        return false;
+                                    }
+                                     o.params=  o.params || {};
+                                     
+                                    o.params.poitem_pohead_id = _this.form.findField('recvgrp_pohead_id').getValue();
+                                    o.params._with_item = 1;
+                                    o.params.item_type = 'P';    
+                                    o.params.recvgrp_id = _this.form.findField('recvgrp_id').getValue();
+                                    o.params.limit = 3000;
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'poitem_linenumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                timeout : 90000,
+                                url : baseURL + '/Roo/poitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'poitem_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_status',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_pohead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_duedate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_vend_item_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_vend_uom',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_invvenduomratio',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_qty_ordered',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_qty_received',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_qty_returned',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_qty_vouchered',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_unitprice',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_vend_item_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_qty_toreceive',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_freight',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_freight_received',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_freight_vouchered',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_soitem_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_stdcost',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_bom_rev_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_boo_rev_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_manuf_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_manuf_item_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_manuf_item_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_tax_recoverable',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_rlsd_duedate',
+                                        'type': 'date',
+                                        'dateFormat': 'Y-m-d'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_number',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_subnumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_status',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_startdate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_duedate',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_ordtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_ordid',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_qtyord',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_qtyrcv',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_adhoc',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_itemcfg_series',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_imported',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_wipvalue',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_postedvalue',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_prodnotes',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_prj_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_priority',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_brdvalue',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_bom_rev_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_boo_rev_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_cosmethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_womatl_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_wohead_id_wo_username',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_taxtype_id_taxtype_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_taxtype_id_taxtype_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_taxtype_id_taxtype_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_taxtype_id_taxtype_sys',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_status',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_so',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_wo',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_po',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_owner_username',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_start_date',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_due_date',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_assigned_date',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_completed_date',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_username',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_prj_id_prj_recurring_prj_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_item_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_item_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_vend_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_vend_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_vend_item_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_vend_item_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_vend_uom',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_invvendoruomratio',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_minordqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_multordqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_leadtime',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_ranking',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_manuf_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_manuf_item_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_manuf_item_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_default',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsrc_id_itemsrc_upccode',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_item_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_warehous_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_qtyonhand',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_reorderlevel',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_ordertoqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_cyclecountfreq',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_datelastcount',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_datelastused',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_loccntrl',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_safetystock',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_minordqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_multordqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_leadtime',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_abcclass',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_issuemethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_controlmethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_plancode_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_costcat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_eventfence',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_sold',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_stocked',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_freeze',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_location_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_useparams',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_useparamsmanual',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_soldranking',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_createpr',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_location',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_location_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_notes',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_perishable',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_nnqoh',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_autoabcclass',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_ordergroup',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_disallowblankwip',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_maxordqty',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_mps_timefence',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_createwo',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_warrpurc',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_autoreg',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_costmethod',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_value',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_ordergroup_first',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_supply_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_planning_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_wosupply',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_posupply',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_lsseq_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_cosdefault',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_createsopr',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_createsopo',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_itemsite_id_itemsite_dropship',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_code',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_exp_accnt_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_liability_accnt_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_purchprice_accnt_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'poitem_expcat_id_expcat_freight_accnt_id',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             // reset..
+                                             _this.grid.load({});
+                                        }
+                                    },
+                                    text : "Reset"
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             if (_this.form.findField('recvgrp_id').getValue() * 1 > 0) {
+                                                Roo.MessageBox.alert("Error", "you can not modify the stock");
+                                                return;
+                                            }
+                                             // reset..
+                                             _this.grid.ds.each(function(r) {
+                                                r.set('recv_qty',  r.data.poitem_qty_ordered - 
+                                                  r.data.poitem_qty_received + r.data.poitem_qty_returned
+                                                );
+                                            });
+                                            
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Recieve All",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'poitem_linenumber',
+                                header : 'Line#',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item No.',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Description',
+                                width : 150,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'poitem_qty_ordered',
+                                header : 'Ordered',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'poitem_qty_received',
+                                header : 'Remaining',
+                                width : 75,
+                                renderer : function(v,x,r) {
+                                
+                                     var vv = r.data.poitem_qty_ordered - 
+                                        r.data.poitem_qty_received + r.data.poitem_qty_returned;
+                                     return String.format('{0}', parseInt(vv)); 
+                                          
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'recv_qty',
+                                header : 'Recieved',
+                                width : 75,
+                                renderer : function(v) { 
+                                
+                                    var voided = _this.form.findField('recvgrp_void').getValue() * 1;
+                                    var format = voided ? '<s>{0}</s>' : '{0}';
+                                    return String.format(format , parseInt(v)); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        cls : 'align-right',
+                                        decimalPrecision : 0
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 150
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            if (!_this.form.findField('recvgrp_id').getValue()) {
+                                Roo.MessageBox.alert("Error", "Can not void this as it has not been saved");
+                                return;
+                            }
+                           
+                             if (1 * _this.form.findField('recvgrp_void').getValue()) {
+                                Roo.MessageBox.alert("Error", "This record is already void.");
+                                return;
+                            }
+                            new Pman.Request({
+                                mask : 'Voiding',
+                                method : 'POST',
+                                url : baseURL + '/Roo/Recvgrp',
+                                params : {
+                                    recvgrp_id : _this.form.findField('recvgrp_id').getValue(),
+                                    _void : 1
+                                },
+                                success : function() {
+                                      if (_this.callback) {
+                                        _this.callback.call(_this, _this.form.getValues());
+                                     }
+                                    _this.dialog.hide();
+                                }
+                            });
+                            
+                           
+                        
+                        }
+                    },
+                    text : "VOID"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                            
+                            var c = [];
+                            var t = 0;
+                            _this.grid.ds.each(function(r) {
+                                var q = r.data.recv_qty * 1;
+                                if (q < 1) {
+                                    return;
+                                }
+                                c.push({
+                                    recv_orderitem_id : r.data.poitem_id,
+                                    recv_qty : r.data.recv_qty
+                                });
+                                t += r.data.recv_qty * 1;
+                            });
+                            if (t < 1) {
+                                Roo.MessageBox.alert("Error", "nothing to recieve");
+                                return;
+                            }
+                            
+                            _this.form.findField('recv_qtys').setValue( Roo.encode(c));
+                            _this.form.doAction("submit");
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleReportCustomer.bjs b/Pman.Dialog.XtupleReportCustomer.bjs
new file mode 100644 (file)
index 0000000..1728776
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "id": "roo-file-347",
+    "name": "Pman.Dialog.XtupleReportCustomer",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleReportCustomer.bjs",
+    "items": [],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleReportCustomer.js b/Pman.Dialog.XtupleReportCustomer.js
new file mode 100644 (file)
index 0000000..c227083
--- /dev/null
@@ -0,0 +1 @@
+0
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleSalesOrder.bjs b/Pman.Dialog.XtupleSalesOrder.bjs
new file mode 100644 (file)
index 0000000..1b600a2
--- /dev/null
@@ -0,0 +1,3360 @@
+{
+    "id": "roo-file-27",
+    "name": "Pman.Dialog.XtupleSalesOrder",
+    "parent": false,
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleSalesOrder.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|show": "function () {\n       this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": true,
+            "collapsible": false,
+            "height": 620,
+            "modal": true,
+            "resizable": true,
+            "title": "Edit / Create Sales Order",
+            "width": 1050,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center",
+                    "alwaysShowTabs": true,
+                    "tabPosition": "top",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "Toolbar",
+                            "*prop": "toolbar",
+                            "items": [
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{\n    var id = 1* _this.form.findField('cohead_id').getValue();\n    if (!id) {\n        Roo.MessageBox.alert(\"Error\", \"Save Sales order first\");\n        return;\n    \n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/cohead',\n            method : 'GET',\n            params : {\n                cohead_id :  id,\n                _excel : 1\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Download Excel",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{\n    var id = 1* _this.form.findField('cohead_id').getValue();\n    if (!id) {\n        Roo.MessageBox.alert(\"Error\", \"Save Sales order first\");\n        return;\n    \n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/cohead',\n            method : 'GET',\n            params : {\n                cohead_id :  id,\n                _print : 1\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Print",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n\n    _this.addShipmentBtn.fireEvent('click');\n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "hidden": true,
+                                    "text": "Add Shipment",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n\n   Pman.Dialog.XtupleCustomer.show({\n         cust_id : _this.form.findField('cohead_cust_id').getValue()\n  }); \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Edit Customer",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n\n        _this.addInvoiceBtn.fireEvent('click');\n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "hidden": true,
+                                    "text": "Add Invoice",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self, e)\n{\n    _this.voidBtn = _self;\n}",
+                                        "click": "function (_self, e)\n{\n     var p = {         \n         cohead_id : _this.form.findField('cohead_id').getValue() \n     };\n    function call() {\n\n            \n       new Pman.Request({\n            mask : 'Sending',\n            url: baseURL + '/Roo/cohead',\n            method : 'POST',\n            params :  p,\n            success : function()\n            {\n                _this.callback();\n                 if ( _this.data.cohead_status == 'X') {\n                  _this.form.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});\n          \n                    return;\n                 }\n\n \n                _this.dialog.hide();\n            }\n       });\n   }\n\n  \n   if (_this.data.cohead_status == 'X') {\n        p._unvoid = 1;\n        call();\n        return;\n    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to void this?\", function(r) {\n    \n        if (r !='yes') {\n            return;\n        }\n        p._void = 1;\n        call();       \n\n      \n    });\n\n}"
+                                    },
+                                    "text": "Void",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n    var p = {          cohead_id : _this.form.findField('cohead_id').getValue() };\n    \n    var close = 1;\n    if (_this.data.cohead_status == 'C') {\n        p._reopen = 1;\n        close = 0;\n        } else {\n                p._close = 1;\n        }\n        \n   new Pman.Request({\n    url: baseURL + '/Roo/cohead',\n    method : 'POST',\n    params :  p,\n    mask : 'Sending',\n    success : function()\n    {\n           _this.callback();\n          if (!close) {\n            _this.form.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});\n          \n            return;\n          }\n       \n        _this.dialog.hide();\n    }\n   });\n    \n}",
+                                        "render": "function (_self)\n{\n   _this.closeBtn = _self;\n}"
+                                    },
+                                    "text": "Completed",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "activate": "function (_self)\n{\n    // we need to reload to find out the subtotal.\n    if (!_this.data || !_this.data.cohead_id) {\n        return;\n    }\n    new Pman.Request({\n        method : 'GET',\n        url : baseURL + '/Roo/cohead',\n        params : { \n            _id : _this.data.cohead_id\n        },\n        success : function(res) {\n            _this.form.findField('cohead_subtotal').setValue(res.data.cohead_subtotal);\n            _this.form.findField('cohead_tax').setValue(res.data.cohead_tax);\n            _this.form.findField('cohead_uninvoiced').setValue(res.data.cohead_uninvoiced);\n            _this.form.findField('cohead_unshipped').setValue(res.data.cohead_unshipped);\n           _this.form.findField('cohead_pretax_discount').setValue(res.data.cohead_pretax_discount); \n            _this.form.findField('cohead_total').recalc(); \n            _this.form.findField('cohead_misc').recalc(); \n        }\n    });\n}"
+                    },
+                    "region": "center",
+                    "title": "Order Details",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        // clear the stock level cache...\n        _this.stockcache = [];\n        \n        if (_this.data.cohead_id) {\n           this.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});\n           \n           return;\n        }\n        _this.dialog.setTitle(\"Edit New Sales Order\");\n       \n        _this.closeBtn.hide();\n        _this.voidBtn.hide();\n        _this.saveBtn.show();\n        \n        if(_this.data.cohead_billto_cntct_id_cntct_id){\n            _this.form.findField('billto_address').update();\n            \r\n            _this.form.setValues({\r\n                cohead_billto_cntct_id: _this.data.cohead_billto_cntct_id_cntct_id,\r\n                cohead_billto_cntct_id_cntct_name : _this.data.cohead_billto_cntct_id_cntct_name,\r\n                _shipto_same : 1,\n                _same_as_order : 1\n                \r\n            }); \r\n        }\n         \n       return;\n    }\n    if (action.type == 'load') {\n         \n        \n        _this.data = action.result.data;\n\n        if (!_this.data.cohead_shipto_id && _this.data.shipto_id*1 > 0) {\n            _this.form.findField('cohead_shipto_id').setValue(_this.data.shipto_id);\n            _this.form.findField('cohead_shipto_id_shipto_name').setValue(_this.data.cohead_shipto_cntct_id_cntct_name);\n        \n        }\n        \n        \n        _this.dataloading = true;\n        if (_this.data.cohead_shipto_cntct_id == _this.data.cohead_billto_cntct_id) {\n            this.findField('_shipto_same').setValue(1);\n              Roo.log(\"set shipto 1\");\n        } else {\n          this.findField('_shipto_same').setValue(0);\n           Roo.log(\"set shipto 0\");\n        }\n        _this.dataloading = false;          \n        \n        \n        this.findField('billto_address').update();\n        this.findField('shipto_address').update();        \n        _this.dialog.setTitle(\"Edit Sales Order - \" + this.findField('cohead_number').getValue());\n         \n        \n        if (_this.data.cohead_status == 'C') {\n            _this.closeBtn.show();\n            _this.closeBtn.setText('Re-open');\n             _this.voidBtn.hide();\n             _this.saveBtn.hide();\n        }  else  if (_this.data.cohead_status == 'X') {\n            _this.closeBtn.hide(); \n             _this.voidBtn.show(); \n             _this.voidBtn.setText(\"Un-void / Re-open\"); \n             _this.saveBtn.hide();\n        } else {\n            // it's open\n             _this.closeBtn.show(); \n            _this.closeBtn.setText('Complete and Close');             \n             _this.voidBtn.setText(\"Void\");             \n             _this.voidBtn.show(); \n             _this.saveBtn.show();        \n        }\n        \n         _this.form.findField('cohead_misc_per').update();\n       \n       // finally override the value for discount...\n       if ((''+ _this.data.cohead_misc_descrip).length) {\n            _this.form.findField('cohead_misc_descrip').setValue(_this.data.cohead_misc_descrip);\n       }\n       \n       // update the stockcache...\n\n       new Pman.Request({\n            url : baseURL + '/Roo/cohead',\n            method : 'GET',\n            params : {\n                _stockLevel : _this.data.cohead_id\n            },\n            success : function(res) \n            {\n                for (var i in res.data) {\n                   \n                    if(typeof(_this.stockcache[res.data[i].item]) == 'undefined'){\n                        _this.stockcache[res.data[i].item] = res.data[i];\n                    }\n                }\n            }\n        });\n       \n        return;\n    }\n    if (action.type =='submit') {\n    \n\n        var id = _this.form.findField('cohead_id').getValue() * 1;\n        if (id < 1) {\n\n            _this.data.cohead_id = action.result.data.cohead_id;\n             this.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});\n            return;\n        }\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n",
+                                "actionfailed": "function (_self, action)\n{\n    if (action.failureType == 'client') {\n        Roo.MessageBox.alert(\"Error\", \"Fill in all the required fields\");\n    }\n    if (action.failureType == 'server') {    \n        Roo.log(action);\n        Roo.MessageBox.alert(\"Error\", action.result.errorMsg);\n    }\n    _this.dialog.layout.getRegion('center').showPanel(0);\n}"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cohead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "width": "435",
+                                    "items": [
+                                        {
+                                            "labelWidth": 120,
+                                            "legend": "Order",
+                                            "style": "width:420px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelWidth": 100,
+                                                    "width": 410,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "labelWidth": 100,
+                                                            "width": 400,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowBlank": true,
+                                                                    "emptyText": "Automatic",
+                                                                    "fieldLabel": "Order#",
+                                                                    "name": "cohead_number",
+                                                                    "readOnly": true,
+                                                                    "width": 120,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "labelWidth": 50,
+                                                                    "style": "float:left",
+                                                                    "width": 150,
+                                                                    "xtype": "Row",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "allowBlank": true,
+                                                                            "fieldLabel": "Cust#",
+                                                                            "name": "cohead_cust_id_cust_number",
+                                                                            "readOnly": true,
+                                                                            "width": 110,
+                                                                            "xtype": "TextField",
+                                                                            "|xns": "Roo.form"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "editable": false,
+                                                            "fieldLabel": "Customer",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_cust_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_cust_id_cust_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select custinfo",
+                                                            "queryParam": "query[cust_name]",
+                                                            "readOnly": true,
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "cust_id",
+                                                            "width": 300,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form",
+                                                            "fieldLabel": "Customer PO#",
+                                                            "name": "cohead_custponumber",
+                                                            "width": "150"
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Ordered",
+                                                            "format": "Y-m-d",
+                                                            "name": "cohead_orderdate",
+                                                            "width": 100,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "labelWidth": 100,
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowBlank": false,
+                                                                    "fieldLabel": "Target Delivery",
+                                                                    "format": "Y-m-d",
+                                                                    "name": "cohead_targetdate",
+                                                                    "width": 100,
+                                                                    "xtype": "DateField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "hideLabels": true,
+                                                                    "xtype": "Row",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "check": "function (_self, checked)\n{\n    if(checked){\n        _this.form.findField('cohead_targetdate').setValue(_this.form.findField('cohead_orderdate').getValue());\n    }\n}"
+                                                                            },
+                                                                            "boxLabel": "same as order",
+                                                                            "inputValue": 1,
+                                                                            "name": "_same_as_order",
+                                                                            "xtype": "Checkbox",
+                                                                            "|xns": "Roo.form"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "displayField": "location_name",
+                                                            "editable": true,
+                                                            "emptyText": "Supply From",
+                                                            "fieldLabel": "Supply From",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_location_src",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_location_src_location_name",
+                                                            "pageSize": 200,
+                                                            "qtip": "Select terms",
+                                                            "queryParam": "query[location_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> {location_descrip} </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": false,
+                                                            "valueField": "location_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n      o.params.location_restrict = 0;\n      o.params._notinternalcompany = 1;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "location_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "labelWidth": 100,
+                                            "legend": "Details",
+                                            "style": "width:420px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelWidth": 100,
+                                                    "width": 420,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "ComboBox",
+                                                            "allowBlank": false,
+                                                            "editable": false,
+                                                            "emptyText": "Select terms",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select terms",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 300,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{terms_descrip}</b> </div>",
+                                                            "queryParam": "query[terms_descrip]",
+                                                            "fieldLabel": "Terms",
+                                                            "valueField": "terms_id",
+                                                            "displayField": "terms_descrip",
+                                                            "hiddenName": "cohead_terms_id",
+                                                            "name": "cohead_terms_id_terms_descrip",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'terms_descrip' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/terms.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "terms_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"terms_id\",\"type\":\"int\"},\"terms_descrip\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": true,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "salesrep_name",
+                                                            "editable": false,
+                                                            "emptyText": "Select salesrep",
+                                                            "fieldLabel": "Sales Rep",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_display_salesrep_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_display_salesrep_id_salesrep_name",
+                                                            "pageSize": 80,
+                                                            "qtip": "Select salesrep",
+                                                            "queryParam": "query[salesrep_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "salesrep_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'salesrep_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/salesrep.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "salesrep_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"},\"salesrep_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowBlank": false,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "salesrep_name",
+                                                            "editable": false,
+                                                            "emptyText": "Select Staff",
+                                                            "fieldLabel": "Staff I.C.",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_salesrep_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_salesrep_id_salesrep_name",
+                                                            "pageSize": 80,
+                                                            "qtip": "Select salesrep",
+                                                            "queryParam": "query[salesrep_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "salesrep_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'salesrep_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/salesrep.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "salesrep_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"},\"salesrep_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Order Comments",
+                                                            "height": 80,
+                                                            "name": "cohead_ordercomments",
+                                                            "width": 300,
+                                                            "xtype": "TextArea",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "style": "width:420px",
+                                            "legend": "Billing",
+                                            "items": [
+                                                {
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "width": "420",
+                                                    "labelWidth": "50",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeselect": "function (combo, record, index)\n{\n    // set _this.data values ..\n    \n    // just add everything...\n    for(var i in record.data) {\n        Roo.log('cohead_billto_cntct_id_' + i +' ='  + record.data[i]);\n        _this.data['cohead_billto_cntct_id_' + i] = record.data[i];\n    }\n    \n    _this.form.findField('billto_address').update();\n    \n \n}",
+                                                                "add": "function (combo)\n{\n  \n  Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cohead_cust_id').getValue()\n            },\n            \n            function (data) {\n               \n                for(var i in  data) {\n                    \n                    _this.data['cohead_billto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('billto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cohead_billto_cntct_id : data.cntct_id,\n                    cohead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                    \n                });\n            }\n        );\n        //  Pman.Dialog.XtupleCustomer.show(\n            //{ cust_id : _this.form.findField('cohead_cust_id').getValue() }, \n            //function(data) {\n        // refresh the data in the pulldown..\n    //    }); \n\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "cntct_name",
+                                                            "editable": true,
+                                                            "emptyText": "Select cntct",
+                                                            "fieldLabel": "Bill To (select)",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_billto_cntct_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_billto_cntct_id_cntct_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select cntct",
+                                                            "queryParam": "query[cntct_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cntct_name}</b> {cntct_addr_id_addr_line1}</div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "cntct_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params._customer_id = _this.data.cohead_cust_id;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'cntct_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/cntct.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "cntct_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"cntct_id\",\"type\":\"int\"},\"cntct_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n   Roo.log(this.el)\n   \n   \n   \n   this.el.on('click', function() { \n       var id = _this.form.findField('cohead_billto_cntct_id').getValue();\n        Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cohead_cust_id').getValue()\n            },\n            \n            function (data) {\n            \n                for(var i in  data) {\n                    \n                    _this.data['cohead_billto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('billto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cohead_billto_cntct_id : data.cntct_id,\n                    cohead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                    \n                });\n                \n                        \n                Roo.log(data);\n            }\n        );\n   \n        Roo.log(\"Click text\");\n        \n        \n     });\n}"
+                                                            },
+                                                            "fieldLabel": "or enter Address",
+                                                            "name": "billto_address",
+                                                            "readOnly": true,
+                                                            "xtype": "TextArea",
+                                                            "|update": "function() {\n\n    var c = ['first_name', 'last_name' ] ;\n    var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];\n    var v = [];\n    Roo.each(c, function(e) {\n        if (_this.data['cohead_billto_cntct_id_cntct_' +e].length) { \n            v.push(_this.data['cohead_billto_cntct_id_cntct_' +e]);\n        }\n    });\n    Roo.each(a, function(e) {\n        if (_this.data['cohead_billto_cntct_id_cntct_addr_id_addr_' +e].length) {\n            v.push(_this.data['cohead_billto_cntct_id_cntct_addr_id_addr_' +e]);\n        }\n    });\n\n    this.setValue(v.join(\"\\n\"));\n}\n",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "width": "435",
+                                    "style": "margin-left:10px",
+                                    "items": [
+                                        {
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "legend": "Price Details",
+                                            "style": "width:420px",
+                                            "labelWidth": "50",
+                                            "items": [
+                                                {
+                                                    "labelAlign": "right",
+                                                    "labelWidth": 300,
+                                                    "width": 420,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "beforequery": "function (combo, query, forceAll, cancel, e)\n{\n    Roo.log('beforequery');\n   \n    if (_this.form.findField('cohead_number').getValue().length) {\n        Roo.MessageBox.alert(\"Error\", \"You can not change the currency of this order\");\n        if (query) {\n            query.cancel = true;\n        }\n        return false;\n    }\n}"
+                                                                    },
+                                                                    "allowBlank": false,
+                                                                    "displayField": "curr_name",
+                                                                    "editable": false,
+                                                                    "emptyText": "Select curr_name",
+                                                                    "fieldLabel": "Currency",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "cohead_curr_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "cohead_curr_id_curr_name",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select Currency",
+                                                                    "queryParam": "query[curr_name]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "curr_id",
+                                                                    "width": 285,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n   \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "method": "GET",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "id": "curr_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Products",
+                                                                    "name": "cohead_subtotal",
+                                                                    "readOnly": true,
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "select": "function (combo, record, index)\n{\n     _this.form.findField('cohead_tax').setValue(\n             parseFloat(record.data.taxzone_rate) * \n             parseFloat(_this.form.findField('cohead_subtotal').getValue())\n     );\n      _this.form.findField('cohead_total').recalc();\n}"
+                                                                    },
+                                                                    "allowBlank": false,
+                                                                    "displayField": "taxzone_descrip",
+                                                                    "editable": false,
+                                                                    "emptyText": "Select taxtype",
+                                                                    "fieldLabel": "Tax Zone",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "cohead_taxzone_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "cohead_taxzone_id_taxzone_descrip",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select taxtype",
+                                                                    "queryParam": "query[taxzone_descrip]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxzone_descrip}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "taxzone_id",
+                                                                    "width": 285,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    \n    o.params.with_date = _this.form.findField('cohead_orderdate').getValue().format('Y-m-d'); \n    Roo.log(\"with date?\" + o.params.with_date);\n    \n    \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'taxzone_descrip' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/taxzone.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "taxzone_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[{\"name\":\"taxzone_id\",\"type\":\"int\"},\"taxzone_descrip\"]",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "Tax",
+                                                                    "name": "cohead_tax",
+                                                                    "readOnly": true,
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowDecimals": true,
+                                                            "cls": "roo-align-right",
+                                                            "decimalPrecision": 3,
+                                                            "fieldLabel": "Pre Tax discount",
+                                                            "name": "cohead_pretax_discount",
+                                                            "readOnly": true,
+                                                            "width": 100,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "labelAlign": "top",
+                                                            "labelSeparator": "&nbsp;",
+                                                            "width": 500,
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "Discount after Tax  Description",
+                                                                    "name": "cohead_misc_descrip",
+                                                                    "width": 230,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "keyup": "function (_self, e)\n{\n    var pv =  parseFloat(_this.form.findField('cohead_subtotal').getValue());\n    var tax = parseFloat(_this.form.findField('cohead_tax').getValue());\n    var pd = parseFloat(_this.form.findField('cohead_pretax_discount').getValue());\n    \n    var n = this.getValue();\n    var discount = parseFloat(n * (pv + tax + pd) * 0.01);\n    \n    _this.form.findField('cohead_posttax_discount').setValue(discount);\n\n    _this.form.findField('cohead_total').recalc();\n    _this.form.findField('cohead_misc').recalc();\n    var val = discount * -1.0;\n     if (val > 0) {\n        _this.form.findField('cohead_misc_descrip').setValue(\"Discount of \" + val.toFixed(1)+'%');\n    }\n   \n    \n}"
+                                                                    },
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 1,
+                                                                    "fieldLabel": "%",
+                                                                    "name": "cohead_misc_per",
+                                                                    "width": 35,
+                                                                    "xtype": "NumberField",
+                                                                    "|update": "function() {\n    var m = _this.form.findField('cohead_misc_per');\n    var pv =  parseFloat(_this.form.findField('cohead_subtotal').getValue());\n    var tax = parseFloat(_this.form.findField('cohead_tax').getValue());\n    var pd = parseFloat(_this.form.findField('cohead_pretax_discount').getValue());\n    \n    var discount = parseFloat(_this.form.findField('cohead_posttax_discount').getValue());\n    \n    if (discount > 0.0) {\n        this.setValue(0);        \n        return;\n    }\n    if (pv < 0) {\n        this.setValue(0);        \n        return;\n    }\n    var val = ((discount) / (pv + tax + pd)) * -100;\n    \n    //Roo.log(\"update discount?\" + val);\n    this.setValue(val.toFixed(1));\n    \n     if (val > 0.0) {\n        _this.form.findField('cohead_misc_descrip').setValue(\"Discount of \" + val.toFixed(1)+'%');\n    \n    }\n    \n   \n}\n",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "keyup": "function (_self, e)\n{\n   _this.form.findField('cohead_misc_per').update();\n    _this.form.findField('cohead_total').recalc();\n    _this.form.findField('cohead_misc').recalc();\n}"
+                                                                    },
+                                                                    "allowDecimals": true,
+                                                                    "cls": "roo-align-right",
+                                                                    "decimalPrecision": 3,
+                                                                    "fieldLabel": "&nbsp;",
+                                                                    "name": "cohead_posttax_discount",
+                                                                    "width": 100,
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "allowDecimals": true,
+                                                            "cls": "roo-align-right",
+                                                            "decimalPrecision": 3,
+                                                            "fieldLabel": "Total",
+                                                            "name": "cohead_total",
+                                                            "readOnly": true,
+                                                            "width": 100,
+                                                            "xtype": "NumberField",
+                                                            "|recalc": "function() {\n    var d = _this.form.getValues();\n    this.setValue( \n                parseFloat(d.cohead_subtotal) + \n                parseFloat(d.cohead_pretax_discount) + \n                parseFloat(d.cohead_posttax_discount) + \n                parseFloat(d.cohead_tax) + \n                parseFloat(d.cohead_freight));\n}\n",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "keyup": "function (_self, e)\n{\n    _this.form.findField('cohead_total').recalc();\n}"
+                                                            },
+                                                            "allowDecimals": true,
+                                                            "cls": "roo-align-right",
+                                                            "decimalPrecision": 3,
+                                                            "fieldLabel": "Shipping",
+                                                            "name": "cohead_freight",
+                                                            "width": 100,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowDecimals": true,
+                                                            "cls": "roo-align-right",
+                                                            "decimalPrecision": 3,
+                                                            "fieldLabel": "Unshipped Total",
+                                                            "name": "cohead_unshipped",
+                                                            "readOnly": true,
+                                                            "width": 100,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "allowDecimals": true,
+                                                            "cls": "roo-align-right",
+                                                            "decimalPrecision": 3,
+                                                            "fieldLabel": "Uninvoiced Total",
+                                                            "name": "cohead_uninvoiced",
+                                                            "readOnly": true,
+                                                            "width": 100,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "style": "width:420px",
+                                            "legend": "Shipping",
+                                            "items": [
+                                                {
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "width": "420",
+                                                    "labelWidth": "50",
+                                                    "items": [
+                                                        {
+                                                            "labelSeparator": "&nbsp;",
+                                                            "xtype": "Row",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "check": "function (_self, checked)\n{\n   if (!_this.form) {\n       return;\n   }\n   \n   if (_this.dataloading) {\n   \n       return;\n   }\n   \n   \n   if (checked) {\n   \n        // copy the cohead_billto_cntct_id\n        for (var i in _this.data) {\n            if (!i.match(/^cohead_billto_cntct_id/)) {\n                continue;\n            }\n            var ni = i.replace(/^cohead_billto_cntct_id/, 'cohead_shipto_cntct_id');\n            _this.data[ni] = _this.data[i];\n        }\n         _this.form.findField('shipto_address').update();\n         _this.form.setValues( {\n                cohead_shipto_cntct_id : _this.data.cohead_shipto_cntct_id,\n                cohead_shipto_cntct_id_cntct_name : _this.data.cohead_shipto_cntct_id_cntct_first_name + ' ' + \n                        _this.data.cohead_shipto_cntct_id_cntct_last_name \n                        \n                \n            });\n\n   \n    } else {\n         for (var i in _this.data) {\n            if (!i.match(/^cohead_billto_cntct_id/)) {\n                continue;\n            }\n            var ni = i.replace(/^cohead_billto_cntct_id/, 'cohead_shipto_cntct_id');\n            \n            _this.data[ni] = '';\n        }\n         _this.form.findField('shipto_address').update();\n         \n        _this.form.setValues( {\n                cohead_shipto_cntct_id : '',\n                cohead_shipto_cntct_id_cntct_name : '' \n                \n                \n            });\n    }\n    \n}"
+                                                                    },
+                                                                    "boxLabel": "Same as Billing",
+                                                                    "name": "_shipto_same",
+                                                                    "xtype": "Checkbox",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "add": "function (combo)\n{\n Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cohead_cust_id').getValue()\n            },\n            \n            function (data) {\n               \n                for(var i in  data) {\n                    \n                    _this.data['cohead_shipto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('shipto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cohead_shipto_cntct_id : data.cntct_id,\n                    cohead_shipto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                    \n                });\n            }\n        ); \n}",
+                                                                "beforeselect": "function (combo, record, index)\n{\n   \n    // just add everything...\n    for(var i in record.data) {\n        //Roo.log('cohead_shipto_cntct_id_' + i +' ='  + record.data[i]);\n        _this.data['cohead_shipto_cntct_id_' + i] = record.data[i];\n    }\n\n    _this.form.findField('shipto_address').update();\n    \n \n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "cntct_name",
+                                                            "editable": true,
+                                                            "emptyText": "Select ship to",
+                                                            "fieldLabel": "Ship to",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "cohead_shipto_cntct_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "cohead_shipto_cntct_id_cntct_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select shiptoinfo",
+                                                            "queryParam": "query[cntct_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\">{cntct_name} - <b>{cntct_addr_id_addr_line1}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "valueField": "cntct_id",
+                                                            "width": 300,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params._customer_id = _this.data.cohead_cust_id;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'cntct_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/cntct.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "cntct_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"cntct_id\",\"type\":\"int\"},\"cntct_name\"]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n   Roo.log(this.el)\n   \n   \n   \n   this.el.on('click', function() { \n       var id = _this.form.findField('cohead_shipto_cntct_id').getValue();\n        Pman.Dialog.XtupleQuickContact.show( \n            {\n              _id : id,\n              customer_id : _this.form.findField('cohead_cust_id').getValue()\n            },\n            \n            function (data) {\n            \n                for(var i in  data) {\n                    \n                    _this.data['cohead_shipto_cntct_id_' + i] =  data[i];\n                }\n                \n                _this.form.findField('shipto_address').update();\n                // fill in the select box..\n                _this.form.setValues( {\n                    cohead_shipto_cntct_id : data.cntct_id,\n                    cohead_shipto_cntct_id_cntct_name : data.cntct_first_name + ' '+ \n                            data.cntct_last_name\n                    \n                });\n                \n                        \n                //Roo.log(data);\n            }\n        );\n   \n      //  Roo.log(\"Click text\");\n        \n        \n     });\n}"
+                                                            },
+                                                            "fieldLabel": "Address",
+                                                            "name": "shipto_address",
+                                                            "readOnly": true,
+                                                            "width": 300,
+                                                            "xtype": "TextArea",
+                                                            "|update": "function() {\n\n    var c = ['first_name', 'last_name' ] ;\n    var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];\n    var v = [];\n    Roo.each(c, function(e) {\n        if (_this.data['cohead_shipto_cntct_id_cntct_' +e] && \n            _this.data['cohead_shipto_cntct_id_cntct_' +e].length) {\n            v.push(_this.data['cohead_shipto_cntct_id_cntct_' +e]);\n        }\n    });\n    Roo.each(a, function(e) {\n        if (_this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e] && \n            _this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e].length) { \n            v.push(_this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e]);\n        }\n    });\n\n    this.setValue(v.join(\"\\n\"));\n}\n",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "xtype": "TextArea",
+                                                            "|xns": "Roo.form",
+                                                            "fieldLabel": "Shipment Comments",
+                                                            "name": "cohead_shipcomments",
+                                                            "width": 300
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "cohead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cohead_shipto_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cohead_shipto_id_shipto_name",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cohead_max_linenumber",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cohead_cust_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "cohead_misc",
+                                    "xtype": "Hidden",
+                                    "|recalc": "function() {\n    var d = _this.form.getValues();\n    this.setValue( \n        parseFloat(d.cohead_pretax_discount) + \n        parseFloat(d.cohead_posttax_discount) );\n}\n",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "taxzone_rate",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    \n    try { if (MODULE.isBuilder) {\n        return;\n    } } catch(e) { }\n    \n    var id = _this.form.findField('cohead_id').getValue() * 1;\n    if (id < 1) {\n        Roo.MessageBox.alert(\"Save First\", \"Save the order first, before adding items\");\n        _this.dialog.layout.getRegion('center').showPanel(0);\n        return;\n    }\n    \n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    \n         //if (_this.form.findField('cohead_cust_id_cust_name').getValue() == 'Bloom and Grow HK') {\n         //   _this.xferAll.show();\n        // \n        // } else {\n        //     _this.xferAll.hide();\n        // }\n     }\n    \n}",
+                        "deactivate": "function (_self)\n{\n    if(_this.grid){\n        _this.grid.stopEditing();\n    }\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "coitem",
+                    "title": "Order Items",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    \n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "afteredit": "function (e)\n{\n    Roo.log('afteredit:' + e.record.data.coitem_linenumber);\n\n    \n   // if ( e.record && e.record.data.coitem_id) {\n        // as we disable update to the display on the ajax callback to \n        // allow editing flow to continue, and not refresh - we can only update\n        // these values after something has actually been edited.\n        // e.record.set('coitem_id', e.record.data.coitem_id);\n        // e.record.set('coitem_status', e.record.data.coitem_status);\n   // }\n    \n    if (e.field == 'item_number' || e.originalValue == e.value) {\n        // afterselect handles this...\n        return;\n    }\n    if (e.field == 'item_descrip1') {\n        e.record.set('coitem_memo', e.value);\n    }\n    var rate = _this.form.findField('taxzone_rate').getValue();\n    switch(e.field) {\n        case 'coitem_linedisc':\n           \n            var cp = parseFloat(e.record.data.coitem_custprice);\n           \n            if (isNaN(cp) || cp == 0.0) {\n                break;\n            }\n            \n            var dis = parseFloat(e.value);\n           \n            if (isNaN(dis)) {\n                break;\n            }\n            \n            e.record.set(\n                'coitem_price',\n                Math.max(0,cp * ((100.0 -  parseInt(e.value))/ 100.0) )  \n            );\n            \n           // donot need to set the subtotal here, coz we will render it automatically\n           // e.record.set(\n           //     'coitem_subtotal',\n           //      e.record.data.coitem_price * 1.0 * e.record.data.coitem_qtyord\n           // );\n            break;\n        \n        case  'coitem_price': // SELL@ price\n\n             var cp = parseFloat(e.record.data.coitem_custprice);\n             // list price is < price -- update it..\n             if (isNaN(cp) || cp == 0.0 || cp < e.value) {\n                e.record.set('coitem_custprice', e.value);\n                cp = e.value;\n             }\n             // update the discount calc.\n             \n             e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( e.value / cp) * 100.0)));  \n             \n             // donot need to set the subtotal here, coz we will render it automatically\n             //e.record.set(\n             //   'coitem_subtotal',\n              //   e.record.data.coitem_price * 1.0 * e.record.data.coitem_qtyord\n             //);\n             break;\n        \n        case 'coitem_custprice':\n            // modified customer price...\n            // just modify the discount.. -- leave the entered price the same..\n              var sp =  parseFloat(e.record.data.coitem_price);\n              var cp = parseFloat(e.value);\n              if (isNaN(cp) || cp == 0.0 || cp < e.value) {\n                    break;\n              }\n              \n             e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  \n             \n             break;\n             \n        case 'coitem_custprice_tax':\n              var cp = parseFloat(e.value / ( 1 + rate * 1 ));\n              var sp =  parseFloat(e.record.data.coitem_price);\n              \n              if (isNaN(cp) || cp == 0.0) {\n                    break;\n              }\n              e.record.set('coitem_custprice', cp);\n              e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  \n             \n             break; \n             \n         case  'coitem_price_tax':\n\n             var cp = parseFloat(e.record.data.coitem_custprice);\n             var sp = parseFloat(e.value / ( 1 + rate * 1 ));\n             if (isNaN(cp) || cp == 0.0 || cp < sp) {\n                e.record.set('coitem_custprice', sp);\n                cp = sp;\n             }\n             e.record.set('coitem_price', sp);\n             e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  \n             \n             break;\n      \n    }\n    \n     \n    \n    \n    var doupdate = function() { \n       if (!e.record.updatePending) {\n            Roo.log('doupdate...'  + e.record.data.coitem_linenumber);\n            Roo.log(e.record);\n            e.record.commit();\n            return;\n        }\n       Roo.log('doupdate pending...'   + e.record.data.coitem_linenumber);\n        // wait until it's not peding an update..\n        doupdate.defer(500);\n    }\n\n    if(e.record.data.coitem_id * 1 < 1 && !e.record.isInserting){ // insert\n        e.record.isInserting = 1;\n        e.record.isUpdating = 0;\n        doupdate();\n        return;\n    }\n    \n    // update\n    if(!e.record.isInserting && !e.record.isUpdating){\n        e.record.isUpdating = 1;\n        doupdate();\n        return;\n    }\n    \n    if(!e.record.updatePending){\n        e.record.updatePending = 1;\n        doupdate();\n        return;\n    }\n    Roo.log(\"got to end without doing an update?\"  + e.record.data.coitem_linenumber);\n    \n}\n",
+                                "beforeedit": "function (e)\n{\n    // we can only edit if nothing is assigned to shipping or invoices..\n    \n    var rec = e.record\n\n    if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0 || (rec.data.shipitem_shipped - rec.data.coitem_qtyshipped) > 0 ) {\n        Roo.MessageBox.alert(\"Error\", \"That item has been shipped, has a draft shipment  or invoices - void the shipments/invoices first\");\n        e.cancel = true;\n        return;\n    }\n    \n    if (rec.data.coitem_subnumber * 1 > 0) {\n        Roo.log(\"Edit container event\");\n        Roo.log(e); // if it's a tab.. \n\n        \n        switch(e.field) {\n            // allow editing of source / destination..\n            case 'coitem_shipto_id':\n            case 'coitem_location_src':            \n                return;\n            default : \n                break;\n        }\n        Roo.MessageBox.alert(\"Error\", \"That is a kit item, edit the container.\");\n        e.cancel = true;\n        return;\n    }\n    // zero off values..\n    //if (e.field == 'coitem_qtyord' && rec.data.coitem_qtyord == 0) {\n    //        e.value ='';\n    //    }\n    //    if (e.field == 'coitem_custprice' && rec.data.coitem_qtyord == 0.0) {\n    //        e.value ='';\n    //    }\n    \n    if (rec.data.item_type == 'K' && e.field == 'item_number') {\n        // you can not change the product type on kits' as it messing things up..\n        Roo.MessageBox.alert(\"Error\", \"That is a kit item,if you need to change it, delete it first.\");\n        e.cancel = true;\n        return;\n    }\n    \n}",
+                                "celldblclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var rec = this.ds.getAt(rowIndex);\n    var di = this.cm.getDataIndex(columnIndex);\n    if (di != 'avail_qty') {\n        return;\n    }\n    \n    Pman.Dialog.XtupleInvHistory.show({\n        itemsite_item_id_item_number   : rec.data.item_number,\n       // itemsite_item_id_item_descript1 : rec.data.item_descrip1,\n        location_name : rec.data.coitem_location_src_location_name,\n        location_descrip : rec.data.coitem_location_src_location_descrip,\n        \n        invhist_transdate : _this.form.findField('cohead_targetdate').getValue() \n    }); \n    \n}",
+                                "rowclass": "function (gridview, rowcfg)\n{\n    if (rowcfg.record.data.coitem_status == 'C' &&\n        rowcfg.record.data.shipitem_shipped * 1 < 1) {\n        \n        rowcfg.rowClass = 'strikethrough';\n    }\n     if (rowcfg.record.data.coitem_status == 'X'  ) {\n        \n        rowcfg.rowClass = 'strikethrough';\n    }\n    \n    if (!rowcfg.record.data.coitem_id) { \n            rowcfg.rowClass = 'dragon-not-saved';\n    }\n    \n    \n   // Roo.log(rowcfg);\n//    shipitem_shipped\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_descrip1",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|loadAvail": "function() {\n    \n    \n    this.ds.each(function(r) {\n        \n        if(!r.data.item_number.length){\n            return;\n        }\n        \n        if(typeof(_this.stockcache[r.data.item_number]) != 'undefined'){\n        \n            r.set('avail_qty', _this.stockcache[r.data.item_number].qty);\n            if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {\n                r.set('coitem_unitcost_in_order_cur', _this.stockcache[r.data.item_number].unitcost);\n            }\n            return;\n        }\n        \n        var q = [];\n        \n        q.push( { \n            item : r.data.item_number, \n            loc: r.data.coitem_location_src_location_name,\n            id: r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '')\n         } );\n         \n         new Pman.Request({\n            url : baseURL + '/Roo/itemloc',\n            method : 'POST',\n            params : {\n                _availqty : Roo.encode(q),\n                curr_name : _this.form.findField('cohead_curr_id').el.dom.value\n            },\n            success : function(res) \n            {\n                for (var i in res.data) {\n                   _this.stockcache[res.data[i].item] = res.data[i];\n                }\n                r.set('avail_qty', _this.stockcache[r.data.item_number].qty);\n                if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {\n                    r.set('coitem_unitcost_in_order_cur', _this.stockcache[r.data.item_number].unitcost);\n                }\n                //_this.grid.ds.fireEvent(\"update\", _this.grid.ds, r, Roo.data.Record.EDIT);\n                return\n            }\n        });\n    });\n        \n                \n}\n",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "tabend": "function (_self)\n{\n    _this.addItemBtn.fireEvent('click', _this.addItemBtn);\n}",
+                                        "beforeeditnext": "function (eventdata)\n{\n    \n    return;\n    // this does not work, as the reload effect cancels editng.\n    var rec = _this.grid.ds.getAt(eventdata.cell[0]);\n    if (rec.data.coitem_subnumber *1 < 0 ) {\n        return;\n    }\n    var r = eventdata.cell[0] + 1;\n\n    while (true) {\n        if (r > _this.grid.ds.getCount()-1 ) {\n            eventdata.cell = false;\n            return;\n        }\n        rec =  _this.grid.ds.getAt(r);\n        if (rec.data.coitem_subnumber *1 < 0 ) {\n           eventdata.cell = [ r, eventdata.cell[1] ];\n           return;\n        }\n        r++;\n    }\n    \n    \n \n\n}"
+                                    },
+                                    "*prop": "sm",
+                                    "enter_is_tab": true,
+                                    "xtype": "CellSelectionModel",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "emptyMsg": "No Items",
+                                    "pageSize": 100,
+                                    "xtype": "PagingToolbar",
+                                    "|updateSummary": "function() {\n    var f = this;\n    new Pman.Request({\n        url : baseURL + '/Roo/Coitem',\n        method : 'GET',\n        params : {\n            _totals : 1,\n            coitem_cohead_id : _this.form.findField('cohead_id').getValue()\n        },\n        success : function(d) {\n            //Roo.log(d);\n            f.displayEl.update(String.format(\n                \"{0} items |  Subtotal: {2} | Tax: {3} | List Discount {4} | Total : {1}{5}\",\n                d.data.total_qty,\n                _this.form.findField('cohead_curr_id').el.dom.value,\n                d.data.total_sub,\n                d.data.total_tax,\n                d.data.total_list_discount,                \n                d.data.total_total\n            ));\n                \n        }\n    });\n}\n",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    new Pman.Request({\n        url : baseURL + '/Roo/Cohead',\n        method : 'GET',\n        params : {\n            _fill_shipto : _this.form.findField('cohead_id').getValue()\n        },\n        success : function() {\n            _this.grid.footer.onClick('first');\n        }\n    });\n}"
+                                            },
+                                            "text": "Fill empty Ship To",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure?<BR>\"+\n        \"This will set all the locations to match the Sales Order - and remove all old locations.\",\n        function (res) {\n            if(res!='yes') {\n                return;\n            \n            }\n            new Pman.Request({\n                url : baseURL + '/Roo/Cohead',\n                method : 'GET',\n                params : {\n                    _fill_location : _this.form.findField('cohead_id').getValue(),\n                    _location_id : _this.form.findField('cohead_location_src').getValue()\n                },\n                success : function() {\n                    _this.grid.footer.onClick('first');\n                }\n            });\n    });\n    \n}"
+                                            },
+                                            "text": "Update Location to match S/O",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "toggle": "function (_self, pressed)\n{\n    this.setText(pressed ? \"Prices exc GST\" : \"Prices with GST\");\n    var cm = _this.grid.getColumnModel();\n\n    cm.setHidden(cm.getIndexByDataIndex('coitem_price_tax'), pressed ? false : true);\n    cm.setHidden(cm.getIndexByDataIndex('coitem_custprice_tax'), pressed ? false : true);\n    cm.setHidden(cm.getIndexByDataIndex('coitem_subtotal_tax'), pressed ? false : true);\n    \n    cm.setHidden(cm.getIndexByDataIndex('coitem_price'), pressed ? true : false);\n    cm.setHidden(cm.getIndexByDataIndex('coitem_custprice'), pressed ? true : false);\n    cm.setHidden(cm.getIndexByDataIndex('coitem_subtotal'), pressed ? true : false);\n    return;\n}",
+                                                "render": "function (_self)\n{\n    _this.showgstBtn = _self;\n}"
+                                            },
+                                            "enableToggle": true,
+                                            "minWidth": 100,
+                                            "text": "Prices with GST",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|beforeload": "function (_self,o) {\n\n    try {\n       this.removeAll();\n   } catch (e) { }\n   \n\n    if (!_this.data || !_this.data.cohead_id) {\n        return false;\n    }\n    o.params = o.params || {};\n    \n    o.params.coitem_cohead_id = _this.data.cohead_id;\n    o.params._without_list_discount =1;\n    //o.params.limit = 999;\n\n    \n}",
+                                        "update": "function (_self, rec, operation)\n    {\n   \n   if (operation !=  Roo.data.Record.COMMIT) {\n       return;\n   }\n\n   // row has been updated..\n   // if the qty + item has been filled in, we should try and save it..\n \n    \n    var setRecord = function(){\n    \n         Roo.log(\"Clearing update?\"  + rec.data.coitem_linenumber);\n        rec.updatePending = 0;\n        if(rec.isInserting){\n            rec.isInserting = 0;\n            return;\n        }\n        rec.isUpdating = 0;\n\n    }\n    if (!(rec.data.coitem_itemsite_id * 1) || !(rec.data.coitem_qtyord*1)) {\n        setRecord();\n        return;\n    }\n    var     doCommit = function() {\n         Roo.log(\"Sending  data?\"  + rec.data.coitem_linenumber);\n        \n        new Pman.Request({\n            url : baseURL+'/Roo/coitem',\n            method : 'POST',\n            params : rec.data,\n            success: function(res)\n            {\n                try {\n                    var row = _this.grid.ds.indexOf(rec);\n                    Roo.get(_this.grid.view.getRow(row)).removeClass('dragon-not-saved');\n                } catch(e) {\n                    Roo.log(e);\n                }\n                    \n                \n                 Roo.log(\"GOT success: \"  + rec.data.coitem_linenumber);\n                //Roo.log(\"GOT success\");\n                // update the data...\n                \n                if (rec.data.item_type == 'K') {\n                     Roo.log(\"Kit??\");\n                    _this.grid.ds.load({});\n                    \n                    return;\n                }\n                \n                // why is this here.??\n                \n                if (_this.grid.activeEditor) {\n                     rec.editing = true;\n                     \n                     \n                 } \n                 \n                rec.set('coitem_id', res.data.coitem_id);\n                rec.set('coitem_status', res.data.coitem_status);\n                 \n                \n                rec.dirty = false;\n                delete rec.modified;\n                try {\n                    _this.grid.footer.updateSummary();          \n                    _this.grid.loadAvail();\n                } catch (e) { }\n                \n\n                setRecord();\n            },\n            failure : function(res)\n            {\n                setRecord();\n                Roo.MessageBox.alert(\"Error\", res.errorMsg ? res.errorMsg : \"Error updating\");\n            }\n            \n            \n        });\n      } ; \n   \n    \n    doCommit();\n    \n    \n    \n}\n   \n  ",
+                                        "load": "function (_self, records, options)\n{\n    // need to fetch availablity from master data..\n    // build a list of what to ask..\n\n    // query: ITEM CODE - LOCATION\n    _this.grid.footer.updateSummary();\n    _this.grid.loadAvail.defer(100, _this.grid);\n\n    \n    \n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'coitem_linenumber,coitem_subnumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/coitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "id": "coitem_id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'coitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyord'\n    },\n    {\n        'name': 'coitem_unitcost'\n    },\n    {\n        'name': 'coitem_price'\n    },\n    {\n        'name': 'coitem_custprice'\n    },\n    {\n        'name': 'coitem_qtyreturned'\n    },\n    {\n        'name': 'coitem_prcost'\n    },\n    {\n        'name': 'coitem_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyreserved'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n   \n    Roo.log(\"add presed\");\n     \n    // work out last \n    var grid = _this.grid;\n    var err = false;\n    grid.ds.each(function(r) {\n        if (r.data.coitem_qtyord < 1) { \n            Roo.MessageBox.alert(\"Error\", \"you must fill in a quantity for \" + r.data.item_number);\n            err = true;\n            return true;\n        }\n        \n    });\n    if (err) {\n        return;\n    }\n    \n\n//    var last = 0;\n    var last = _this.form.findField('cohead_max_linenumber').getValue();   \n    last++; \n    if(last == 99999){\n        last++;\n    }\n    \n\n    _this.form.findField('cohead_max_linenumber').setValue(last);    \n    \n    // this should be getting the previous row..??\n     var ct  =    _this.grid.ds.getCount();\n     var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;\n     \n     function lastor(k,d,kk) {\n        var def = d ? _this.form.findField(k).el.dom.value : _this.form.findField(k).getValue();\n        return lastrow ? lastrow.data[kk] : def;\n     }\n    \n    // uses form defaults or last row value.\n    var nr = _this.grid.ds.reader.newRow({\n        coitem_linenumber : last,\n        item_number : '',\n        item_descrip1 : '',\n        coitem_qtyord : 0,\n        coitem_cohead_id : _this.form.findField('cohead_id').getValue(),\n        coitem_qtyshipped : 0,\n        coitem_location_src : lastor('cohead_location_src',false, 'coitem_location_src'),\n        coitem_location_src_location_name : lastor('cohead_location_src',true, 'coitem_location_src_location_name'),\n        coitem_shipto_id    :  lastor('cohead_shipto_id',false, 'coitem_shipto_id'),\n        coitem_shipto_id_shipto_name  : lastor('cohead_shipto_id_shipto_name', false, 'coitem_shipto_id_shipto_name'),\n        coitem_unitcost_in_order_cur  : 0,\n        coitem_taxtype_id : _this.data.default_taxtype_id,\n        coitem_taxtype_id_taxtype_name : 'Taxable',\n        coitem_status : '',\n        avail_qty : 0\n                \n    });\n    grid.stopEditing();\n    grid.ds.insert(grid.ds.getCount(), nr); \n    grid.startEditing(grid.ds.getCount()-1, 1); // type..\n    nr.updatePending = 0;\n    nr.isUpdating = 0;\n    nr.isInserting =0;\n    \n}\n",
+                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Add",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    var last = _this.form.findField('cohead_max_linenumber').getValue();    \r\n    last++;\r\n    _this.form.findField('cohead_max_linenumber').setValue(last); \n\n    var ct  =    _this.grid.ds.getCount();\r\n    var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;\r\n         \r\n    function lastor(k,d,kk) {\r\n       var def = d ? _this.form.findField(k).el.dom.value : _this.form.findField(k).getValue();\r\n       return lastrow ? lastrow.data[kk] : def;\r\n    }\n    \n    var cohead_cust_id = _this.form.findField('cohead_cust_id').getValue();\n    var cohead_id = _this.form.findField('cohead_id').getValue();\n    \n    Pman.Dialog.XtupleSalesProductList.show( {cohead_cust_id : cohead_cust_id, cohead_id : cohead_id} , function(res) {\n\n        _this.grid.stopEditing();\n\n        if (_this.grid.ds.getCount() > 0) {\n            var lr = _this.grid.ds.getAt(_this.grid.ds.getCount()-1);\n            if (!lr.data.coitem_itemsite_id) {\n                lr.set('coitem_itemsite_id', res.item_itemsite_id_itemsite_id);\n                lr.set('item_number',  res.item_number);\n                lr.set('item_descrip1', res.item_descrip1);                                \n                lr.set('coitem_listprice', res.item_price);                \n                lr.set('coitem_price', res.item_price);                                \n                lr.set('coitem_custprice', res.item_price);                \n                return;\n            }\n        }\n        \n        \n        \n        var nr = _this.grid.ds.reader.newRow({\n            coitem_linenumber : last,\n            coitem_itemsite_id : res.item_itemsite_id_itemsite_id,\n            item_number : res.item_number,\n            item_descrip1 : res.item_descrip1,\n            coitem_qtyord : 0,\n            coitem_cohead_id : _this.form.findField('cohead_id').getValue(),\n            coitem_qtyshipped : 0,\n            coitem_listprice : res.item_price,\n            coitem_price : res.item_price,\n            coitem_custprice : res.item_price,\n            avail_qty : 0,\n            coitem_location_src : lastor('cohead_location_src',false, 'coitem_location_src'),\n            coitem_location_src_location_name : lastor('cohead_location_src',true, 'coitem_location_src_location_name'),\n            coitem_shipto_id    :  lastor('cohead_shipto_id',false, 'coitem_shipto_id'),\n            coitem_shipto_id_shipto_name  : lastor('cohead_shipto_id_shipto_name', false, 'coitem_shipto_id_shipto_name')\n                    \n        });\n        _this.grid.ds.insert(_this.grid.ds.getCount(), nr); \n\n   }); \n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Find Products",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n    // work out last \n    new Pman.Request({\n        url : baseURL + '/Roo/coitem',\n        mask : 'Loading Data',\n        method: 'GET',\n        params : {\n\n            _hk_xfer :_this.form.findField('cohead_id').getValue()\n        },\n        success : function() {\n            _this.grid.ds.load({});\n        }\n    \n    });\n}\n",
+                                                "render": "function (_self)\n{\n    _this.xferAll  = _self;\n}"
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "hidden": true,
+                                            "text": "Xfer all stock to HK",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n   var c    = _this.grid.getSelectionModel().getSelectedCell();\n   if (!c) {\n        Roo.MessageBox.alert(\"Error\", \"Select item to show history (you can also double click on the #avail number) \");\n        return;\n   }\n   \n    var rec = _this.grid.ds.getAt(c[0]);\n\n  Pman.Dialog.XtupleInvHistory.show({\n        itemsite_item_id_item_number   : rec.data.item_number,\n       // itemsite_item_id_item_descript1 : rec.data.item_descrip1,\n        location_name : rec.data.coitem_location_src_location_name,\n        location_descrip : rec.data.coitem_location_src_location_descrip,\n        \n        \n        invhist_transdate : _this.form.findField('cohead_targetdate').getValue() \n    }); \n    \n   \n}"
+                                            },
+                                            "text": "Show Inventory History",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Separator"
+                                        },
+                                        {
+                                            "text": "Apply % Discount of : ",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "render": "function (_self)\n{\n    _this._applyDiscount = _self;\n}"
+                                            },
+                                            "width": 40,
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    var val =  parseFloat(_this._applyDiscount.getValue());\n    \n    var factor = (100.0 - val)/100.0;\n    \n    _this.grid.ds.each(function(rec) {\n        if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {\n            return;\n        }\n    \n        rec.set('coitem_price', rec.data.coitem_custprice * factor);\n        rec.set('coitem_linedisc', val);\n        rec.set('coitem_subtotal', rec.data.coitem_price  & rec.data.ordqty);\n        rec.commit();\n    \n    });\n    \n    \n}"
+                                            },
+                                            "text": "Apply To All",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n\n    if (!(1* _this.form.findField('cohead_id').getValue())) {\n        Roo.MessageBox.alert(\"Error\", \"save the order first\");\n    }\n    \n\n   Pman.Dialog.Image.show(\n       {\n            timeout : 60000,\n            _url : baseURL+'/Xtuple/Import/SalesOrder',\n            onid : _this.form.findField('cohead_id').getValue()\n        \n       },\n       function (data) {\n\n            Roo.MessageBox.alert(\"Notice\", \"Uploaded\");\n            _this.grid.footer.onClick('first');\n\n       }\n   );\n}"
+                                            },
+                                            "text": "Import",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "xtype": "Fill",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     _this.grid.stopEditing();\n    // check that no shipments or invoices are done..\n    var rc = _this.grid.getSelectionModel().getSelectedCell();\n    \n    var rec = _this.grid.ds.getAt(rc[0]);\n    \n    if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {\n        Roo.MessageBox.alert(\"Error\", \"That item has been shipped or invoices - void the shipments/invoices first\");\n        return;\n    }\n   if (rec.data.coitem_subnumber*1  > 0) {\n        Roo.MessageBox.alert(\"Error\", \"Delete the kit item that that belongs to.\");\n        return;\n    }\n    if (!rec.data.coitem_id) {\n        _this.grid.ds.remove(rec);\n        return;\n    }\n    function remove()\n    {\n    \n        new  Pman.Request({\n            url : baseURL + '/Roo/coitem',\n            method : 'POST',\n            params : {\n                _delete : rec.data.coitem_id\n            \n            },\n            success : function() {\n                if (rec.data.item_type == 'K') {\n                    _this.grid.ds.load({});\n                    return;\n                }\n                _this.grid.ds.remove(rec);\n            }\n        \n        });\n    }\n    if (rec.data_qtyord * 1 < 1) {\n        remove();\n    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to delete that line?\", function(r)\n    {\n        if (r != 'yes') {\n            return;\n        }\n        remove();\n    \n    });\n\n    \n    \n}\n        "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Delete",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     _this.grid.stopEditing();\n    // check that no shipments or invoices are done..\n    var ids = [];\n    _this.grid.ds.each(function(rec) {\n    \n\n    \n        if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {\n            //Roo.MessageBox.alert(\"Error\", \"That item has been shipped or invoices - void the shipments/invoices first\");\n            return;\n        }\n        if (rec.data.item_type == 'K') {\n            return;\n        }\n\n       if (rec.data.coitem_subnumber*1  > 0) {\n            //Roo.MessageBox.alert(\"Error\", \"Delete the kit item that that belongs to.\");\n            return;\n        }\n        if (!rec.data.coitem_id) {\n            _this.grid.ds.remove(rec);\n            return;\n        }\n        ids.push(rec.data.coitem_id);\n    });\n    function remove()\n    {\n    \n        new  Pman.Request({\n            url : baseURL + '/Roo/coitem',\n            method : 'POST',\n            params : {\n                _delete : ids.join(',')\n            \n            },\n            success : function() {\n\n                _this.grid.footer.onClick('first');\n            }\n        \n        });\n    }\n//    if (rec.data_qtyord * 1 < 1) {\n//        remove();\n//    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to delete everything?\", function(r)\n    {\n        if (r != 'yes') {\n            return;\n        }\n        remove();\n    \n    });\n\n    \n    \n}\n        "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Delete All",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"}",
+                                    "dataIndex": "coitem_linenumber",
+                                    "header": "Item#",
+                                    "width": 40,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n\n    if (r.data.coitem_subnumber * 1 > 0) {\n         return String.format('{0}.{1}', v,r.data.coitem_subnumber);\n     }\n     return String.format('{0}', v);\n  }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item Code",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n  // set _this.data values ..\n  var ar = _this.grid.activeEditor.record;\n//  Roo.log('beforeselect');\n  \n  \n  (function() { \n     //  Roo.log('beforeselect-cb');\n      ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);\n      ar.set('coitem_listprice', record.data.item_listprice);\n      ar.set('coitem_price', record.data.item_price);\n      ar.set('coitem_custprice', record.data.item_price);\n      ar.set('coitem_itemsite_id', record.data.itemsite_id);\n      ar.set('item_number', record.data.itemsite_item_id_item_number);\n     ar.set('item_type', record.data.itemsite_item_id_item_type);\n      ar.set('avail_qty', 0);\n      ar.commit();\n  }).defer(100);\n  \n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "itemsite_item_id_item_number",
+                                                    "editable": true,
+                                                    "emptyText": "Select item",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "itemsite_item_id_item_number",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "item_number",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select item",
+                                                    "queryParam": "query[number]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> ${item_price:toFixed(2)}- {itemsite_item_id_item_descrip1} </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": false,
+                                                    "valueField": "item_number",
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.customer_id = _this.form.findField('cohead_cust_id').getValue();\n    o.params['query[cohead_id]'] = _this.form.findField('cohead_id').getValue();\n    //o.params.shipto_cust_id = _this.data.cohead_cust_id;\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'item_number' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "shipto_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"item_id\",\"type\":\"int\"},\"item_number\"]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "coitem_location_src",
+                                    "header": "From",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    return String.format('{0}', r.data.coitem_location_src_location_name); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "editor",
+                                            "xtype": "GridEditor",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeselect": "function (combo, record, index)\n{\n  // set _this.data values ..\n  var ar = _this.grid.activeEditor.record;\n  \n  \n  \n  //Roo.log('beforeselect');\n \n /*\n  (function() { \n     //  Roo.log('beforeselect-cb');\n      ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);\n      ar.set('coitem_price', record.data.item_listprice);\n      ar.set('coitem_custprice', record.data.item_price);\n       ar.set('coitem_itemsite_id', record.data.itemsite_id);\n      ar.set('item_number', record.data.itemsite_item_id_item_number);\n\n      ar.commit();\n  }).defer(100);\n  */\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "alwaysQuery": true,
+                                                    "displayField": "location_name",
+                                                    "editable": true,
+                                                    "emptyText": "Select location",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "coitem_location_src",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "coitem_location_src_location_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select item",
+                                                    "queryParam": "query[location_name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b> {location_name}</b> {location_descrip}</div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": false,
+                                                    "valueField": "location_id",
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n    var row = _this.grid.activeEditor.record;\n    \n    o.params['query[item_itemsite_id]'] = row.data.coitem_itemsite_id;\n    // need to know the date to calc the est. delivery time..\n    //o.params['query[avail_when]'] = _this.form.findField('cohead_targetdate').getValue().format('Y-m-d');\n    //o.params.location_netable = 1;\n    o.params['query[cohead_id]'] = _this.form.findField('cohead_id').getValue(); \n    \n     o.params.location_restrict = 0;\n    o.params._notinternalcompany = 1;\n    \n  //  _this.grid;\n\n//    o.params.itemsite_id = _this.form.findField('cohead_cust_id').getValue();\n    //o.params.shipto_cust_id = _this.data.cohead_cust_id;\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "shipto_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "coitem_shipto_id",
+                                    "header": "To",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    return String.format('{0}:{1}', v, r.data.coitem_shipto_id_shipto_name); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "add": "function (combo)\n{\n\n   Pman.Dialog.XtupleCustomer.show({ cust_id : _this.form.findField('cohead_cust_id').getValue() }, function(data) {\n        // refresh the data in the pulldown..\n    }); \n}",
+                                                        "beforeselect": "function (combo, record, index)\n{\n\n    var v = [];\n    for(var i = 1; i <4; i++) {\n        _this.data['cohead_shiptoaddress'+  i] = record.data['cntct_addr_id_addr_line'+i];\n    }\n    _this.form.findField('shipto_address').update();\n    \n \n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "alwaysQuery": true,
+                                                    "displayField": "shipto_name",
+                                                    "editable": false,
+                                                    "emptyText": "Select cntct",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "cohead_shipto_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "coitem_shipto_id_shipto_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select shipto",
+                                                    "queryParam": "query[shipto_name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{shipto_id}:{shipto_addr_id_addr_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": false,
+                                                    "valueField": "shipto_id",
+                                                    "width": 300,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.shipto_cust_id = _this.data.cohead_cust_id; \n    //o.params['query[with_shipinfo]'] = 1;\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'shipto_name' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/shiptoinfo.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "shipto_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"cntct_id\",\"type\":\"int\"},\"cntct_name\"]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Item Description",
+                                    "width": "150.00",
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    if (r.data.coitem_memo && r.data.coitem_memo.length) {\n        return String.format('{0}', r.data.coitem_memo);\n        if (r.data.coitem_memo != v) {\n            r.set('item_descrip1', r.data.coitem_memo);\n        }\n        \n    }\n    if (v && v.length > 49) {\n        return String.format('<span style=\"color:orange\" qtip=\"line may be too long to print\">{0}</span>', v);\n    }\n    \n    return String.format('{0}', v); \n    \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"}",
+                                    "align": "right",
+                                    "dataIndex": "coitem_status",
+                                    "header": "Status",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_qtyord",
+                                    "header": "Qty",
+                                    "width": 40,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    var v = parseInt(v);\n    //var aq = parseInt(r.data.avail_qty);\n    //aq = isNaN(aq) ? 0 : aq;\n   \n    var rate = _this.form.findField('taxzone_rate').getValue();\n    r.data.coitem_subtotal =  v * r.data.coitem_price;\n    r.data.coitem_subtotal_tax = v * r.data.coitem_price * ( 1 + rate * 1);\n    return String.format('{0}', v); \n    \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "editor",
+                                            "xtype": "GridEditor",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "allowDecimals": false,
+                                                    "decimalPrecision": 0,
+                                                    "minValue": 1,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_price",
+                                    "header": "Sell @",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    var rate = _this.form.findField('taxzone_rate').getValue();\n    r.data.coitem_subtotal = v * r.data.coitem_qtyord;\n    r.data.coitem_subtotal_tax = v * ( 1 + rate * 1 ) * r.data.coitem_qtyord;\n    r.data.coitem_price_tax = v * ( 1 + rate * 1 );\n    if (parseInt(v) < 1) {\n        return String.format('<b style=\"color:red;\">{0}</b>', Roo.util.Format.number(v,3)); \n    }\n    \n    \n    //r.set('coitem_subtotal', v * r.data.coitem_qtyord);\n    \n    return  String.format('{0}', Roo.util.Format.number(v,3)); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 3,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_price_tax",
+                                    "header": "Sell @w/GST",
+                                    "hidden": true,
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    if (parseInt(v) < 1) {\n        return String.format('<b style=\"color:red;\">{0}</b>', Roo.util.Format.number(v,3)); \n    }\n    \n    return  String.format('{0}', Roo.util.Format.number(v,3)); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 3,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_linedisc",
+                                    "header": "Disc%",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    // coitem_custprice = coitem_price * ((100 - coitem_disc)/ 100) \n    \n    //                      12 * (( 100 - 0) / 100)\n    // coitem_custprice / coitem_price = ((100 - coitem_disc)/ 100) \n    // 100 - ((coitem_custprice / coitem_price) * 100)  = coitem_disc\n    //                             100 -  97 =        100 -3 \n\n   // r.data.coitem_linedisc = 100 - (\n    //           (parseFloat(r.data.coitem_custprice) /\n     //               parseFloat(r.data.coitem_price)\n       //        ) * 100.00);\n    var fl = parseFloat(r.data.coitem_linedisc);\n    if ( isNaN(fl) || fl == 0.0 || r.data.coitem_price > r.data.coitem_custprice)  {\n        return '';\n    }\n    return  String.format('<span style=\"color:green\">{0}%</span>', Roo.util.Format.number( r.data.coitem_linedisc,2)); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 2,
+                                                    "maxValue": 100,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_custprice",
+                                    "header": "List Price",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    var rate = _this.form.findField('taxzone_rate').getValue();\n    r.data.coitem_custprice_tax = v * ( 1 + rate * 1 );\n    \n    var tip = 'No WRP available';\n    if ((r.data.coitem_wrpprice * 1) > 0) {\n        tip = \"WRP : \" + Roo.util.Format.number(r.data.coitem_wrpprice,3);\n    }\n    // less than zero, show as red..\n    if (parseFloat(v) < 1) {\n        return String.format('<b qtip=\"{1}\" style=\"color:red;\">{0}</b>', \n            Roo.util.Format.number(v,3), tip); \n    }\n    if (r.data.customer_price_each != v) {\n          return String.format('<b qtip=\"{1}\" style=\"color:pink;\">{0}</b>', \n            Roo.util.Format.number(v,3), \n            \"List Price = \" +  Roo.util.Format.number(r.data.customer_price_each,3)\n        ); \n    }\n    \n    \n    \n    //r.data.coitem_subtotal = v * r.data.coitem_qtyord;\n    \n    //r.set('coitem_subtotal', v * r.data.coitem_qtyord);\n    \n    return  String.format('<span qtip=\"{1}\">{0}</span>', Roo.util.Format.number(v,3), tip); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 3,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_custprice_tax",
+                                    "header": "List Price w/GST",
+                                    "hidden": true,
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    var rate = _this.form.findField('taxzone_rate').getValue();\n    var tip = 'No WRP available';\n    if ((r.data.coitem_wrpprice * 1) > 0) {\n        tip = \"WRP : \" + Roo.util.Format.number(r.data.coitem_wrpprice,3);\n    }\n    \n    if (parseFloat(v) < 1) {\n        return String.format('<b qtip=\"{1}\" style=\"color:red;\">{0}</b>', \n            Roo.util.Format.number(v,3), tip); \n    }\n    if (r.data.customer_price_each != v) {\n          return String.format('<b qtip=\"{1}\" style=\"color:pink;\">{0}</b>', \n            Roo.util.Format.number(v,3), \n            \"List Price = \" +  Roo.util.Format.number(r.data.customer_price_each * ( 1 + rate * 1 ),3)\n        ); \n    }\n    \n    return  String.format('<span qtip=\"{1}\">{0}</span>', Roo.util.Format.number(v,3), tip); \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "focus": "function (_self)\n{\n    if (this.value == 0.0) {\n        this.el.dom.value = '';\n    }\n}"
+                                                    },
+                                                    "*prop": "field",
+                                                    "decimalPrecision": 3,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_subtotal",
+                                    "header": "SubTotal",
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {\n\n    if (parseInt(v) < 1) {\n        return String.format('<b style=\"color:red;\">{0}</b>', Roo.util.Format.number(v,2)); \n    }\n\n    \n\n return Roo.util.Format.number( v, 2);\n  }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_subtotal_tax",
+                                    "header": "SubTotal w/GST",
+                                    "hidden": true,
+                                    "width": 70,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n   \n    if (parseInt(v) < 1) {\n        return String.format('<b style=\"color:red;\">{0}</b>', Roo.util.Format.number(v,2)); \n    }\n    \n    return  String.format('{0}', Roo.util.Format.number(v,2)); \n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"}",
+                                    "align": "right",
+                                    "dataIndex": "coitem_unitcost_in_order_cur",
+                                    "header": "Unit Cost",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "coitem_taxtype_id",
+                                    "header": "Taxed",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0}', r.data.coitem_taxtype_id_taxtype_name); }",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.grid",
+                                            "xtype": "GridEditor",
+                                            "*prop": "editor",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowBlank": false,
+                                                    "displayField": "taxtype_name",
+                                                    "editable": false,
+                                                    "emptyText": "Select Tax Type",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "coitem_taxtype_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "coitem_taxtype_id_taxtype_name",
+                                                    "pageSize": 20,
+                                                    "qtip": "Select taxtype",
+                                                    "queryParam": "query[taxtype_id]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{taxtype_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "taxtype_id",
+                                                    "width": 40,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    \n    \n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'taxtype_name' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/taxtype.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "taxtype_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"taxtype_id\",\"type\":\"int\"},\"taxtype_name\"]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "avail_qty",
+                                    "header": "#avail",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    var oq  = parseInt(r.data.coitem_qtyord);\n    var aq = parseInt(r.data.avail_qty);\n    var sq = parseInt(r.data.coitem_qtyshipped);\n    aq = isNaN(aq) ? 0 : aq;\n    oq = isNaN(oq) ? 0 : oq;\n    sq = isNaN(sq) ? 0 : sq;\n    \n    var unshipped = oq - sq;\n    \n    if ( aq < 0 || (unshipped > 0  &&  aq < unshipped))  {\n       return String.format('<b style=\"color:red;\">{0}</b>', parseInt(aq));\n    }\n     \n    return String.format('{0}', aq); \n    \n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}",
+                                    "align": "right",
+                                    "dataIndex": "shipitem_shipped",
+                                    "header": "#reserved",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n\n    \n    var vv = parseInt(v);\n    vv = isNaN(vv) ? 0 : vv;\n    \n    var ov = parseInt(r.data.coitem_qtyord);\n    ov = isNaN(ov) ? 0 : ov;\n    \n    var qs = parseInt(r.data.coitem_qtyshipped);\n    qs = isNaN(qs) ? 0 : qs;\n    \n    \n    \n    if (vv < ov) {\n        // not enough reserved yet.\n        return String.format('<b style=\"background-color:red;color:yellow\">{0}</b>', vv - qs);\n    }\n    \n    return String.format('{0}', vv -  qs); \n    \n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}",
+                                    "align": "right",
+                                    "dataIndex": "coitem_qtyshipped",
+                                    "header": "#shipped",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    var vv = parseInt(v);\n    vv = isNaN(vv) ? 0 : vv;\n    \n    var ov = parseInt(r.data.coitem_qtyord);\n    ov = isNaN(ov) ? 0 : ov;\n    \n\n    if (vv != ov) {\n        // not enought shipped.\n        // or too many shipped.\n        return String.format('<b style=\"background-color:red;color:yellow\">{0}</b>',  vv);\n    }\n\n    \n    \n    return String.format('{0}', vv); \n    \n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "align": "right",
+                                    "dataIndex": "cobill_billed",
+                                    "header": "#invoiced",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    var vv = parseInt(v);\n    vv = isNaN(vv) ? 0 : vv;\n    \n    var ov = parseInt(r.data.coitem_qtyord);\n    ov = isNaN(ov) ? 0 : ov;\n    \n\n    if (vv !=ov) {\n            return String.format('<b style=\"background-color:red;color:yellow\">{0}</b>', vv); \n    }\n    return String.format('{0}', vv); \n    \n}",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "activate": "function (_self)\n{\n    _this.shipinvtab = _self;\n}"
+                    },
+                    "region": "center",
+                    "title": "Shipments / Invoices",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "*prop": "center",
+                                    "titlebar": true,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "north",
+                                    "height": 250,
+                                    "title": "Reserve Stock / Shipments",
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.shippanel = this;\n    if (_this.shipgrid) {\n        _this.shipgrid.ds.load({});\n    }\n}"
+                                    },
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipvia\",\"columnshort\":\"shiphead_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_tracknum\",\"columnshort\":\"shiphead_tracknum\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_shipvia\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "north",
+                                    "tableName": "shiphead",
+                                    "title": "shiphead",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.shipgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.shippanel.active) {\n       this.ds.load({});\n    }\n}",
+                                                "rowdblclick": "function (_self, rowIndex, e)\n{\n    var rec = this.ds.getAt(rowIndex);\n    if (!rec.json.shiphead_shipdate.length) {\n         Roo.MessageBox.alert(\"Error\", \"You can not edit voided shipments, create a new one, and use the restore feature\");\n         return;\n     }\n\n   Pman.Dialog.XtupleShipment.show({\n        shiphead_id : rec.data.shiphead_id\n\n    }, function() {\n        _self.ds.load({});\n    \n    });\n   \n}\n"
+                                            },
+                                            "*prop": "grid",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipvia\",\"columnshort\":\"shiphead_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_tracknum\",\"columnshort\":\"shiphead_tracknum\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_shipvia\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "autoExpandColumn": "shiphead_shipvia",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, options)\n{\n     options.params = options.params || {};\n     options.params.shiphead_order_id = _this.form.findField('cohead_id').getValue() * 1;\n    if (options.params.shiphead_order_id < 1) {\n        return false;\n    }\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipvia\",\"columnshort\":\"shiphead_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_tracknum\",\"columnshort\":\"shiphead_tracknum\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_shipvia\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'shiphead_shipvia', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|url": "baseURL + '/Roo/shiphead.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipvia\",\"columnshort\":\"shiphead_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_tracknum\",\"columnshort\":\"shiphead_tracknum\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_shipvia\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'shiphead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'shiphead_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'shiphead_shipdate',\n        'type': 'date'\n    },\n    {\n        'name': 'shiphead_sfstatus'\n    },\n    {\n        'name': 'shiphead_tracknum',\n        'type': 'string'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "toolbar",
+                                                    "xtype": "Toolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n     var sel  = _this.shipgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a shipment\");\n        return;\n    }\n    if (sel.data.shiphead_shipped) {\n        Roo.MessageBox.alert(\"Error\", \"Shipment is already confirmed\");\n        return;\n    }\n    \n    \n    // check current status of shipment..\n    \n        \n    new Pman.Request({ \n           mask : 'Sending',\n        url : baseURL + '/Roo/shiphead',\n        method : 'POST',\n        timeout : 90000,\n        params : {\n            shiphead_id : sel.data.shiphead_id,\n            _confirm : 1\n        },\n        success : function() {\n            _this.shipgrid.ds.load({});\n        }\n    });\n         \n     \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Confirm Shipment",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/lock.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n     var sel  = _this.shipgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a shipment\");\n        return;\n    }\n\n    \n    // check current status of shipment..\n    \n        \n   new Pman.Download({\n        url : baseURL + '/Roo/shiphead',\n        method : 'GET',\n        params : {\n           _download :sel.data.shiphead_id\n             \n        }\n    });\n         \n     \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Download (as xls)",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/save.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function ()\n{\n    var sel  = _this.shipgrid.getSelectionModel().getSelected();\r\n    if (!sel) {\r\n        Roo.MessageBox.alert(\"Error\", \"Select a shipment\");\r\n        return;\r\n    }\r\n    // check current status of shipment..\n \n        new Pman.Download({\n            url : baseURL + '/Xtuple/Print',\n            method : 'GET',\n            params : {\n                template : 'picking-slip',\n                param : \"shiphead_id:integer='\" + sel.data.shiphead_id + \"'\",\n                filename : 'picking-slip-' + sel.data.shiphead_number\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Print Picking Slip",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function ()\n{\n    var sel  = _this.shipgrid.getSelectionModel().getSelected();\r\n    if (!sel) {\r\n        Roo.MessageBox.alert(\"Error\", \"Select a shipment\");\r\n        return;\r\n    }\r\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Xtuple/Print',\n            method : 'GET',\n            params : {\n                template : 'delivery-note-',\n                param : \"shiphead_id:integer='\" + sel.data.shiphead_id + \"'\",\n                filename : 'delivery-note-' + sel.data.shiphead_number\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Print Delivery Note",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "xtype": "Fill",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{   \n    if (!_this.form.findField('cohead_id').getValue()) {\n        Roo.MessageBox.alert(\"Error\", \"Save Order first\");\n        return;\n    }\n    var rv = _this.form.getFieldValues();\n    \n    Pman.Dialog.XtupleShipmentNew.show({\n            shiphead_order_id : rv.cohead_id,\n            shiphead_shipdate :  _this.form.findField('cohead_targetdate').getValue().format('Y-m-d')\n        },\n        function() { \n             _this.shipgrid.ds.load({});\n        }\n    );\n}",
+                                                                "render": "function (_self)\n{\n  _this.addShipmentBtn = _self;\n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    var sel  = _this.shipgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a shipment\");\n        return;\n    }\n    // check current status of shipment..\n    \n    var msg = sel.data.shiphead_shipped ? \n        \"Are you sure you want to un-confirm that shipment? - It will remove items from unposted invoices\" : \n        \"Are you sure you want to void that shipment?\";\n    \n    Roo.MessageBox.confirm(\"Are you sure\", msg,\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            new Pman.Request({\n                mask : 'Sending',\n                 timeout : 90000,\n                url : baseURL + '/Roo/shiphead',\n                method : 'POST',\n                \n                params : {\n                    shiphead_id : sel.data.shiphead_id,\n                    _void : 1\n                },\n                success : function() {\n                    _this.shipgrid.ds.load({});\n                }\n            })\n            \n        }\n    );\n            \n            \n    \n    \n    \n}\n        "
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Void / Unconfirm",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "dataIndex": "shiphead_number",
+                                                    "header": "number",
+                                                    "width": 80,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) {\n    if (r.json.shiphead_shipdate.length) {\n         return String.format('{0}', v); \n     }\n     return String.format('<s>{0}</s>', v); \n }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "shiphead_location_id_location_name",
+                                                    "header": "From Location",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "shiphead_shipto_id_shipto_name",
+                                                    "header": "Ship to",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "xtype": "ColumnModel",
+                                                    ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "header": "shipdate",
+                                                    "width": 75,
+                                                    "dataIndex": "shiphead_shipdate",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                                    "|xns": "Roo.grid",
+                                                    "*prop": "colModel[]"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "dataIndex": "shiphead_sfstatus",
+                                                    "header": "Status",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n\n\n  \n    if (r.json.shiphead_shipdate.length) {\n    \n        if (r.json.shiphead_shipped) {\n            return \"Confirmed\";\n        }\n    \n         return '<span style=\"color:red\">Draft</span>';\n    }\n     \n    return 'VOID';\n   \n\n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "xtype": "ColumnModel",
+                                                    ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_shipvia\",\"columnshort\":\"shiphead_shipvia\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}",
+                                                    "header": "shipvia",
+                                                    "width": 200,
+                                                    "dataIndex": "shiphead_shipvia",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid",
+                                                    "*prop": "colModel[]"
+                                                },
+                                                {
+                                                    "xtype": "ColumnModel",
+                                                    ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_tracknum\",\"columnshort\":\"shiphead_tracknum\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "header": "tracknum",
+                                                    "width": 200,
+                                                    "dataIndex": "shiphead_tracknum",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid",
+                                                    "*prop": "colModel[]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.invpanel = this;\n    if (_this.invgrid) {\n        _this.invgrid.ds.load({});\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "cobmisc",
+                                    "title": "Invoices",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.invgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.invpanel.active) {\n       this.ds.load({});\n    }\n}",
+                                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n\n    var ri = this.ds.getAt(rowIndex);\n    if ( ri.data.cobmisc_id < 0) { // skip summary row..\n        return;\n    }\n    var rv = _this.form.getFieldValues();\n   Pman.Dialog.XtupleInvoice.show({\n        cobmisc_id : ri.data.cobmisc_id,\n        // below parms for add credit memo\n        cmdata : {\n            cm_cust_id : rv.cohead_cust_id,\n            cm_cust_id_cust_name : rv.cohead_cust_id_cust_name,\n            cm_curr_id : rv.cohead_curr_id,\n            cm_curr_id_curr_name : rv.cohead_curr_id_curr_name,\n            cm_terms_id : rv.cohead_terms_id,\n            cm_terms_id_terms_descrip : rv.cohead_terms_id_terms_descrip,\n            cm_salesrep_id : rv.cohead_salesrep_id,\n            cm_salesrep_id_salesrep_name : rv.cohead_salesrep_id_salesrep_name,\n            cm_docdate : new Date(),\n            cm_taxzone_id : rv.cohead_taxzone_id,\n            cm_taxzone_id_taxzone_descrip : rv.cohead_taxzone_id_taxzone_descrip,\n            cm_billto_cntct_id : rv.cohead_billto_cntct_id,\n            cm_billto_cntct_id_cntct_name : rv.cohead_billto_cntct_id_cntct_name,\n            cm_location_src : rv.cohead_location_src,\n            cm_location_src_location_name : rv.cohead_location_src_location_name,\n            cm_billto_address : rv.billto_address\n        }\n    },\n        function() { \n         _this.invgrid.ds.load({});\n    });\n   \n}\n\n"
+                                            },
+                                            "*prop": "grid",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"invchead\",\"column\":\"invchead_invcnumber\",\"columnshort\":\"invchead_invcnumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"invchead_invcnumber\"],\"table\":\"invchead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "autoExpandColumn": "invchead_invcnumber",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, options)\n{\n\n    options.params = options.params || {};\n    options.params.cobmisc_cohead_id = _this.form.findField('cohead_id').getValue() * 1;\n    if (options.params.cobmisc_cohead_id < 1) {\n        return false;\n    }\n    \n    options.params._with_other_payment = 1;\n    //options.params['query[invchead_ordernumber]']  = _this.form.findField('cohead_number').getValue()\n    \n}",
+                                                        "load": "function (_self, records, options)\n{\n    var total = 0;\n    var done = 0;\n    var totalic = 0.0;\n    var totalfreight = 0.0;    \n    var totalmisc = 0.0;        \n    var totaltax = 0.0;        \n   \n    Roo.each(records, function(r)\n    {\n        if(r.data.cobmisc_id > 1){\n            done += parseInt(r.data.cobmisc_qty);\n            totalic += parseFloat(r.data.cobmisc_itemcost).toFixed(2)*1;        \n            totalmisc += parseFloat(r.data.cobmisc_misc).toFixed(2)*1;        \n            totalfreight += parseFloat(r.data.cobmisc_freight).toFixed(2)*1;                \n            totaltax += parseFloat(r.data.cobmisc_tax).toFixed(2)*1;                \n            total = parseInt(r.data.cobmisc_total_qty);\n        }\n       \n    });\n    \n    _this.shipinvtab.layout.getRegion('center').getPanel(0).setTitle(\n        (total == done) ?\n             \"Invoices (Complete)\" : \n            (\"Invoices prepared for \" +    done + '/' + total)\n    );\n\n    \n    var frtotal = (parseFloat(_this.form.findField('cohead_freight').getValue())  - totalfreight).toFixed(2);\n    var misctotal = (parseFloat(_this.form.findField('cohead_misc').getValue()) - totalmisc).toFixed(2);\n    var ictotal =  (parseFloat(_this.form.findField('cohead_subtotal').getValue()) - totalic).toFixed(2);\n    var taxtotal =  (parseFloat(_this.form.findField('cohead_tax').getValue())  - totaltax).toFixed(2);\n    var remtotal = frtotal*1 + misctotal*1 + ictotal*1 + taxtotal*1;\n    \n    var nr = this.reader.newRow({\n        cobmisc_id : -1,\n        cobmisc_invchead_id_invchead_invcnumber : \"Total Remaining\",\n        cobmisc_qty : total - done,\n        cobmisc_freight :frtotal,\n        cobmisc_misc : misctotal,        \n        cobmisc_itemcost  : ictotal,             \n        cobmisc_tax : taxtotal,\n        cobmisc_total : remtotal\n\n        \n    });\n    // do we need to add it somehow??\n    _this.invgrid.ds.add(nr);\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'invchead_invcnumber', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/cobmisc.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            ".builderCfg": "{\"cols\":[{\"table\":\"invchead\",\"column\":\"invchead_invcnumber\",\"columnshort\":\"invchead_invcnumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"invchead_invcnumber\"],\"table\":\"invchead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\n    {\n        'name': 'invchead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invchead_invcdate',\n        'type': 'date'\n    }\n]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "toolbar",
+                                                    "xtype": "Toolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function ()\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    // check current status of shipment..\n    \n    Roo.MessageBox.confirm(\"Are you sure\", \"Are you sure you want to Post that invoice?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            new Pman.Request({\n               mask : 'Sending',\n                url : baseURL + '/Roo/cobmisc',\n                method : 'POST',\n                params : {\n                    cobmisc_id : sel.data.cobmisc_id,\n                    _post : 1\n                },\n                success : function() {\n                    _this.invgrid.ds.load({});\n                }\n            })\n            \n        }\n    );\n            \n            \n   \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Post Invoice",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/lock.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Print",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                                            "|xns": "Roo.Toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Menu",
+                                                                    "*prop": "menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function ()\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n                _print : 1\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                                                            },
+                                                                            "text": "Print Standard Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n                _print : 'cn'\n                \n            },\n            success : function() {\n\n            }\n        })\n            \n          \n} "
+                                                                            },
+                                                                            "text": "Print Chinese Invoice With GST in line item",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!(baseURL.match(/(hk\\.php|cn\\.php)$/))",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n                _print : 'cn-gst'\n                \n            },\n            success : function() {\n\n            }\n        })\n            \n          \n} "
+                                                                            },
+                                                                            "text": "Print Chinese Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!(baseURL.match(/(hk\\.php|cn\\.php)$/))",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n                _print : 'au-gst'\n                \n            },\n            success : function() {\n\n            }\n        })\n            \n          \n} "
+                                                                            },
+                                                                            "text": "Print Aus - GST included Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!(baseURL.match(/au\\.php$/))",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n  var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n\n                _print : 'au-net',\n               ts: Math.random()\n            }\n        })\n\n\n}"
+                                                                            },
+                                                                            "text": "Print Bambini Pronto Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!(baseURL.match(/au\\.php$/))",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if (!sel.data.cobmisc_invchead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Invoice has not been posted\");\n        return;\n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/invchead',\n            method : 'GET',\n            params : {\n                invchead_id : sel.data.cobmisc_invchead_id,\n                _print : 'au-proforma'\n                \n            },\n            success : function() {\n\n            }\n        })\n            \n          \n} "
+                                                                            },
+                                                                            "text": "Print Bambini Pro Forma Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!(baseURL.match(/au\\.php$/))",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    \n    Pman.Dialog.XtupleDiscountOfInvoice.show({invchead_id : sel.data.cobmisc_invchead_id}, function(){\n\n    });\n}"
+                                                                            },
+                                                                            "text": "Print Shipping / Commercial Invoice",
+                                                                            "xtype": "Item",
+                                                                            "|hidden": "!( baseURL.match(/au\\.php$/)) ",
+                                                                            "|xns": "Roo.menu"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Tools",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                            "|xns": "Roo.Toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Menu",
+                                                                    "*prop": "menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function(_self,e)\n    {\n    \n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel || sel.data.cobmisc_id < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    if(!sel.data.cobmisc_posted){\n        Roo.MessageBox.alert(\"Error\", \"This invoice has not been posted!\");\n        return;\n    }\n    if(sel.data.cobmisc_outstanding == 0){\n        Roo.MessageBox.alert(\"Error\", \"There is no any outstanding of this invoice!\");\n        return;\n    }\n    \n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if(!cust_id){\n        return;\n    }\n    var data = {\n        cashrcpt_amount : sel.data.cobmisc_outstanding,\n        cashrcpt_cust_id : cust_id,\n        cashrcpt_aropen_id : sel.data.cobmisc_aropen_id_aropen_id,\n        cashrcpt_distdate : new Date(),\n        cashrcpt_fundstype : 'C',\n        cashrcpt_curr_id : sel.data.cobmisc_curr_id_curr_id,\n        cashrcpt_curr_id_curr_name : sel.data.cobmisc_curr_id_curr_name,\n        cashrcpt_usecustdeposit : true,\n        cashrcpt_docdate : new Date(),\n        cashrcpt_salescat_id : -1,\n        cashrcpt_applydate : new Date(),\n        cashrcpt_discount : 0\n    };\n    Pman.Dialog.XtupleReceivePayment.show( data , function() {\n        _this.invgrid.ds.load({});\n    }); \n}\n"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Receive Payment",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function(_self,e)\n{\n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel || sel.data.cobmisc_cobapply_aropen_id < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a credit memo\");\n        return;\n    }\n    if(!sel.data.cobmisc_posted){\n        Roo.MessageBox.alert(\"Error\", \"The invoice that credit memo has been applied to has been not posted\");\n        return;\n    }\n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if(!cust_id){\n        return;\n    }\n    \n    if(!sel.data.cobmisc_outstanding || sel.data.cobmisc_outstanding == 0){\n        Roo.MessageBox.alert(\"Error\", \"The amount of this credit memo is 0!\");\n        return;\n    }\n    \n    var d = _this.form.getFieldValues();\n    \n    var data = {\n        'checkhead_recip_id' : cust_id,\n        'checkhead_recip_type' : 'C',\n        'checkhead_checkdate' : new Date(),\n        'checkhead_amount' : sel.data.cobmisc_outstanding,\n        'remaining_total' : sel.data.cobmisc_outstanding,\n        'checkhead_curr_id' : d.cohead_curr_id,\n        'checkhead_curr_id_curr_name' : d.cohead_curr_id_curr_name,\n        'checkhead_misc' : true,\n        'aropen_id' : sel.data.cobmisc_cobapply_aropen_id,\n    \t'cmhead_number' : sel.data.cobmisc_invchead_id_invchead_invcnumber,\n\t'cust_name' : d.cohead_cust_id_cust_name,\n\t'_create_and_post' : 1\n\n    };\n    \n    \n    Pman.Dialog.XtupleMiscellaneousCheck.show( data , function() {\n        _this.invgrid.ds.load({});\n   }); \n}\n"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Issue Refund",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function(_self,e)\n{\n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel || sel.data.cobmisc_cashrcpt_id * 1 < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a Receive Payment\");\n        return;\n    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Voiding receipt will mean you will have to re-enter the receipt refund - \" + \n                    \"please take note of the details so you can enter it again correctly later.\", function(r) {\n                            \n        if (r !='yes') {\n            return;\n        }\n        new Pman.Request({\n            url : baseURL + '/Roo/cashrcpt',\n            method : 'POST',\n            params : {\n                cashrcpt_id : sel.data.cobmisc_cashrcpt_id,\n                _void : 1\n            },\n            success : function() \n            {\n                _this.invgrid.ds.load({});\n            \n            }\n        });\n    \n   })\n    \n     \n}\n"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Void Receive",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function(_self,e)\n{\n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel || sel.data.cobmisc_checkhead_id * 1 < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a Miscellaneours Check\");\n        return;\n    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Voiding refund will mean you will have to re-enter the receipt refund - \" + \n                    \"please take note of the details so you can enter it again correctly later.\", function(r) {\n                            \n        if (r !='yes') {\n            return;\n        }\n        new Pman.Request({\n            url : baseURL + '/Roo/checkhead',\n            method : 'POST',\n            params : {\n                checkhead_id : sel.data.cobmisc_checkhead_id,\n                _voidPosted : 1\n            },\n            success : function() \n            {\n                _this.invgrid.ds.load({});\n            \n            }\n        });\n    \n   })\n    \n     \n}\n"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Void Refund",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function(_self,e)\n{\n    var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel || sel.data.cobmisc_cobapply_aropen_id < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a credit memo\");\n        return;\n    }\n    \n    if(sel.data.cobmisc_posted){\n        Roo.MessageBox.alert(\"Error\", \"You cann't void this credit memo, since the invoice that credit memo has been applied to has been posted\");\n        return;\n    }\n    \n    if (sel.data.cobmisc_cobapply_id < 1) {\n        Roo.MessageBox.alert(\"Error\", \"invaild credit memo\");\n        return;\n    }\n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to void this applied credit memo, \" + \n                \"it will also void all the check that belongs to this credit memo \", function(r) {\n                            \n        if (r !='yes') {\n            return;\n        }\n        new Pman.Request({\n            url : baseURL + '/Roo/cobapply',\n            method : 'POST',\n            params : {\n                _delete : sel.data.cobmisc_cobapply_id,\n                _void : 1\n            },\n            success : function() \n            {\n                _this.invgrid.ds.load({});\n            \n            }\n        });\n    \n   })\n     \n}\n"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Void Credit Memo",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "xtype": "Fill",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function ()\n{\n\n    if (!_this.form.findField('cohead_id').getValue()) {\n        Roo.MessageBox.alert(\"Error\", \"Save Order first\");\n        return;\n    }\n    \n    var rv = _this.form.getFieldValues();\n    \n   \n   Pman.Dialog.XtupleInvoice.show({\n        cobmisc_cohead_id : rv.cohead_id,\n        cobmisc_shipdate :  _this.form.findField('cohead_targetdate').getValue(),\n        cobmisc_invcdate :  _this.form.findField('cohead_targetdate').getValue(),\n        cobmisc_curr_id : rv.cohead_curr_id,\n        cobmisc_curr_id_curr_name : rv.cohead_curr_id_curr_name,\n        // below parms for add credit memo\n        cmdata : {\n            cm_cust_id : rv.cohead_cust_id,\n            cm_cust_id_cust_name : rv.cohead_cust_id_cust_name,\n            cm_curr_id : rv.cohead_curr_id,\n            cm_curr_id_curr_name : rv.cohead_curr_id_curr_name,\n            cm_terms_id : rv.cohead_terms_id,\n            cm_terms_id_terms_descrip : rv.cohead_terms_id_terms_descrip,\n            cm_salesrep_id : rv.cohead_salesrep_id,\n            cm_salesrep_id_salesrep_name : rv.cohead_salesrep_id_salesrep_name,\n            cm_docdate : new Date(),\n            cm_taxzone_id : rv.cohead_taxzone_id,\n            cm_taxzone_id_taxzone_descrip : rv.cohead_taxzone_id_taxzone_descrip,\n            cm_billto_cntct_id : rv.cohead_billto_cntct_id,\n            cm_billto_cntct_id_cntct_name : rv.cohead_billto_cntct_id_cntct_name,\n            cm_location_src : rv.cohead_location_src,\n            cm_location_src_location_name : rv.cohead_location_src_location_name,\n            cm_billto_address : rv.billto_address\n        }\n        \n    },\n        function() { \n         _this.invgrid.ds.load({});\n    });\n   \n}",
+                                                                "render": "function (_self)\n{\n  _this.addInvoiceBtn = _self;\n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function ()\n{\n\n     var sel  = _this.invgrid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    // check current status of shipment..\n    \n    var params =  {\n//        cobmisc_id : sel.data.cobmisc_id,\n        _void : 1\n    };\n    if (sel.data.cobmisc_id * 1) {\n        params.cobmisc_id = sel.data.cobmisc_id * 1 ;\n    }\n    if (sel.data.cobmisc_invchead_id_invchead_id * 1) {    \n        params.invchead_id  =  sel.data.cobmisc_invchead_id_invchead_id * 1;\n    }\n    \n    Roo.MessageBox.confirm(\"Are you sure\", \"Are you sure you want to VOID that invoice?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            new Pman.Request({\n                mask : 'Sending',\n                url : baseURL + '/Roo/cobmisc',\n                method : 'POST',\n                params :  params,\n                success : function() {\n                    _this.invgrid.ds.load({});\n                }\n            })\n            \n        }\n    );\n            \n            \n   \n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Void / Unpost",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "cobmisc_invchead_id_invchead_invcnumber",
+                                                    "header": "Invoice #",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n       if (v && \n             r.data.cobmisc_invchead_id_invchead_id * 1 && \n            !r.data.cobmisc_invchead_id_invchead_posted) {\n           return  '<span style=\"color:red\">' + \n                \"NEEDS Voiding then re-posted: \" + \n                String.format('{0}', v) +\n                '</span>'; \n       }\n\n       if(v && r.data.cobmisc_id == -2){\n            return String.format('<span style=\"margin-left: 10px;\"> - {0} (Credit Memo)</span>', v); \n       }\n       if(v && r.data.cobmisc_id == -3){\n            return String.format('<span style=\"margin-left: 20px;\"> - {0} (Miscellaneous Check)</span>', v); \n       }\n      if(v && r.data.cobmisc_id == -4){\n            return String.format('<span style=\"margin-left: 10px;\"> - {0} (Receive Payment) [ {1} ]</span>', v, r.data.cobmisc_cashrcpt_amount); \n       }\n       \n        return v ? String.format('{0}', v) : \n                '<span style=\"color:red\">' + \"Not Posted\" + '</span>'; \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    ".builderCfg": "{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "dataIndex": "cobmisc_invcdate",
+                                                    "header": "invcdate",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n        return String.format('{0}', v && r.data.cobmisc_id > 0 ? v.format('d/M/Y') : ''); \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_qty",
+                                                    "header": "Qty",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? parseInt(v) : 0); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_itemcost",
+                                                    "header": "Item Cost",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2)  : 0); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_freight",
+                                                    "header": "Shipping",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2)  : ''); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_tax",
+                                                    "header": "Tax",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n    // tax is based on the % itemcost..\n//    var ic  = r.data.cobmisc_itemcost;\n    /*\n    var ic  =r.data.cobmisc_itemcost - (1* r.data.cobmisc_itemcost_taxfree);\n    \n    var tax= _this.form.findField('cohead_tax').getValue() * 1.0;\n    var totic = _this.form.findField('cohead_subtotal').getValue() * 1.0;    \n    if (tax < 0.1) {\n        return '';\n    }\n    var taxp = tax / totic;\n    var lv = taxp * ic;\n    */\n    return String.format('{0}', (1.0*v).toFixed(2) );\n    \n    \n }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_cohead_id_cohead_pretax_discount",
+                                                    "header": "Discount (Pretax)",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2) : 0); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_misc",
+                                                    "header": "Discount (Posttax)",
+                                                    "width": 100,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{\n    var vv = v - r.data.cobmisc_cohead_id_cohead_pretax_discount;\n    \n    return String.format('{0}', vv ? (1.0*vv).toFixed(2) : 0); \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_total",
+                                                    "header": "Total ",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n/*    \n    var ic  = r.data.cobmisc_itemcost;\n    var tax= _this.form.findField('cohead_tax').getValue() * 1.0;\n    var totic = _this.form.findField('cohead_subtotal').getValue() * 1.0;    \n    var     lv = 0.0;\n    if (tax > 0.0) {\n        var taxp = tax / totic;\n        lv = taxp * ic;\n\n    }\n  */  \n  \n\n    if(v){\n        return String.format('{0}',(v * 1.0).toFixed(2) );\n    }\n    var d= r.data;\n\n    return String.format('{0}',\n       ((d.cobmisc_itemcost * 1.0) + \n       (d.cobmisc_freight * 1.0) + \n       (d.cobmisc_tax * 1.0) +\n       (d.cobmisc_misc * 1.0)  \n\n       ).toFixed(2) );\n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "cobmisc_outstanding",
+                                                    "header": "Outstanding",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{ \n    \n    return String.format('{0}', v ? (v * 1.0).toFixed(2) : 0 );\n}",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.hpanel = this;\n    if (_this.hgrid) {\n        _this.hgrid.footer.onClick('first');\n    }\n}"
+                    },
+                    ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "events",
+                    "title": "History",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.hgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.hpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                            },
+                            "*prop": "grid",
+                            ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "autoExpandColumn": "remarks",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, options)\n{\n    options.params._related_on_table = 'cohead';\n    options.params._related_on_id = _this.form.findField('cohead_id').getValue();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'event_when', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/events.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"remarks\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "id": "id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'event_when',\n        'type': 'date'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "xtype": "PagingToolbar",
+                                    "pageSize": 25,
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying events{0} - {1} of {2}",
+                                    "emptyMsg": "No events found",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"event_when\",\"columnshort\":\"event_when\",\"ctype\":\"timestamp\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "event_when",
+                                    "header": "Changed",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"action\",\"columnshort\":\"action\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "action",
+                                    "header": "action",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"ipaddr\",\"columnshort\":\"ipaddr\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "ipaddr",
+                                    "header": "IP address",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"person\",\"column\":\"person_id_name\",\"columnshort\":\"name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "person_id_name",
+                                    "header": "Who",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"events\",\"column\":\"remarks\",\"columnshort\":\"remarks\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}",
+                                    "dataIndex": "remarks",
+                                    "header": "Notes",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "region": "center",
+                    "title": "Stock Tx",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "*prop": "east",
+                                    "split": true,
+                                    "width": 500,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.txpanel = this;\n    if (_this.txgrid) {\n        _this.txgrid.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "invdetail",
+                                    "title": "invdetail",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.txgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.txpanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "item_number",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    new Pman.Request({\n        mask : 'applying',\n        url : baseURL + '/Roo/Cohead',\n        method : 'GET',\n        params : {\n            _apply_fifo : _this.form.findField('cohead_id').getValue()\n        },\n        success : function () {\n            Roo.MessageBox.alert(\"Applied\", \"Succesfully Applied\");\n        }\n    });\n}"
+                                                            },
+                                                            "text": "Run Apply Fifo on order",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    new Pman.Request({\n        mask : 'running',\n        url : baseURL + '/Roo/Cohead',\n        method : 'GET',\n        params : {\n            _run_void_fix : _this.form.findField('cohead_id').getValue()\n        },\n        success : function () {\n            Roo.MessageBox.alert(\"Applied\", \"Succesfully Run\");\n        }\n    });\n}"
+                                                            },
+                                                            "text": "Run Void flagger",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        newWindow : true,\n        mask : 'running',\n        url : baseURL + '/Roo/Invdetail',\n        method : 'GET',\n        timeout :90000,\n        params : {\n            _post : 1,\n            _reverse_all_bad : _this.form.findField('cohead_id').getValue()\n        },\n        success : function () {\n            Roo.MessageBox.alert(\"Applied\", \"Succesfully Run\");\n        }\n    });\n}"
+                                                            },
+                                                            "text": "Auto Reverse",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "selectionchange": "function (_self)\n{\n    _this.txdgrid.footer.onClick('first');;\n}"
+                                                    },
+                                                    "*prop": "sm",
+                                                    "singleSelect": true,
+                                                    "xtype": "RowSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params.cohead_id = _this.form.findField('cohead_id').getValue();\n    if (! o.params.cohead_id ) {\n        this.removeAll();\n        return false;\n    }\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'item_number', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/invdetail.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'invdetail_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_qty_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_qty_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_invcitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_ls_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": true,
+                                                    "displayMsg": "Displaying invdetail{0} - {1} of {2}",
+                                                    "emptyMsg": "No invdetail found",
+                                                    "pageSize": 9999,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "item_number",
+                                                    "header": "Item",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "rec_shipped",
+                                                    "header": "#Ship",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "rec_returned",
+                                                    "header": "#Ret",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', Roo.util.Format.number(v,0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "tx_shipped",
+                                                    "header": "#TX ship",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "tx_returned",
+                                                    "header": "#TX ret",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "tx_total",
+                                                    "header": "#TX Tot",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', Roo.util.Format.number(v,0)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "total_value",
+                                                    "header": "Value",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n    return (v*1).toFixed(3);\n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "tx_total",
+                                                    "header": "#Diff",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n\n    var cototal = (r.data.rec_returned*1) - (r.data.rec_shipped*1);\n//    Roo.log(cototal);\n    var diff = (v*1) - cototal;\n //   Roo.log(diff);\n    if (diff == 0)  {\n        return '';\n    }\n    return String.format('<span style=\"color:red\">{0}</span>',  diff ); \n    }",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.txdpanel = this;\n    if (_this.txdgrid) {\n        _this.txdgrid.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "east",
+                                    "tableName": "invdetail",
+                                    "title": "invdetail",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.txdgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.txdpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                                "rowclick": "function (_self, rowIndex, e)\n{\n    var s = _this.txdgrid.ds.getAt(rowIndex);\n    var dt = s.data.invhist_transdate.split(' ');\n    \n    _this.dateSel.setValue(new Date(dt[0]));\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "invhist_comments",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    var s = _this.txdgrid.selModel.getSelected();\n\n    if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a transaction\");\n        return;\n    }\n    \n    var reverseSel = function() {\n    \n        new Pman.Request({\n            mask : \"Reversing\",\n            url : baseURL + '/Roo/invdetail',\n            method : 'POST',\n            params : {\n                _duplicate : s.data.invdetail_id\n            }, \n            success : function() {\n                _this.txdgrid.footer.onClick('first');\n            }\n        });\n    \n    }\n    \n    \n\n    Roo.MessageBox.confirm(\n        \"Confirm\", \n        \"This should only be used by System Administrators - are you sure you know what you are doing!\",\n        function(x) {\n            if (x != 'yes') {\n                return;\n            }\n            reverseSel();\n        }\n    );\n                        \n    \n    \n    \n}"
+                                                            },
+                                                            "text": "Duplicate Selected",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "text": "Issue Date",
+                                                            "xtype": "TextItem",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.dateSel = _self;\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Issue Date",
+                                                            "format": "Y-m-d",
+                                                            "name": "issue_date",
+                                                            "width": 150,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    var s = _this.txdgrid.selModel.getSelected();\n    var dt = _this.dateSel.getValue();\n    if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a transaction\");\n        return;\n    }\n    \n    var reverseSel = function(force) {\n    \n        new Pman.Request({\n            mask : \"Reversing\",\n            url : baseURL + '/Roo/invdetail',\n            method : 'POST',\n            params : {\n                _reverse : s.data.invdetail_id,\n                _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n                _force : force\n            }, \n            success : function() {\n                _this.txdgrid.footer.onClick('first');\n            },\n            failure : function(res) {\n                Roo.log(res);\n                try {\n                    if (res.errors.confirm) {\n                                      \n                        Roo.MessageBox.confirm(\n                            \"Confirm\", \n                            \"are you really sure the totals will get messed up.\",\n                            function(x) {\n                                if (x != 'yes') {\n                                    return;\n                                }\n                                reverseSel(1);\n                            }\n                        );\n                        return;\n                    }\n                } catch(e) { }\n                Roo.MessageBox.alert(\"Error\", res.errorMsg);\n                \n                \n            }\n        });\n    \n    }\n    \n    \n\n    Roo.MessageBox.confirm(\n        \"Confirm\", \n        \"This should only be used by System Administrators - are you sure you know what you are doing!\",\n        function(x) {\n            if (x != 'yes') {\n                return;\n            }\n            reverseSel(0);\n        }\n    );\n                        \n    \n    \n    \n}"
+                                                            },
+                                                            "text": "Reverse Selected",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params.cohead_id = _this.form.findField('cohead_id').getValue();\n    var s = _this.txgrid.selModel.getSelected();\n    if (!s) { \n        this.removeAll();\n        return false;\n    }\n    o.params.itemsite_id = s.data.invhist_itemsite_id;\n    \n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'invdetail_id', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/invdetail.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'invdetail_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_qty_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_qty_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_invcitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_ls_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": true,
+                                                    "displayMsg": "Displaying invdetail{0} - {1} of {2}",
+                                                    "emptyMsg": "No invdetail found",
+                                                    "pageSize": 9999,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invdetail_id",
+                                                    "header": "TX#",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invhist_transdate",
+                                                    "header": "Date",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invhist_ordnumber",
+                                                    "header": "Ref#",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) {\n    if (r.data.invfifo_void *1 != 0) {\n        return String.format('<s>{0}</s>', v); \n    }\n\n     return String.format('{0}', v); \n }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invhist_comments",
+                                                    "header": "Notes",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invdetail_qty",
+                                                    "header": "Qty Changed",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) {\n    if ( r.data.coitem_shipped != v) {\n        return String.format('{0} <span style=\"color:red\">({1})</span>',\n             Roo.util.Format.number(v,0),\n             r.data.coitem_shipped\n         );\n    \n    }\n     return String.format('{0}', Roo.util.Format.number(v,0));\n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invhist_value_before",
+                                                    "header": "Qty Changed",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) {\n    var tot = r.data.invhist_value_after*1 - v*1;\n    var f = '{0}';\n    if (r.data.invdetail_qty >0 && tot < 0) {\n        f = '<span style=\"color:red\">{0}</span>';\n    }\n    if (r.data.invdetail_qty < 0 && tot > 0) {\n        f = '<span style=\"color:red\">{0}</span>';\n    }    \n    return String.format(f, Roo.util.Format.number(tot));\n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invhist_posted",
+                                                    "header": "Posted",
+                                                    "width": 40,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    \n    var state = v   ?  '-checked' : '';\n                                    \n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n }",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "region": "center",
+                    "title": "GL Tx",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "*prop": "east",
+                                    "split": true,
+                                    "width": 500,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.gltxpanel = this;\n    if (_this.gltxgrid) {\n        _this.gltxgrid.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "invdetail",
+                                    "title": "invdetail",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.gltxgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.gltxpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                                "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n    if (columnIndex > 0) {\n        return;\n    }\n    var rec = this.ds.getAt(rowIndex);\n    rec.set('gltrans_as_summary', rec.data.gltrans_as_summary *1 ? 0 : 1);\n    _this.gltxdgrid.footer.onClick('first');\n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "gltrans_accnt_id_accnt_descrip",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "selectionchange": "function (_self)\n{\n    _this.gltxdgrid.footer.onClick('first');;\n}"
+                                                    },
+                                                    "*prop": "sm",
+                                                    "singleSelect": true,
+                                                    "xtype": "RowSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params.cohead_id = _this.form.findField('cohead_id').getValue();\n    if (! o.params.cohead_id ) {\n        this.removeAll();\n        return false;\n    }\n    o.params._split_sales = _this.glsalesbtn.pressed ? 1 : 0;\n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'item_number', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/gltrans.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'invdetail_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_qty_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_qty_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_invcitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_ls_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": true,
+                                                    "displayMsg": "Displaying invdetail{0} - {1} of {2}",
+                                                    "emptyMsg": "No invdetail found",
+                                                    "pageSize": 9999,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.glsalesbtn = _self;\n}",
+                                                                "click": "function (_self, e)\n{\n    (function()  { _this.gltxgrid.footer.onClick('first'); }).defer(100);\n}"
+                                                            },
+                                                            "enableToggle": true,
+                                                            "pressed": true,
+                                                            "text": "Split sales",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_as_summary",
+                                                    "header": "Summary",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    \n    var state = v*1   ?  '-checked' : '';\n                                    \n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_accnt_id_accnt_descrip",
+                                                    "header": "Account",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "gltrans_amount_credit",
+                                                    "header": "Credit",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}',  Roo.util.Format.number(v,3)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "gltrans_amount_debit",
+                                                    "header": "Debit",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', Roo.util.Format.number(v,3)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "gltrans_amount_total",
+                                                    "header": "Sum",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('<b>{0}</b>', Roo.util.Format.number(v,3)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "gltrans_amount_total_unposted",
+                                                    "header": "Unposted",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('<span style=\"color:red\">{0}</span>', Roo.util.Format.number(v,3)); }",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.gltxdpanel = this;\n    if (_this.gltxdgrid) {\n        _this.gltxdgrid.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "background": false,
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "east",
+                                    "tableName": "invdetail",
+                                    "title": "invdetail",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.gltxdgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.gltxdpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                                "cellclick": "function (_self, ri, ci, e)\n{\n    \n      var deleteSel = function() {\n    \n        new Pman.Request({\n            mask : \"Reversing\",\n            url : baseURL + '/Roo/gltrans',\n            method : 'POST',\n            params : {  \n                _void : 1,\n                gltrans_id : rec.data.gltrans_id\n                \n            }, \n            success : function() {\n                rec.set('gltrans_posted', false);\n                rec.set('gltrans_deleted', true);\n                rec.set('gltrans_docnumber', rec.data.gltrans_docnumber);\n               _this.gltxgrid.footer.onClick('first');\n            }\n        });\n    \n    }\n    var undeleteSel = function() {\n    \n        new Pman.Request({\n            mask : \"Reversing\",\n            url : baseURL + '/Roo/gltrans',\n            method : 'POST',\n            params : {  \n                _unvoid : 1,\n                gltrans_id : rec.data.gltrans_id\n                \n            }, \n            success : function() {\n                rec.set('gltrans_posted', true);\n                rec.set('gltrans_deleted', false);\n                rec.set('gltrans_docnumber', rec.data.gltrans_docnumber);\n               _this.gltxgrid.footer.onClick('first');\n            }\n        });\n    \n    }\n    \n    var di = this.colModel.config[ci].dataIndex;\n    if (di != 'gltrans_posted') {\n        return;\n    }\n    \n    \n    \n    var rec = this.ds.getAt(ri);\n    if (rec.data.gltrans_deleted) {\n    \n         Roo.MessageBox.confirm(\n            \"Confirm\", \n            \"This should only be used by System Administrators - are you sure you know what you are doing!\",\n            function(x) {\n                if (x != 'yes') {\n                    return;\n                }\n                undeleteSel();\n            }\n        );\n    \n        return false;\n    }\n\n    \n    \n    if (!rec.data.gltrans_posted) {\n\n        \n        \n        new Pman.Request({\n            method : 'POST',\n            url : baseURL + '/Roo/gltrans',\n            mask : \"Posting\",\n            params : {\n                _post : 1,\n                gltrans_id : rec.data.gltrans_id\n            },\n            success : function (res)\n            {\n                rec.set('gltrans_posted', true);\n                _this.gltxgrid.footer.onClick('first');\n            \n            }\n        \n        \n        });\n        return;\n    }\n    \n    // we have a posted transaction.\n    // only allow recalled to be deleted..\n    if (!rec.data.gltrans_notes.match(/(Recall|Ship Order)/)) {\n        return false;\n    }\n    \n    \n \n    \n    \n\n    Roo.MessageBox.confirm(\n        \"Confirm\", \n        \"This should only be used by System Administrators - are you sure you know what you are doing!\",\n        function(x) {\n            if (x != 'yes') {\n                return;\n            }\n            deleteSel();\n        }\n    );\n          \n    \n    \n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "gltrans_notes",
+                                            "loadMask": true,
+                                            "xtype": "Grid",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n    o.params.cohead_id = _this.form.findField('cohead_id').getValue();\n    var s = _this.gltxgrid.selModel.getSelected();\n    if (!s) { \n        this.removeAll();\n        return false;\n    }\n    o.params.gltrans_accnt_id = s.data.gltrans_accnt_id;\n    o.params.gltrans_is_ship = s.data.gltrans_is_ship;\n    o.params.gltrans_as_summary =     s.data.gltrans_as_summary;\n    \n    \n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'gltrans_docnumber', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/gltrans.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.data",
+                                                            "xtype": "JsonReader",
+                                                            "totalProperty": "total",
+                                                            "root": "data",
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "|fields": "[\n    {\n        'name': 'invdetail_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invdetail_qty_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_qty_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invdetail_invcitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invdetail_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invdetail_ls_id',\n        'type': 'int'\n    }\n]"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "footer",
+                                                    "displayInfo": true,
+                                                    "displayMsg": "Displaying invdetail{0} - {1} of {2}",
+                                                    "emptyMsg": "No invdetail found",
+                                                    "pageSize": 9999,
+                                                    "xtype": "PagingToolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    new Pman.Download( {\n        grid : _this.gltxdgrid\n    \n    });\n}"
+                                                            },
+                                                            "text": "Download",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_id",
+                                                    "header": "Ref#",
+                                                    "sortable": true,
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_date",
+                                                    "header": "Date",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_docnumber",
+                                                    "header": "Doc#",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    if (r.data.gltrans_deleted) {\n       return String.format('<s>{0}</s>', v);     \n    }\n    return String.format('{0}', v); \n}",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_source",
+                                                    "header": "Source",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_notes",
+                                                    "header": "Notes",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "gltrans_amount",
+                                                    "header": "Amount",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', Roo.util.Format.number(v,3)); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "gltrans_posted",
+                                                    "header": "Posted",
+                                                    "width": 50,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    \n    var state = v   ?  '-checked' : '';\n                                    \n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n }",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.profitpanel = this;\n    \n    try { if (MODULE.isBuilder) {\n        return;\n    } } catch(e) { }\n    \n    var id = _this.form.findField('cohead_id').getValue() * 1;\n    if (id < 1) {\n        Roo.MessageBox.alert(\"Save First\", \"Save the order first, before adding items\");\n        _this.dialog.layout.getRegion('center').showPanel(0);\n        return;\n    }\n    \n    if (_this.profitgrid) {\n        _this.profitgrid.footer.onClick('first');\n     }\n    \n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "coitem",
+                    "title": "Profit",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.profitgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.profitpanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_number",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self,o) {\n\n    try {\n       this.removeAll();\n   } catch (e) { }\n   \n\n    if (!_this.data || !_this.data.cohead_id) {\n        return false;\n    }\n    o.params = o.params || {};\n    \n    o.params.coitem_cohead_id = _this.data.cohead_id;\n    o.params._without_list_discount =1;\n    o.params._with_profit = 1;\n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'coitem_linenumber,coitem_subnumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/coitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying coitem{0} - {1} of {2}",
+                                    "emptyMsg": "No coitem found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item Code",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "calc_subtotal",
+                                    "header": "SubTotal",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {\n\n\n     return Roo.util.Format.number( v, 2);\n  }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "calc_cost_total",
+                                    "header": "Cost of goods",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {\n\n    return Roo.util.Format.number( v, 2);\n  }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "profit",
+                                    "header": "Profit",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n        \n   var profit = r.data.calc_subtotal - r.data.calc_cost_total;\n   \n   if(parseInt(profit) < 1){\n       return String.format('<b style=\"color:red;\">{0}</b>', Roo.util.Format.number(profit,2));      \n   }\n        \n        \n    return Roo.util.Format.number( profit, 2);\n}",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n      if (_this.grid)  _this.grid.stopEditing();\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     \n      if (_this.grid)  _this.grid.stopEditing();\n \n    _this.form.doAction(\"submit\");\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleSalesOrder.js b/Pman.Dialog.XtupleSalesOrder.js
new file mode 100644 (file)
index 0000000..5eaf268
--- /dev/null
@@ -0,0 +1,6727 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleSalesOrder = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function () {
+                       this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : true,
+            collapsible : false,
+            height : 620,
+            modal : true,
+            resizable : true,
+            title : "Edit / Create Sales Order",
+            width : 1050,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function (_self)
+                        {
+                            // we need to reload to find out the subtotal.
+                            if (!_this.data || !_this.data.cohead_id) {
+                                return;
+                            }
+                            new Pman.Request({
+                                method : 'GET',
+                                url : baseURL + '/Roo/cohead',
+                                params : { 
+                                    _id : _this.data.cohead_id
+                                },
+                                success : function(res) {
+                                    _this.form.findField('cohead_subtotal').setValue(res.data.cohead_subtotal);
+                                    _this.form.findField('cohead_tax').setValue(res.data.cohead_tax);
+                                    _this.form.findField('cohead_uninvoiced').setValue(res.data.cohead_uninvoiced);
+                                    _this.form.findField('cohead_unshipped').setValue(res.data.cohead_unshipped);
+                                   _this.form.findField('cohead_pretax_discount').setValue(res.data.cohead_pretax_discount); 
+                                    _this.form.findField('cohead_total').recalc(); 
+                                    _this.form.findField('cohead_misc').recalc(); 
+                                }
+                            });
+                        }
+                    },
+                    region : 'center',
+                    title : "Order Details",
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        // clear the stock level cache...
+                                        _this.stockcache = [];
+                                        
+                                        if (_this.data.cohead_id) {
+                                           this.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});
+                                           
+                                           return;
+                                        }
+                                        _this.dialog.setTitle("Edit New Sales Order");
+                                       
+                                        _this.closeBtn.hide();
+                                        _this.voidBtn.hide();
+                                        _this.saveBtn.show();
+                                        
+                                        if(_this.data.cohead_billto_cntct_id_cntct_id){
+                                            _this.form.findField('billto_address').update();
+                                            
+                                            _this.form.setValues({
+                                                cohead_billto_cntct_id: _this.data.cohead_billto_cntct_id_cntct_id,
+                                                cohead_billto_cntct_id_cntct_name : _this.data.cohead_billto_cntct_id_cntct_name,
+                                                _shipto_same : 1,
+                                                _same_as_order : 1
+                                                
+                                            }); 
+                                        }
+                                         
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                         
+                                        
+                                        _this.data = action.result.data;
+                                
+                                        if (!_this.data.cohead_shipto_id && _this.data.shipto_id*1 > 0) {
+                                            _this.form.findField('cohead_shipto_id').setValue(_this.data.shipto_id);
+                                            _this.form.findField('cohead_shipto_id_shipto_name').setValue(_this.data.cohead_shipto_cntct_id_cntct_name);
+                                        
+                                        }
+                                        
+                                        
+                                        _this.dataloading = true;
+                                        if (_this.data.cohead_shipto_cntct_id == _this.data.cohead_billto_cntct_id) {
+                                            this.findField('_shipto_same').setValue(1);
+                                              Roo.log("set shipto 1");
+                                        } else {
+                                          this.findField('_shipto_same').setValue(0);
+                                           Roo.log("set shipto 0");
+                                        }
+                                        _this.dataloading = false;          
+                                        
+                                        
+                                        this.findField('billto_address').update();
+                                        this.findField('shipto_address').update();        
+                                        _this.dialog.setTitle("Edit Sales Order - " + this.findField('cohead_number').getValue());
+                                         
+                                        
+                                        if (_this.data.cohead_status == 'C') {
+                                            _this.closeBtn.show();
+                                            _this.closeBtn.setText('Re-open');
+                                             _this.voidBtn.hide();
+                                             _this.saveBtn.hide();
+                                        }  else  if (_this.data.cohead_status == 'X') {
+                                            _this.closeBtn.hide(); 
+                                             _this.voidBtn.show(); 
+                                             _this.voidBtn.setText("Un-void / Re-open"); 
+                                             _this.saveBtn.hide();
+                                        } else {
+                                            // it's open
+                                             _this.closeBtn.show(); 
+                                            _this.closeBtn.setText('Complete and Close');             
+                                             _this.voidBtn.setText("Void");             
+                                             _this.voidBtn.show(); 
+                                             _this.saveBtn.show();        
+                                        }
+                                        
+                                         _this.form.findField('cohead_misc_per').update();
+                                       
+                                       // finally override the value for discount...
+                                       if ((''+ _this.data.cohead_misc_descrip).length) {
+                                            _this.form.findField('cohead_misc_descrip').setValue(_this.data.cohead_misc_descrip);
+                                       }
+                                       
+                                       // update the stockcache...
+                                
+                                       new Pman.Request({
+                                            url : baseURL + '/Roo/cohead',
+                                            method : 'GET',
+                                            params : {
+                                                _stockLevel : _this.data.cohead_id
+                                            },
+                                            success : function(res) 
+                                            {
+                                                for (var i in res.data) {
+                                                   
+                                                    if(typeof(_this.stockcache[res.data[i].item]) == 'undefined'){
+                                                        _this.stockcache[res.data[i].item] = res.data[i];
+                                                    }
+                                                }
+                                            }
+                                        });
+                                       
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                
+                                        var id = _this.form.findField('cohead_id').getValue() * 1;
+                                        if (id < 1) {
+                                
+                                            _this.data.cohead_id = action.result.data.cohead_id;
+                                             this.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});
+                                            return;
+                                        }
+                                    
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                },
+                                actionfailed : function (_self, action)
+                                {
+                                    if (action.failureType == 'client') {
+                                        Roo.MessageBox.alert("Error", "Fill in all the required fields");
+                                    }
+                                    if (action.failureType == 'server') {    
+                                        Roo.log(action);
+                                        Roo.MessageBox.alert("Error", action.result.errorMsg);
+                                    }
+                                    _this.dialog.layout.getRegion('center').showPanel(0);
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/cohead.php',
+                            items : [
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : '435',
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            labelWidth : 120,
+                                            legend : "Order",
+                                            style : 'width:420px',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelWidth : 100,
+                                                    width : 410,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelWidth : 100,
+                                                            width : 400,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    allowBlank : true,
+                                                                    emptyText : "Automatic",
+                                                                    fieldLabel : 'Order#',
+                                                                    name : 'cohead_number',
+                                                                    readOnly : true,
+                                                                    width : 120
+                                                                },
+                                                                {
+                                                                    xtype: 'Row',
+                                                                    xns: Roo.form,
+                                                                    labelWidth : 50,
+                                                                    style : 'float:left',
+                                                                    width : 150,
+                                                                    items : [
+                                                                        {
+                                                                            xtype: 'TextField',
+                                                                            xns: Roo.form,
+                                                                            allowBlank : true,
+                                                                            fieldLabel : 'Cust#',
+                                                                            name : 'cohead_cust_id_cust_number',
+                                                                            readOnly : true,
+                                                                            width : 110
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            editable : false,
+                                                            fieldLabel : 'Customer',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_cust_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_cust_id_cust_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select custinfo",
+                                                            queryParam : 'query[cust_name]',
+                                                            readOnly : true,
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'cust_id',
+                                                            width : 300
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Customer PO#',
+                                                            name : 'cohead_custponumber',
+                                                            width : '150'
+                                                        },
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            fieldLabel : 'Ordered',
+                                                            format : 'Y-m-d',
+                                                            name : 'cohead_orderdate',
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelWidth : 100,
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'DateField',
+                                                                    xns: Roo.form,
+                                                                    allowBlank : false,
+                                                                    fieldLabel : 'Target Delivery',
+                                                                    format : 'Y-m-d',
+                                                                    name : 'cohead_targetdate',
+                                                                    width : 100
+                                                                },
+                                                                {
+                                                                    xtype: 'Row',
+                                                                    xns: Roo.form,
+                                                                    hideLabels : true,
+                                                                    items : [
+                                                                        {
+                                                                            xtype: 'Checkbox',
+                                                                            xns: Roo.form,
+                                                                            listeners : {
+                                                                                check : function (_self, checked)
+                                                                                {
+                                                                                    if(checked){
+                                                                                        _this.form.findField('cohead_targetdate').setValue(_this.form.findField('cohead_orderdate').getValue());
+                                                                                    }
+                                                                                }
+                                                                            },
+                                                                            boxLabel : 'same as order',
+                                                                            inputValue : 1,
+                                                                            name : '_same_as_order'
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            displayField : 'location_name',
+                                                            editable : true,
+                                                            emptyText : "Supply From",
+                                                            fieldLabel : 'Supply From',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_location_src',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_location_src_location_name',
+                                                            pageSize : 200,
+                                                            qtip : "Select terms",
+                                                            queryParam : 'query[location_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> {location_descrip} </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : false,
+                                                            valueField : 'location_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                         o.params.location_netable = 1;
+                                                                          o.params.location_restrict = 0;
+                                                                          o.params._notinternalcompany = 1;
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/location.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'location_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"location_id","type":"int"},"location_name"]
+                                                                }
+                                                            }
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            labelWidth : 100,
+                                            legend : "Details",
+                                            style : 'width:420px',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelWidth : 100,
+                                                    width : 420,
+                                                    items : [
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            editable : false,
+                                                            emptyText : "Select terms",
+                                                            forceSelection : true,
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            pageSize : 20,
+                                                            qtip : "Select terms",
+                                                            selectOnFocus : true,
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            width : 300,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{terms_descrip}</b> </div>',
+                                                            queryParam : 'query[terms_descrip]',
+                                                            fieldLabel : 'Terms',
+                                                            valueField : 'terms_id',
+                                                            displayField : 'terms_descrip',
+                                                            hiddenName : 'cohead_terms_id',
+                                                            name : 'cohead_terms_id_terms_descrip',
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'terms_descrip' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/terms.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'terms_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"terms_id","type":"int"},"terms_descrip"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : true,
+                                                            alwaysQuery : true,
+                                                            displayField : 'salesrep_name',
+                                                            editable : false,
+                                                            emptyText : "Select salesrep",
+                                                            fieldLabel : 'Sales Rep',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_display_salesrep_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_display_salesrep_id_salesrep_name',
+                                                            pageSize : 80,
+                                                            qtip : "Select salesrep",
+                                                            queryParam : 'query[salesrep_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'salesrep_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'salesrep_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/salesrep.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'salesrep_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"salesrep_id","type":"int"},"salesrep_name"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            alwaysQuery : true,
+                                                            displayField : 'salesrep_name',
+                                                            editable : false,
+                                                            emptyText : "Select Staff",
+                                                            fieldLabel : 'Staff I.C.',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_salesrep_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_salesrep_id_salesrep_name',
+                                                            pageSize : 80,
+                                                            qtip : "Select salesrep",
+                                                            queryParam : 'query[salesrep_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'salesrep_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'salesrep_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/salesrep.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'salesrep_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"salesrep_id","type":"int"},"salesrep_name"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Order Comments',
+                                                            height : 80,
+                                                            name : 'cohead_ordercomments',
+                                                            width : 300
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            style : 'width:420px',
+                                            legend : "Billing",
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    width : '420',
+                                                    labelWidth : '50',
+                                                    items : [
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                beforeselect : function (combo, record, index)
+                                                                {
+                                                                    // set _this.data values ..
+                                                                    
+                                                                    // just add everything...
+                                                                    for(var i in record.data) {
+                                                                        Roo.log('cohead_billto_cntct_id_' + i +' ='  + record.data[i]);
+                                                                        _this.data['cohead_billto_cntct_id_' + i] = record.data[i];
+                                                                    }
+                                                                    
+                                                                    _this.form.findField('billto_address').update();
+                                                                    
+                                                                 
+                                                                },
+                                                                add : function (combo)
+                                                                {
+                                                                  
+                                                                  Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cohead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                               
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cohead_billto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('billto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cohead_billto_cntct_id : data.cntct_id,
+                                                                                    cohead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                    
+                                                                                });
+                                                                            }
+                                                                        );
+                                                                        //  Pman.Dialog.XtupleCustomer.show(
+                                                                            //{ cust_id : _this.form.findField('cohead_cust_id').getValue() }, 
+                                                                            //function(data) {
+                                                                        // refresh the data in the pulldown..
+                                                                    //    }); 
+                                                                
+                                                                }
+                                                            },
+                                                            allowBlank : false,
+                                                            alwaysQuery : true,
+                                                            displayField : 'cntct_name',
+                                                            editable : true,
+                                                            emptyText : "Select cntct",
+                                                            fieldLabel : 'Bill To (select)',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_billto_cntct_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_billto_cntct_id_cntct_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select cntct",
+                                                            queryParam : 'query[cntct_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cntct_name}</b> {cntct_addr_id_addr_line1}</div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'cntct_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                        o.params._customer_id = _this.data.cohead_cust_id;
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'cntct_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/cntct.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'cntct_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"cntct_id","type":"int"},"cntct_name"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                render : function (_self)
+                                                                {
+                                                                   Roo.log(this.el)
+                                                                   
+                                                                   
+                                                                   
+                                                                   this.el.on('click', function() { 
+                                                                       var id = _this.form.findField('cohead_billto_cntct_id').getValue();
+                                                                        Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cohead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                            
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cohead_billto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('billto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cohead_billto_cntct_id : data.cntct_id,
+                                                                                    cohead_billto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                    
+                                                                                });
+                                                                                
+                                                                                        
+                                                                                Roo.log(data);
+                                                                            }
+                                                                        );
+                                                                   
+                                                                        Roo.log("Click text");
+                                                                        
+                                                                        
+                                                                     });
+                                                                }
+                                                            },
+                                                            fieldLabel : 'or enter Address',
+                                                            name : 'billto_address',
+                                                            readOnly : true,
+                                                            update : function() {
+                                                            
+                                                                var c = ['first_name', 'last_name' ] ;
+                                                                var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];
+                                                                var v = [];
+                                                                Roo.each(c, function(e) {
+                                                                    if (_this.data['cohead_billto_cntct_id_cntct_' +e].length) { 
+                                                                        v.push(_this.data['cohead_billto_cntct_id_cntct_' +e]);
+                                                                    }
+                                                                });
+                                                                Roo.each(a, function(e) {
+                                                                    if (_this.data['cohead_billto_cntct_id_cntct_addr_id_addr_' +e].length) {
+                                                                        v.push(_this.data['cohead_billto_cntct_id_cntct_addr_id_addr_' +e]);
+                                                                    }
+                                                                });
+                                                            
+                                                                this.setValue(v.join("\n"));
+                                                            }
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : '435',
+                                    style : 'margin-left:10px',
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Price Details",
+                                            style : 'width:420px',
+                                            labelWidth : '50',
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'right',
+                                                    labelWidth : 300,
+                                                    width : 420,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'ComboBox',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        beforequery : function (combo, query, forceAll, cancel, e)
+                                                                        {
+                                                                            Roo.log('beforequery');
+                                                                           
+                                                                            if (_this.form.findField('cohead_number').getValue().length) {
+                                                                                Roo.MessageBox.alert("Error", "You can not change the currency of this order");
+                                                                                if (query) {
+                                                                                    query.cancel = true;
+                                                                                }
+                                                                                return false;
+                                                                            }
+                                                                        }
+                                                                    },
+                                                                    allowBlank : false,
+                                                                    displayField : 'curr_name',
+                                                                    editable : false,
+                                                                    emptyText : "Select curr_name",
+                                                                    fieldLabel : 'Currency',
+                                                                    forceSelection : true,
+                                                                    hiddenName : 'cohead_curr_id',
+                                                                    listWidth : 400,
+                                                                    loadingText : "Searching...",
+                                                                    minChars : 2,
+                                                                    name : 'cohead_curr_id_curr_name',
+                                                                    pageSize : 20,
+                                                                    qtip : "Select Currency",
+                                                                    queryParam : 'query[curr_name]',
+                                                                    selectOnFocus : true,
+                                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                                                    triggerAction : 'all',
+                                                                    typeAhead : true,
+                                                                    valueField : 'curr_id',
+                                                                    width : 285,
+                                                                    store : {
+                                                                        xtype: 'Store',
+                                                                        xns: Roo.data,
+                                                                        listeners : {
+                                                                            beforeload : function (_self, o){
+                                                                                o.params = o.params || {};
+                                                                                // set more here
+                                                                               
+                                                                            }
+                                                                        },
+                                                                        remoteSort : true,
+                                                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                                                        proxy : {
+                                                                            xtype: 'HttpProxy',
+                                                                            xns: Roo.data,
+                                                                            method : 'GET',
+                                                                            url : baseURL + '/Roo/curr_symbol.php'
+                                                                        },
+                                                                        reader : {
+                                                                            xtype: 'JsonReader',
+                                                                            xns: Roo.data,
+                                                                            id : 'curr_id',
+                                                                            root : 'data',
+                                                                            totalProperty : 'total',
+                                                                            fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                                                        }
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Products',
+                                                                    name : 'cohead_subtotal',
+                                                                    readOnly : true,
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'ComboBox',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        select : function (combo, record, index)
+                                                                        {
+                                                                             _this.form.findField('cohead_tax').setValue(
+                                                                                     parseFloat(record.data.taxzone_rate) * 
+                                                                                     parseFloat(_this.form.findField('cohead_subtotal').getValue())
+                                                                             );
+                                                                              _this.form.findField('cohead_total').recalc();
+                                                                        }
+                                                                    },
+                                                                    allowBlank : false,
+                                                                    displayField : 'taxzone_descrip',
+                                                                    editable : false,
+                                                                    emptyText : "Select taxtype",
+                                                                    fieldLabel : 'Tax Zone',
+                                                                    forceSelection : true,
+                                                                    hiddenName : 'cohead_taxzone_id',
+                                                                    listWidth : 400,
+                                                                    loadingText : "Searching...",
+                                                                    minChars : 2,
+                                                                    name : 'cohead_taxzone_id_taxzone_descrip',
+                                                                    pageSize : 20,
+                                                                    qtip : "Select taxtype",
+                                                                    queryParam : 'query[taxzone_descrip]',
+                                                                    selectOnFocus : true,
+                                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxzone_descrip}</b> </div>',
+                                                                    triggerAction : 'all',
+                                                                    typeAhead : true,
+                                                                    valueField : 'taxzone_id',
+                                                                    width : 285,
+                                                                    store : {
+                                                                        xtype: 'Store',
+                                                                        xns: Roo.data,
+                                                                        listeners : {
+                                                                            beforeload : function (_self, o){
+                                                                                o.params = o.params || {};
+                                                                                // set more here
+                                                                                
+                                                                                o.params.with_date = _this.form.findField('cohead_orderdate').getValue().format('Y-m-d'); 
+                                                                                Roo.log("with date?" + o.params.with_date);
+                                                                                
+                                                                                
+                                                                            }
+                                                                        },
+                                                                        remoteSort : true,
+                                                                        sortInfo : { direction : 'ASC', field: 'taxzone_descrip' },
+                                                                        proxy : {
+                                                                            xtype: 'HttpProxy',
+                                                                            xns: Roo.data,
+                                                                            method : 'GET',
+                                                                            url : baseURL + '/Roo/taxzone.php'
+                                                                        },
+                                                                        reader : {
+                                                                            xtype: 'JsonReader',
+                                                                            xns: Roo.data,
+                                                                            id : 'taxzone_id',
+                                                                            root : 'data',
+                                                                            totalProperty : 'total',
+                                                                            fields : [{"name":"taxzone_id","type":"int"},"taxzone_descrip"]
+                                                                        }
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : 'Tax',
+                                                                    name : 'cohead_tax',
+                                                                    readOnly : true,
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'NumberField',
+                                                            xns: Roo.form,
+                                                            allowDecimals : true,
+                                                            cls : 'roo-align-right',
+                                                            decimalPrecision : 3,
+                                                            fieldLabel : 'Pre Tax discount',
+                                                            name : 'cohead_pretax_discount',
+                                                            readOnly : true,
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelAlign : 'top',
+                                                            labelSeparator : '&nbsp;',
+                                                            width : 500,
+                                                            items : [
+                                                                {
+                                                                    xtype: 'TextField',
+                                                                    xns: Roo.form,
+                                                                    fieldLabel : 'Discount after Tax  Description',
+                                                                    name : 'cohead_misc_descrip',
+                                                                    width : 230
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        keyup : function (_self, e)
+                                                                        {
+                                                                            var pv =  parseFloat(_this.form.findField('cohead_subtotal').getValue());
+                                                                            var tax = parseFloat(_this.form.findField('cohead_tax').getValue());
+                                                                            var pd = parseFloat(_this.form.findField('cohead_pretax_discount').getValue());
+                                                                            
+                                                                            var n = this.getValue();
+                                                                            var discount = parseFloat(n * (pv + tax + pd) * 0.01);
+                                                                            
+                                                                            _this.form.findField('cohead_posttax_discount').setValue(discount);
+                                                                        
+                                                                            _this.form.findField('cohead_total').recalc();
+                                                                            _this.form.findField('cohead_misc').recalc();
+                                                                            var val = discount * -1.0;
+                                                                             if (val > 0) {
+                                                                                _this.form.findField('cohead_misc_descrip').setValue("Discount of " + val.toFixed(1)+'%');
+                                                                            }
+                                                                           
+                                                                            
+                                                                        }
+                                                                    },
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 1,
+                                                                    fieldLabel : '%',
+                                                                    name : 'cohead_misc_per',
+                                                                    width : 35,
+                                                                    update : function() {
+                                                                        var m = _this.form.findField('cohead_misc_per');
+                                                                        var pv =  parseFloat(_this.form.findField('cohead_subtotal').getValue());
+                                                                        var tax = parseFloat(_this.form.findField('cohead_tax').getValue());
+                                                                        var pd = parseFloat(_this.form.findField('cohead_pretax_discount').getValue());
+                                                                        
+                                                                        var discount = parseFloat(_this.form.findField('cohead_posttax_discount').getValue());
+                                                                        
+                                                                        if (discount > 0.0) {
+                                                                            this.setValue(0);        
+                                                                            return;
+                                                                        }
+                                                                        if (pv < 0) {
+                                                                            this.setValue(0);        
+                                                                            return;
+                                                                        }
+                                                                        var val = ((discount) / (pv + tax + pd)) * -100;
+                                                                        
+                                                                        //Roo.log("update discount?" + val);
+                                                                        this.setValue(val.toFixed(1));
+                                                                        
+                                                                         if (val > 0.0) {
+                                                                            _this.form.findField('cohead_misc_descrip').setValue("Discount of " + val.toFixed(1)+'%');
+                                                                        
+                                                                        }
+                                                                        
+                                                                       
+                                                                    }
+                                                                },
+                                                                {
+                                                                    xtype: 'NumberField',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        keyup : function (_self, e)
+                                                                        {
+                                                                           _this.form.findField('cohead_misc_per').update();
+                                                                            _this.form.findField('cohead_total').recalc();
+                                                                            _this.form.findField('cohead_misc').recalc();
+                                                                        }
+                                                                    },
+                                                                    allowDecimals : true,
+                                                                    cls : 'roo-align-right',
+                                                                    decimalPrecision : 3,
+                                                                    fieldLabel : '&nbsp;',
+                                                                    name : 'cohead_posttax_discount',
+                                                                    width : 100
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'NumberField',
+                                                            xns: Roo.form,
+                                                            allowDecimals : true,
+                                                            cls : 'roo-align-right',
+                                                            decimalPrecision : 3,
+                                                            fieldLabel : 'Total',
+                                                            name : 'cohead_total',
+                                                            readOnly : true,
+                                                            width : 100,
+                                                            recalc : function() {
+                                                                var d = _this.form.getValues();
+                                                                this.setValue( 
+                                                                            parseFloat(d.cohead_subtotal) + 
+                                                                            parseFloat(d.cohead_pretax_discount) + 
+                                                                            parseFloat(d.cohead_posttax_discount) + 
+                                                                            parseFloat(d.cohead_tax) + 
+                                                                            parseFloat(d.cohead_freight));
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'NumberField',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                keyup : function (_self, e)
+                                                                {
+                                                                    _this.form.findField('cohead_total').recalc();
+                                                                }
+                                                            },
+                                                            allowDecimals : true,
+                                                            cls : 'roo-align-right',
+                                                            decimalPrecision : 3,
+                                                            fieldLabel : 'Shipping',
+                                                            name : 'cohead_freight',
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'NumberField',
+                                                            xns: Roo.form,
+                                                            allowDecimals : true,
+                                                            cls : 'roo-align-right',
+                                                            decimalPrecision : 3,
+                                                            fieldLabel : 'Unshipped Total',
+                                                            name : 'cohead_unshipped',
+                                                            readOnly : true,
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'NumberField',
+                                                            xns: Roo.form,
+                                                            allowDecimals : true,
+                                                            cls : 'roo-align-right',
+                                                            decimalPrecision : 3,
+                                                            fieldLabel : 'Uninvoiced Total',
+                                                            name : 'cohead_uninvoiced',
+                                                            readOnly : true,
+                                                            width : 100
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            style : 'width:420px',
+                                            legend : "Shipping",
+                                            items : [
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    width : '420',
+                                                    labelWidth : '50',
+                                                    items : [
+                                                        {
+                                                            xtype: 'Row',
+                                                            xns: Roo.form,
+                                                            labelSeparator : '&nbsp;',
+                                                            items : [
+                                                                {
+                                                                    xtype: 'Checkbox',
+                                                                    xns: Roo.form,
+                                                                    listeners : {
+                                                                        check : function (_self, checked)
+                                                                        {
+                                                                           if (!_this.form) {
+                                                                               return;
+                                                                           }
+                                                                           
+                                                                           if (_this.dataloading) {
+                                                                           
+                                                                               return;
+                                                                           }
+                                                                           
+                                                                           
+                                                                           if (checked) {
+                                                                           
+                                                                                // copy the cohead_billto_cntct_id
+                                                                                for (var i in _this.data) {
+                                                                                    if (!i.match(/^cohead_billto_cntct_id/)) {
+                                                                                        continue;
+                                                                                    }
+                                                                                    var ni = i.replace(/^cohead_billto_cntct_id/, 'cohead_shipto_cntct_id');
+                                                                                    _this.data[ni] = _this.data[i];
+                                                                                }
+                                                                                 _this.form.findField('shipto_address').update();
+                                                                                 _this.form.setValues( {
+                                                                                        cohead_shipto_cntct_id : _this.data.cohead_shipto_cntct_id,
+                                                                                        cohead_shipto_cntct_id_cntct_name : _this.data.cohead_shipto_cntct_id_cntct_first_name + ' ' + 
+                                                                                                _this.data.cohead_shipto_cntct_id_cntct_last_name 
+                                                                                                
+                                                                                        
+                                                                                    });
+                                                                        
+                                                                           
+                                                                            } else {
+                                                                                 for (var i in _this.data) {
+                                                                                    if (!i.match(/^cohead_billto_cntct_id/)) {
+                                                                                        continue;
+                                                                                    }
+                                                                                    var ni = i.replace(/^cohead_billto_cntct_id/, 'cohead_shipto_cntct_id');
+                                                                                    
+                                                                                    _this.data[ni] = '';
+                                                                                }
+                                                                                 _this.form.findField('shipto_address').update();
+                                                                                 
+                                                                                _this.form.setValues( {
+                                                                                        cohead_shipto_cntct_id : '',
+                                                                                        cohead_shipto_cntct_id_cntct_name : '' 
+                                                                                        
+                                                                                        
+                                                                                    });
+                                                                            }
+                                                                            
+                                                                        }
+                                                                    },
+                                                                    boxLabel : 'Same as Billing',
+                                                                    name : '_shipto_same'
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            xtype: 'ComboBox',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                add : function (combo)
+                                                                {
+                                                                 Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cohead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                               
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cohead_shipto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('shipto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cohead_shipto_cntct_id : data.cntct_id,
+                                                                                    cohead_shipto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                    
+                                                                                });
+                                                                            }
+                                                                        ); 
+                                                                },
+                                                                beforeselect : function (combo, record, index)
+                                                                {
+                                                                   
+                                                                    // just add everything...
+                                                                    for(var i in record.data) {
+                                                                        //Roo.log('cohead_shipto_cntct_id_' + i +' ='  + record.data[i]);
+                                                                        _this.data['cohead_shipto_cntct_id_' + i] = record.data[i];
+                                                                    }
+                                                                
+                                                                    _this.form.findField('shipto_address').update();
+                                                                    
+                                                                 
+                                                                }
+                                                            },
+                                                            allowBlank : false,
+                                                            alwaysQuery : true,
+                                                            displayField : 'cntct_name',
+                                                            editable : true,
+                                                            emptyText : "Select ship to",
+                                                            fieldLabel : 'Ship to',
+                                                            forceSelection : true,
+                                                            hiddenName : 'cohead_shipto_cntct_id',
+                                                            listWidth : 400,
+                                                            loadingText : "Searching...",
+                                                            minChars : 2,
+                                                            name : 'cohead_shipto_cntct_id_cntct_name',
+                                                            pageSize : 20,
+                                                            qtip : "Select shiptoinfo",
+                                                            queryParam : 'query[cntct_name]',
+                                                            selectOnFocus : true,
+                                                            tpl : '<div class="x-grid-cell-text x-btn button">{cntct_name} - <b>{cntct_addr_id_addr_line1}</b> </div>',
+                                                            triggerAction : 'all',
+                                                            typeAhead : true,
+                                                            valueField : 'cntct_id',
+                                                            width : 300,
+                                                            store : {
+                                                                xtype: 'Store',
+                                                                xns: Roo.data,
+                                                                listeners : {
+                                                                    beforeload : function (_self, o){
+                                                                        o.params = o.params || {};
+                                                                        // set more here
+                                                                        o.params._customer_id = _this.data.cohead_cust_id;
+                                                                    }
+                                                                },
+                                                                remoteSort : true,
+                                                                sortInfo : { direction : 'ASC', field: 'cntct_name' },
+                                                                proxy : {
+                                                                    xtype: 'HttpProxy',
+                                                                    xns: Roo.data,
+                                                                    method : 'GET',
+                                                                    url : baseURL + '/Roo/cntct.php'
+                                                                },
+                                                                reader : {
+                                                                    xtype: 'JsonReader',
+                                                                    xns: Roo.data,
+                                                                    id : 'cntct_id',
+                                                                    root : 'data',
+                                                                    totalProperty : 'total',
+                                                                    fields : [{"name":"cntct_id","type":"int"},"cntct_name"]
+                                                                }
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            listeners : {
+                                                                render : function (_self)
+                                                                {
+                                                                   Roo.log(this.el)
+                                                                   
+                                                                   
+                                                                   
+                                                                   this.el.on('click', function() { 
+                                                                       var id = _this.form.findField('cohead_shipto_cntct_id').getValue();
+                                                                        Pman.Dialog.XtupleQuickContact.show( 
+                                                                            {
+                                                                              _id : id,
+                                                                              customer_id : _this.form.findField('cohead_cust_id').getValue()
+                                                                            },
+                                                                            
+                                                                            function (data) {
+                                                                            
+                                                                                for(var i in  data) {
+                                                                                    
+                                                                                    _this.data['cohead_shipto_cntct_id_' + i] =  data[i];
+                                                                                }
+                                                                                
+                                                                                _this.form.findField('shipto_address').update();
+                                                                                // fill in the select box..
+                                                                                _this.form.setValues( {
+                                                                                    cohead_shipto_cntct_id : data.cntct_id,
+                                                                                    cohead_shipto_cntct_id_cntct_name : data.cntct_first_name + ' '+ 
+                                                                                            data.cntct_last_name
+                                                                                    
+                                                                                });
+                                                                                
+                                                                                        
+                                                                                //Roo.log(data);
+                                                                            }
+                                                                        );
+                                                                   
+                                                                      //  Roo.log("Click text");
+                                                                        
+                                                                        
+                                                                     });
+                                                                }
+                                                            },
+                                                            fieldLabel : 'Address',
+                                                            name : 'shipto_address',
+                                                            readOnly : true,
+                                                            width : 300,
+                                                            update : function() {
+                                                            
+                                                                var c = ['first_name', 'last_name' ] ;
+                                                                var a = [ 'line1', 'line2', 'line3', 'city', 'state', 'country' ];
+                                                                var v = [];
+                                                                Roo.each(c, function(e) {
+                                                                    if (_this.data['cohead_shipto_cntct_id_cntct_' +e] && 
+                                                                        _this.data['cohead_shipto_cntct_id_cntct_' +e].length) {
+                                                                        v.push(_this.data['cohead_shipto_cntct_id_cntct_' +e]);
+                                                                    }
+                                                                });
+                                                                Roo.each(a, function(e) {
+                                                                    if (_this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e] && 
+                                                                        _this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e].length) { 
+                                                                        v.push(_this.data['cohead_shipto_cntct_id_cntct_addr_id_addr_' +e]);
+                                                                    }
+                                                                });
+                                                            
+                                                                this.setValue(v.join("\n"));
+                                                            }
+                                                        },
+                                                        {
+                                                            xtype: 'TextArea',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Shipment Comments',
+                                                            name : 'cohead_shipcomments',
+                                                            width : 300
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_shipto_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_shipto_id_shipto_name'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_max_linenumber'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_cust_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'cohead_misc',
+                                    recalc : function() {
+                                        var d = _this.form.getValues();
+                                        this.setValue( 
+                                            parseFloat(d.cohead_pretax_discount) + 
+                                            parseFloat(d.cohead_posttax_discount) );
+                                    }
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'taxzone_rate'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            
+                            try { if (MODULE.isBuilder) {
+                                return;
+                            } } catch(e) { }
+                            
+                            var id = _this.form.findField('cohead_id').getValue() * 1;
+                            if (id < 1) {
+                                Roo.MessageBox.alert("Save First", "Save the order first, before adding items");
+                                _this.dialog.layout.getRegion('center').showPanel(0);
+                                return;
+                            }
+                            
+                            if (_this.grid) {
+                                _this.grid.footer.onClick('first');
+                            
+                                 //if (_this.form.findField('cohead_cust_id_cust_name').getValue() == 'Bloom and Grow HK') {
+                                 //   _this.xferAll.show();
+                                // 
+                                // } else {
+                                //     _this.xferAll.hide();
+                                // }
+                             }
+                            
+                        },
+                        deactivate : function (_self)
+                        {
+                            if(_this.grid){
+                                _this.grid.stopEditing();
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'coitem',
+                    title : "Order Items",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                
+                                if (_this.panel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            afteredit : function (e)
+                            {
+                                Roo.log('afteredit:' + e.record.data.coitem_linenumber);
+                            
+                                
+                               // if ( e.record && e.record.data.coitem_id) {
+                                    // as we disable update to the display on the ajax callback to 
+                                    // allow editing flow to continue, and not refresh - we can only update
+                                    // these values after something has actually been edited.
+                                    // e.record.set('coitem_id', e.record.data.coitem_id);
+                                    // e.record.set('coitem_status', e.record.data.coitem_status);
+                               // }
+                                
+                                if (e.field == 'item_number' || e.originalValue == e.value) {
+                                    // afterselect handles this...
+                                    return;
+                                }
+                                if (e.field == 'item_descrip1') {
+                                    e.record.set('coitem_memo', e.value);
+                                }
+                                var rate = _this.form.findField('taxzone_rate').getValue();
+                                switch(e.field) {
+                                    case 'coitem_linedisc':
+                                       
+                                        var cp = parseFloat(e.record.data.coitem_custprice);
+                                       
+                                        if (isNaN(cp) || cp == 0.0) {
+                                            break;
+                                        }
+                                        
+                                        var dis = parseFloat(e.value);
+                                       
+                                        if (isNaN(dis)) {
+                                            break;
+                                        }
+                                        
+                                        e.record.set(
+                                            'coitem_price',
+                                            Math.max(0,cp * ((100.0 -  parseInt(e.value))/ 100.0) )  
+                                        );
+                                        
+                                       // donot need to set the subtotal here, coz we will render it automatically
+                                       // e.record.set(
+                                       //     'coitem_subtotal',
+                                       //      e.record.data.coitem_price * 1.0 * e.record.data.coitem_qtyord
+                                       // );
+                                        break;
+                                    
+                                    case  'coitem_price': // SELL@ price
+                            
+                                         var cp = parseFloat(e.record.data.coitem_custprice);
+                                         // list price is < price -- update it..
+                                         if (isNaN(cp) || cp == 0.0 || cp < e.value) {
+                                            e.record.set('coitem_custprice', e.value);
+                                            cp = e.value;
+                                         }
+                                         // update the discount calc.
+                                         
+                                         e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( e.value / cp) * 100.0)));  
+                                         
+                                         // donot need to set the subtotal here, coz we will render it automatically
+                                         //e.record.set(
+                                         //   'coitem_subtotal',
+                                          //   e.record.data.coitem_price * 1.0 * e.record.data.coitem_qtyord
+                                         //);
+                                         break;
+                                    
+                                    case 'coitem_custprice':
+                                        // modified customer price...
+                                        // just modify the discount.. -- leave the entered price the same..
+                                          var sp =  parseFloat(e.record.data.coitem_price);
+                                          var cp = parseFloat(e.value);
+                                          if (isNaN(cp) || cp == 0.0 || cp < e.value) {
+                                                break;
+                                          }
+                                          
+                                         e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  
+                                         
+                                         break;
+                                         
+                                    case 'coitem_custprice_tax':
+                                          var cp = parseFloat(e.value / ( 1 + rate * 1 ));
+                                          var sp =  parseFloat(e.record.data.coitem_price);
+                                          
+                                          if (isNaN(cp) || cp == 0.0) {
+                                                break;
+                                          }
+                                          e.record.set('coitem_custprice', cp);
+                                          e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  
+                                         
+                                         break; 
+                                         
+                                     case  'coitem_price_tax':
+                            
+                                         var cp = parseFloat(e.record.data.coitem_custprice);
+                                         var sp = parseFloat(e.value / ( 1 + rate * 1 ));
+                                         if (isNaN(cp) || cp == 0.0 || cp < sp) {
+                                            e.record.set('coitem_custprice', sp);
+                                            cp = sp;
+                                         }
+                                         e.record.set('coitem_price', sp);
+                                         e.record.set('coitem_linedisc', Math.max(0, 100.0 -  (( sp / cp) * 100.0)));  
+                                         
+                                         break;
+                                  
+                                }
+                                
+                                 
+                                
+                                
+                                var doupdate = function() { 
+                                   if (!e.record.updatePending) {
+                                        Roo.log('doupdate...'  + e.record.data.coitem_linenumber);
+                                        Roo.log(e.record);
+                                        e.record.commit();
+                                        return;
+                                    }
+                                   Roo.log('doupdate pending...'   + e.record.data.coitem_linenumber);
+                                    // wait until it's not peding an update..
+                                    doupdate.defer(500);
+                                }
+                            
+                                if(e.record.data.coitem_id * 1 < 1 && !e.record.isInserting){ // insert
+                                    e.record.isInserting = 1;
+                                    e.record.isUpdating = 0;
+                                    doupdate();
+                                    return;
+                                }
+                                
+                                // update
+                                if(!e.record.isInserting && !e.record.isUpdating){
+                                    e.record.isUpdating = 1;
+                                    doupdate();
+                                    return;
+                                }
+                                
+                                if(!e.record.updatePending){
+                                    e.record.updatePending = 1;
+                                    doupdate();
+                                    return;
+                                }
+                                Roo.log("got to end without doing an update?"  + e.record.data.coitem_linenumber);
+                                
+                            },
+                            beforeedit : function (e)
+                            {
+                                // we can only edit if nothing is assigned to shipping or invoices..
+                                
+                                var rec = e.record
+                            
+                                if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0 || (rec.data.shipitem_shipped - rec.data.coitem_qtyshipped) > 0 ) {
+                                    Roo.MessageBox.alert("Error", "That item has been shipped, has a draft shipment  or invoices - void the shipments/invoices first");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                
+                                if (rec.data.coitem_subnumber * 1 > 0) {
+                                    Roo.log("Edit container event");
+                                    Roo.log(e); // if it's a tab.. 
+                            
+                                    
+                                    switch(e.field) {
+                                        // allow editing of source / destination..
+                                        case 'coitem_shipto_id':
+                                        case 'coitem_location_src':            
+                                            return;
+                                        default : 
+                                            break;
+                                    }
+                                    Roo.MessageBox.alert("Error", "That is a kit item, edit the container.");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                // zero off values..
+                                //if (e.field == 'coitem_qtyord' && rec.data.coitem_qtyord == 0) {
+                                //        e.value ='';
+                                //    }
+                                //    if (e.field == 'coitem_custprice' && rec.data.coitem_qtyord == 0.0) {
+                                //        e.value ='';
+                                //    }
+                                
+                                if (rec.data.item_type == 'K' && e.field == 'item_number') {
+                                    // you can not change the product type on kits' as it messing things up..
+                                    Roo.MessageBox.alert("Error", "That is a kit item,if you need to change it, delete it first.");
+                                    e.cancel = true;
+                                    return;
+                                }
+                                
+                            },
+                            celldblclick : function (_self, rowIndex, columnIndex, e)
+                            {
+                                var rec = this.ds.getAt(rowIndex);
+                                var di = this.cm.getDataIndex(columnIndex);
+                                if (di != 'avail_qty') {
+                                    return;
+                                }
+                                
+                                Pman.Dialog.XtupleInvHistory.show({
+                                    itemsite_item_id_item_number   : rec.data.item_number,
+                                   // itemsite_item_id_item_descript1 : rec.data.item_descrip1,
+                                    location_name : rec.data.coitem_location_src_location_name,
+                                    location_descrip : rec.data.coitem_location_src_location_descrip,
+                                    
+                                    invhist_transdate : _this.form.findField('cohead_targetdate').getValue() 
+                                }); 
+                                
+                            },
+                            rowclass : function (gridview, rowcfg)
+                            {
+                                if (rowcfg.record.data.coitem_status == 'C' &&
+                                    rowcfg.record.data.shipitem_shipped * 1 < 1) {
+                                    
+                                    rowcfg.rowClass = 'strikethrough';
+                                }
+                                 if (rowcfg.record.data.coitem_status == 'X'  ) {
+                                    
+                                    rowcfg.rowClass = 'strikethrough';
+                                }
+                                
+                                if (!rowcfg.record.data.coitem_id) { 
+                                        rowcfg.rowClass = 'dragon-not-saved';
+                                }
+                                
+                                
+                               // Roo.log(rowcfg);
+                            //    shipitem_shipped
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        loadAvail : function() {
+                            
+                            
+                            this.ds.each(function(r) {
+                                
+                                if(!r.data.item_number.length){
+                                    return;
+                                }
+                                
+                                if(typeof(_this.stockcache[r.data.item_number]) != 'undefined'){
+                                
+                                    r.set('avail_qty', _this.stockcache[r.data.item_number].qty);
+                                    if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {
+                                        r.set('coitem_unitcost_in_order_cur', _this.stockcache[r.data.item_number].unitcost);
+                                    }
+                                    return;
+                                }
+                                
+                                var q = [];
+                                
+                                q.push( { 
+                                    item : r.data.item_number, 
+                                    loc: r.data.coitem_location_src_location_name,
+                                    id: r.data.coitem_linenumber + (r.data.coitem_subnumber ? ('.' + r.data.coitem_subnumber) : '')
+                                 } );
+                                 
+                                 new Pman.Request({
+                                    url : baseURL + '/Roo/itemloc',
+                                    method : 'POST',
+                                    params : {
+                                        _availqty : Roo.encode(q),
+                                        curr_name : _this.form.findField('cohead_curr_id').el.dom.value
+                                    },
+                                    success : function(res) 
+                                    {
+                                        for (var i in res.data) {
+                                           _this.stockcache[res.data[i].item] = res.data[i];
+                                        }
+                                        r.set('avail_qty', _this.stockcache[r.data.item_number].qty);
+                                        if (r.data.coitem_unitcost_in_order_cur * 1.0 < 0.1) {
+                                            r.set('coitem_unitcost_in_order_cur', _this.stockcache[r.data.item_number].unitcost);
+                                        }
+                                        //_this.grid.ds.fireEvent("update", _this.grid.ds, r, Roo.data.Record.EDIT);
+                                        return
+                                    }
+                                });
+                            });
+                                
+                                        
+                        },
+                        sm : {
+                            xtype: 'CellSelectionModel',
+                            xns: Roo.grid,
+                            listeners : {
+                                tabend : function (_self)
+                                {
+                                    _this.addItemBtn.fireEvent('click', _this.addItemBtn);
+                                },
+                                beforeeditnext : function (eventdata)
+                                {
+                                    
+                                    return;
+                                    // this does not work, as the reload effect cancels editng.
+                                    var rec = _this.grid.ds.getAt(eventdata.cell[0]);
+                                    if (rec.data.coitem_subnumber *1 < 0 ) {
+                                        return;
+                                    }
+                                    var r = eventdata.cell[0] + 1;
+                                
+                                    while (true) {
+                                        if (r > _this.grid.ds.getCount()-1 ) {
+                                            eventdata.cell = false;
+                                            return;
+                                        }
+                                        rec =  _this.grid.ds.getAt(r);
+                                        if (rec.data.coitem_subnumber *1 < 0 ) {
+                                           eventdata.cell = [ r, eventdata.cell[1] ];
+                                           return;
+                                        }
+                                        r++;
+                                    }
+                                    
+                                    
+                                 
+                                
+                                }
+                            },
+                            enter_is_tab : true
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            emptyMsg : "No Items",
+                            pageSize : 100,
+                            updateSummary : function() {
+                                var f = this;
+                                new Pman.Request({
+                                    url : baseURL + '/Roo/Coitem',
+                                    method : 'GET',
+                                    params : {
+                                        _totals : 1,
+                                        coitem_cohead_id : _this.form.findField('cohead_id').getValue()
+                                    },
+                                    success : function(d) {
+                                        //Roo.log(d);
+                                        f.displayEl.update(String.format(
+                                            "{0} items |  Subtotal: {2} | Tax: {3} | List Discount {4} | Total : {1}{5}",
+                                            d.data.total_qty,
+                                            _this.form.findField('cohead_curr_id').el.dom.value,
+                                            d.data.total_sub,
+                                            d.data.total_tax,
+                                            d.data.total_list_discount,                
+                                            d.data.total_total
+                                        ));
+                                            
+                                    }
+                                });
+                            },
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            new Pman.Request({
+                                                url : baseURL + '/Roo/Cohead',
+                                                method : 'GET',
+                                                params : {
+                                                    _fill_shipto : _this.form.findField('cohead_id').getValue()
+                                                },
+                                                success : function() {
+                                                    _this.grid.footer.onClick('first');
+                                                }
+                                            });
+                                        }
+                                    },
+                                    text : "Fill empty Ship To"
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            Roo.MessageBox.confirm("Confirm", "Are you sure?<BR>"+
+                                                "This will set all the locations to match the Sales Order - and remove all old locations.",
+                                                function (res) {
+                                                    if(res!='yes') {
+                                                        return;
+                                                    
+                                                    }
+                                                    new Pman.Request({
+                                                        url : baseURL + '/Roo/Cohead',
+                                                        method : 'GET',
+                                                        params : {
+                                                            _fill_location : _this.form.findField('cohead_id').getValue(),
+                                                            _location_id : _this.form.findField('cohead_location_src').getValue()
+                                                        },
+                                                        success : function() {
+                                                            _this.grid.footer.onClick('first');
+                                                        }
+                                                    });
+                                            });
+                                            
+                                        }
+                                    },
+                                    text : "Update Location to match S/O"
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        toggle : function (_self, pressed)
+                                        {
+                                            this.setText(pressed ? "Prices exc GST" : "Prices with GST");
+                                            var cm = _this.grid.getColumnModel();
+                                        
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_price_tax'), pressed ? false : true);
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_custprice_tax'), pressed ? false : true);
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_subtotal_tax'), pressed ? false : true);
+                                            
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_price'), pressed ? true : false);
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_custprice'), pressed ? true : false);
+                                            cm.setHidden(cm.getIndexByDataIndex('coitem_subtotal'), pressed ? true : false);
+                                            return;
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.showgstBtn = _self;
+                                        }
+                                    },
+                                    enableToggle : true,
+                                    minWidth : 100,
+                                    text : "Prices with GST"
+                                }
+                            ]
+                        },
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                
+                                    try {
+                                       this.removeAll();
+                                   } catch (e) { }
+                                   
+                                
+                                    if (!_this.data || !_this.data.cohead_id) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    
+                                    o.params.coitem_cohead_id = _this.data.cohead_id;
+                                    o.params._without_list_discount =1;
+                                    //o.params.limit = 999;
+                                
+                                    
+                                },
+                                update : function (_self, rec, operation)
+                                    {
+                                   
+                                   if (operation !=  Roo.data.Record.COMMIT) {
+                                       return;
+                                   }
+                                
+                                   // row has been updated..
+                                   // if the qty + item has been filled in, we should try and save it..
+                                 
+                                    
+                                    var setRecord = function(){
+                                    
+                                         Roo.log("Clearing update?"  + rec.data.coitem_linenumber);
+                                        rec.updatePending = 0;
+                                        if(rec.isInserting){
+                                            rec.isInserting = 0;
+                                            return;
+                                        }
+                                        rec.isUpdating = 0;
+                                
+                                    }
+                                    if (!(rec.data.coitem_itemsite_id * 1) || !(rec.data.coitem_qtyord*1)) {
+                                        setRecord();
+                                        return;
+                                    }
+                                    var     doCommit = function() {
+                                         Roo.log("Sending  data?"  + rec.data.coitem_linenumber);
+                                        
+                                        new Pman.Request({
+                                            url : baseURL+'/Roo/coitem',
+                                            method : 'POST',
+                                            params : rec.data,
+                                            success: function(res)
+                                            {
+                                                try {
+                                                    var row = _this.grid.ds.indexOf(rec);
+                                                    Roo.get(_this.grid.view.getRow(row)).removeClass('dragon-not-saved');
+                                                } catch(e) {
+                                                    Roo.log(e);
+                                                }
+                                                    
+                                                
+                                                 Roo.log("GOT success: "  + rec.data.coitem_linenumber);
+                                                //Roo.log("GOT success");
+                                                // update the data...
+                                                
+                                                if (rec.data.item_type == 'K') {
+                                                     Roo.log("Kit??");
+                                                    _this.grid.ds.load({});
+                                                    
+                                                    return;
+                                                }
+                                                
+                                                // why is this here.??
+                                                
+                                                if (_this.grid.activeEditor) {
+                                                     rec.editing = true;
+                                                     
+                                                     
+                                                 } 
+                                                 
+                                                rec.set('coitem_id', res.data.coitem_id);
+                                                rec.set('coitem_status', res.data.coitem_status);
+                                                 
+                                                
+                                                rec.dirty = false;
+                                                delete rec.modified;
+                                                try {
+                                                    _this.grid.footer.updateSummary();          
+                                                    _this.grid.loadAvail();
+                                                } catch (e) { }
+                                                
+                                
+                                                setRecord();
+                                            },
+                                            failure : function(res)
+                                            {
+                                                setRecord();
+                                                Roo.MessageBox.alert("Error", res.errorMsg ? res.errorMsg : "Error updating");
+                                            }
+                                            
+                                            
+                                        });
+                                      } ; 
+                                   
+                                    
+                                    doCommit();
+                                    
+                                    
+                                    
+                                },
+                                load : function (_self, records, options)
+                                {
+                                    // need to fetch availablity from master data..
+                                    // build a list of what to ask..
+                                
+                                    // query: ITEM CODE - LOCATION
+                                    _this.grid.footer.updateSummary();
+                                    _this.grid.loadAvail.defer(100, _this.grid);
+                                
+                                    
+                                    
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'coitem_linenumber,coitem_subnumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/coitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'coitem_id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'coitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyord'
+                                    },
+                                    {
+                                        'name': 'coitem_unitcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price'
+                                    },
+                                    {
+                                        'name': 'coitem_custprice'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreturned'
+                                    },
+                                    {
+                                        'name': 'coitem_prcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreserved'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                           
+                                            Roo.log("add presed");
+                                             
+                                            // work out last 
+                                            var grid = _this.grid;
+                                            var err = false;
+                                            grid.ds.each(function(r) {
+                                                if (r.data.coitem_qtyord < 1) { 
+                                                    Roo.MessageBox.alert("Error", "you must fill in a quantity for " + r.data.item_number);
+                                                    err = true;
+                                                    return true;
+                                                }
+                                                
+                                            });
+                                            if (err) {
+                                                return;
+                                            }
+                                            
+                                        
+                                        //    var last = 0;
+                                            var last = _this.form.findField('cohead_max_linenumber').getValue();   
+                                            last++; 
+                                            if(last == 99999){
+                                                last++;
+                                            }
+                                            
+                                        
+                                            _this.form.findField('cohead_max_linenumber').setValue(last);    
+                                            
+                                            // this should be getting the previous row..??
+                                             var ct  =    _this.grid.ds.getCount();
+                                             var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;
+                                             
+                                             function lastor(k,d,kk) {
+                                                var def = d ? _this.form.findField(k).el.dom.value : _this.form.findField(k).getValue();
+                                                return lastrow ? lastrow.data[kk] : def;
+                                             }
+                                            
+                                            // uses form defaults or last row value.
+                                            var nr = _this.grid.ds.reader.newRow({
+                                                coitem_linenumber : last,
+                                                item_number : '',
+                                                item_descrip1 : '',
+                                                coitem_qtyord : 0,
+                                                coitem_cohead_id : _this.form.findField('cohead_id').getValue(),
+                                                coitem_qtyshipped : 0,
+                                                coitem_location_src : lastor('cohead_location_src',false, 'coitem_location_src'),
+                                                coitem_location_src_location_name : lastor('cohead_location_src',true, 'coitem_location_src_location_name'),
+                                                coitem_shipto_id    :  lastor('cohead_shipto_id',false, 'coitem_shipto_id'),
+                                                coitem_shipto_id_shipto_name  : lastor('cohead_shipto_id_shipto_name', false, 'coitem_shipto_id_shipto_name'),
+                                                coitem_unitcost_in_order_cur  : 0,
+                                                coitem_taxtype_id : _this.data.default_taxtype_id,
+                                                coitem_taxtype_id_taxtype_name : 'Taxable',
+                                                coitem_status : '',
+                                                avail_qty : 0
+                                                        
+                                            });
+                                            grid.stopEditing();
+                                            grid.ds.insert(grid.ds.getCount(), nr); 
+                                            grid.startEditing(grid.ds.getCount()-1, 1); // type..
+                                            nr.updatePending = 0;
+                                            nr.isUpdating = 0;
+                                            nr.isInserting =0;
+                                            
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.addItemBtn = _self;
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Add",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            var last = _this.form.findField('cohead_max_linenumber').getValue();    
+                                            last++;
+                                            _this.form.findField('cohead_max_linenumber').setValue(last); 
+                                        
+                                            var ct  =    _this.grid.ds.getCount();
+                                            var lastrow = ct ?  _this.grid.ds.getAt(ct-1)  : false;
+                                                 
+                                            function lastor(k,d,kk) {
+                                               var def = d ? _this.form.findField(k).el.dom.value : _this.form.findField(k).getValue();
+                                               return lastrow ? lastrow.data[kk] : def;
+                                            }
+                                            
+                                            var cohead_cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                            var cohead_id = _this.form.findField('cohead_id').getValue();
+                                            
+                                            Pman.Dialog.XtupleSalesProductList.show( {cohead_cust_id : cohead_cust_id, cohead_id : cohead_id} , function(res) {
+                                        
+                                                _this.grid.stopEditing();
+                                        
+                                                if (_this.grid.ds.getCount() > 0) {
+                                                    var lr = _this.grid.ds.getAt(_this.grid.ds.getCount()-1);
+                                                    if (!lr.data.coitem_itemsite_id) {
+                                                        lr.set('coitem_itemsite_id', res.item_itemsite_id_itemsite_id);
+                                                        lr.set('item_number',  res.item_number);
+                                                        lr.set('item_descrip1', res.item_descrip1);                                
+                                                        lr.set('coitem_listprice', res.item_price);                
+                                                        lr.set('coitem_price', res.item_price);                                
+                                                        lr.set('coitem_custprice', res.item_price);                
+                                                        return;
+                                                    }
+                                                }
+                                                
+                                                
+                                                
+                                                var nr = _this.grid.ds.reader.newRow({
+                                                    coitem_linenumber : last,
+                                                    coitem_itemsite_id : res.item_itemsite_id_itemsite_id,
+                                                    item_number : res.item_number,
+                                                    item_descrip1 : res.item_descrip1,
+                                                    coitem_qtyord : 0,
+                                                    coitem_cohead_id : _this.form.findField('cohead_id').getValue(),
+                                                    coitem_qtyshipped : 0,
+                                                    coitem_listprice : res.item_price,
+                                                    coitem_price : res.item_price,
+                                                    coitem_custprice : res.item_price,
+                                                    avail_qty : 0,
+                                                    coitem_location_src : lastor('cohead_location_src',false, 'coitem_location_src'),
+                                                    coitem_location_src_location_name : lastor('cohead_location_src',true, 'coitem_location_src_location_name'),
+                                                    coitem_shipto_id    :  lastor('cohead_shipto_id',false, 'coitem_shipto_id'),
+                                                    coitem_shipto_id_shipto_name  : lastor('cohead_shipto_id_shipto_name', false, 'coitem_shipto_id_shipto_name')
+                                                            
+                                                });
+                                                _this.grid.ds.insert(_this.grid.ds.getCount(), nr); 
+                                        
+                                           }); 
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Find Products",
+                                    icon : rootURL + '/Pman/templates/images/search.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                            // work out last 
+                                            new Pman.Request({
+                                                url : baseURL + '/Roo/coitem',
+                                                mask : 'Loading Data',
+                                                method: 'GET',
+                                                params : {
+                                        
+                                                    _hk_xfer :_this.form.findField('cohead_id').getValue()
+                                                },
+                                                success : function() {
+                                                    _this.grid.ds.load({});
+                                                }
+                                            
+                                            });
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.xferAll  = _self;
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    hidden : true,
+                                    text : "Xfer all stock to HK",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                           var c    = _this.grid.getSelectionModel().getSelectedCell();
+                                           if (!c) {
+                                                Roo.MessageBox.alert("Error", "Select item to show history (you can also double click on the #avail number) ");
+                                                return;
+                                           }
+                                           
+                                            var rec = _this.grid.ds.getAt(c[0]);
+                                        
+                                          Pman.Dialog.XtupleInvHistory.show({
+                                                itemsite_item_id_item_number   : rec.data.item_number,
+                                               // itemsite_item_id_item_descript1 : rec.data.item_descrip1,
+                                                location_name : rec.data.coitem_location_src_location_name,
+                                                location_descrip : rec.data.coitem_location_src_location_descrip,
+                                                
+                                                
+                                                invhist_transdate : _this.form.findField('cohead_targetdate').getValue() 
+                                            }); 
+                                            
+                                           
+                                        }
+                                    },
+                                    text : "Show Inventory History"
+                                },
+                                {
+                                    xtype: 'Separator',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "Apply % Discount of : "
+                                },
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        render : function (_self)
+                                        {
+                                            _this._applyDiscount = _self;
+                                        }
+                                    },
+                                    width : 40
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            var val =  parseFloat(_this._applyDiscount.getValue());
+                                            
+                                            var factor = (100.0 - val)/100.0;
+                                            
+                                            _this.grid.ds.each(function(rec) {
+                                                if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {
+                                                    return;
+                                                }
+                                            
+                                                rec.set('coitem_price', rec.data.coitem_custprice * factor);
+                                                rec.set('coitem_linedisc', val);
+                                                rec.set('coitem_subtotal', rec.data.coitem_price  & rec.data.ordqty);
+                                                rec.commit();
+                                            
+                                            });
+                                            
+                                            
+                                        }
+                                    },
+                                    text : "Apply To All"
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                        
+                                            if (!(1* _this.form.findField('cohead_id').getValue())) {
+                                                Roo.MessageBox.alert("Error", "save the order first");
+                                            }
+                                            
+                                        
+                                           Pman.Dialog.Image.show(
+                                               {
+                                                    timeout : 60000,
+                                                    _url : baseURL+'/Xtuple/Import/SalesOrder',
+                                                    onid : _this.form.findField('cohead_id').getValue()
+                                                
+                                               },
+                                               function (data) {
+                                        
+                                                    Roo.MessageBox.alert("Notice", "Uploaded");
+                                                    _this.grid.footer.onClick('first');
+                                        
+                                               }
+                                           );
+                                        }
+                                    },
+                                    text : "Import"
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             _this.grid.stopEditing();
+                                            // check that no shipments or invoices are done..
+                                            var rc = _this.grid.getSelectionModel().getSelectedCell();
+                                            
+                                            var rec = _this.grid.ds.getAt(rc[0]);
+                                            
+                                            if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {
+                                                Roo.MessageBox.alert("Error", "That item has been shipped or invoices - void the shipments/invoices first");
+                                                return;
+                                            }
+                                           if (rec.data.coitem_subnumber*1  > 0) {
+                                                Roo.MessageBox.alert("Error", "Delete the kit item that that belongs to.");
+                                                return;
+                                            }
+                                            if (!rec.data.coitem_id) {
+                                                _this.grid.ds.remove(rec);
+                                                return;
+                                            }
+                                            function remove()
+                                            {
+                                            
+                                                new  Pman.Request({
+                                                    url : baseURL + '/Roo/coitem',
+                                                    method : 'POST',
+                                                    params : {
+                                                        _delete : rec.data.coitem_id
+                                                    
+                                                    },
+                                                    success : function() {
+                                                        if (rec.data.item_type == 'K') {
+                                                            _this.grid.ds.load({});
+                                                            return;
+                                                        }
+                                                        _this.grid.ds.remove(rec);
+                                                    }
+                                                
+                                                });
+                                            }
+                                            if (rec.data_qtyord * 1 < 1) {
+                                                remove();
+                                            }
+                                            
+                                            Roo.MessageBox.confirm("Confirm", "Are you sure you want to delete that line?", function(r)
+                                            {
+                                                if (r != 'yes') {
+                                                    return;
+                                                }
+                                                remove();
+                                            
+                                            });
+                                        
+                                            
+                                            
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Delete",
+                                    icon : rootURL + '/Pman/templates/images/trash.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             _this.grid.stopEditing();
+                                            // check that no shipments or invoices are done..
+                                            var ids = [];
+                                            _this.grid.ds.each(function(rec) {
+                                            
+                                        
+                                            
+                                                if (rec.data.coitem_qtyshipped > 0 || rec.data.cobill_billed > 0) {
+                                                    //Roo.MessageBox.alert("Error", "That item has been shipped or invoices - void the shipments/invoices first");
+                                                    return;
+                                                }
+                                                if (rec.data.item_type == 'K') {
+                                                    return;
+                                                }
+                                        
+                                               if (rec.data.coitem_subnumber*1  > 0) {
+                                                    //Roo.MessageBox.alert("Error", "Delete the kit item that that belongs to.");
+                                                    return;
+                                                }
+                                                if (!rec.data.coitem_id) {
+                                                    _this.grid.ds.remove(rec);
+                                                    return;
+                                                }
+                                                ids.push(rec.data.coitem_id);
+                                            });
+                                            function remove()
+                                            {
+                                            
+                                                new  Pman.Request({
+                                                    url : baseURL + '/Roo/coitem',
+                                                    method : 'POST',
+                                                    params : {
+                                                        _delete : ids.join(',')
+                                                    
+                                                    },
+                                                    success : function() {
+                                        
+                                                        _this.grid.footer.onClick('first');
+                                                    }
+                                                
+                                                });
+                                            }
+                                        //    if (rec.data_qtyord * 1 < 1) {
+                                        //        remove();
+                                        //    }
+                                            
+                                            Roo.MessageBox.confirm("Confirm", "Are you sure you want to delete everything?", function(r)
+                                            {
+                                                if (r != 'yes') {
+                                                    return;
+                                                }
+                                                remove();
+                                            
+                                            });
+                                        
+                                            
+                                            
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Delete All",
+                                    icon : rootURL + '/Pman/templates/images/trash.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'coitem_linenumber',
+                                header : 'Item#',
+                                width : 40,
+                                renderer : function(v,x,r) {
+                                
+                                    if (r.data.coitem_subnumber * 1 > 0) {
+                                         return String.format('{0}.{1}', v,r.data.coitem_subnumber);
+                                     }
+                                     return String.format('{0}', v);
+                                  }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item Code',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            beforeselect : function (combo, record, index)
+                                            {
+                                              // set _this.data values ..
+                                              var ar = _this.grid.activeEditor.record;
+                                            //  Roo.log('beforeselect');
+                                              
+                                              
+                                              (function() { 
+                                                 //  Roo.log('beforeselect-cb');
+                                                  ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);
+                                                  ar.set('coitem_listprice', record.data.item_listprice);
+                                                  ar.set('coitem_price', record.data.item_price);
+                                                  ar.set('coitem_custprice', record.data.item_price);
+                                                  ar.set('coitem_itemsite_id', record.data.itemsite_id);
+                                                  ar.set('item_number', record.data.itemsite_item_id_item_number);
+                                                 ar.set('item_type', record.data.itemsite_item_id_item_type);
+                                                  ar.set('avail_qty', 0);
+                                                  ar.commit();
+                                              }).defer(100);
+                                              
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'itemsite_item_id_item_number',
+                                        editable : true,
+                                        emptyText : "Select item",
+                                        forceSelection : true,
+                                        hiddenName : 'itemsite_item_id_item_number',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'item_number',
+                                        pageSize : 20,
+                                        qtip : "Select item",
+                                        queryParam : 'query[number]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> ${item_price:toFixed(2)}- {itemsite_item_id_item_descrip1} </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'item_number',
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    o.params.customer_id = _this.form.findField('cohead_cust_id').getValue();
+                                                    o.params['query[cohead_id]'] = _this.form.findField('cohead_id').getValue();
+                                                    //o.params.shipto_cust_id = _this.data.cohead_cust_id;
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'item_number' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/itemsite.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'shipto_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"item_id","type":"int"},"item_number"]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'coitem_location_src',
+                                header : 'From',
+                                width : 75,
+                                renderer : function(v,x,r) { 
+                                    return String.format('{0}', r.data.coitem_location_src_location_name); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            beforeselect : function (combo, record, index)
+                                            {
+                                              // set _this.data values ..
+                                              var ar = _this.grid.activeEditor.record;
+                                              
+                                              
+                                              
+                                              //Roo.log('beforeselect');
+                                             
+                                             /*
+                                              (function() { 
+                                                 //  Roo.log('beforeselect-cb');
+                                                  ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);
+                                                  ar.set('coitem_price', record.data.item_listprice);
+                                                  ar.set('coitem_custprice', record.data.item_price);
+                                                   ar.set('coitem_itemsite_id', record.data.itemsite_id);
+                                                  ar.set('item_number', record.data.itemsite_item_id_item_number);
+                                            
+                                                  ar.commit();
+                                              }).defer(100);
+                                              */
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        alwaysQuery : true,
+                                        displayField : 'location_name',
+                                        editable : true,
+                                        emptyText : "Select location",
+                                        forceSelection : true,
+                                        hiddenName : 'coitem_location_src',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'coitem_location_src_location_name',
+                                        pageSize : 20,
+                                        qtip : "Select item",
+                                        queryParam : 'query[location_name]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b> {location_name}</b> {location_descrip}</div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'location_id',
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    
+                                                    var row = _this.grid.activeEditor.record;
+                                                    
+                                                    o.params['query[item_itemsite_id]'] = row.data.coitem_itemsite_id;
+                                                    // need to know the date to calc the est. delivery time..
+                                                    //o.params['query[avail_when]'] = _this.form.findField('cohead_targetdate').getValue().format('Y-m-d');
+                                                    //o.params.location_netable = 1;
+                                                    o.params['query[cohead_id]'] = _this.form.findField('cohead_id').getValue(); 
+                                                    
+                                                     o.params.location_restrict = 0;
+                                                    o.params._notinternalcompany = 1;
+                                                    
+                                                  //  _this.grid;
+                                                
+                                                //    o.params.itemsite_id = _this.form.findField('cohead_cust_id').getValue();
+                                                    //o.params.shipto_cust_id = _this.data.cohead_cust_id;
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'location_name' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/location.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'shipto_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"location_id","type":"int"},"location_name"]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'coitem_shipto_id',
+                                header : 'To',
+                                width : 75,
+                                renderer : function(v,x,r) { 
+                                    return String.format('{0}:{1}', v, r.data.coitem_shipto_id_shipto_name); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            add : function (combo)
+                                            {
+                                            
+                                               Pman.Dialog.XtupleCustomer.show({ cust_id : _this.form.findField('cohead_cust_id').getValue() }, function(data) {
+                                                    // refresh the data in the pulldown..
+                                                }); 
+                                            },
+                                            beforeselect : function (combo, record, index)
+                                            {
+                                            
+                                                var v = [];
+                                                for(var i = 1; i <4; i++) {
+                                                    _this.data['cohead_shiptoaddress'+  i] = record.data['cntct_addr_id_addr_line'+i];
+                                                }
+                                                _this.form.findField('shipto_address').update();
+                                                
+                                             
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        alwaysQuery : true,
+                                        displayField : 'shipto_name',
+                                        editable : false,
+                                        emptyText : "Select cntct",
+                                        forceSelection : true,
+                                        hiddenName : 'cohead_shipto_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'coitem_shipto_id_shipto_name',
+                                        pageSize : 20,
+                                        qtip : "Select shipto",
+                                        queryParam : 'query[shipto_name]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{shipto_id}:{shipto_addr_id_addr_name}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'shipto_id',
+                                        width : 300,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    o.params.shipto_cust_id = _this.data.cohead_cust_id; 
+                                                    //o.params['query[with_shipinfo]'] = 1;
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'shipto_name' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/shiptoinfo.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'shipto_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"cntct_id","type":"int"},"cntct_name"]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Item Description',
+                                width : '150.00',
+                                renderer : function(v,x,r) { 
+                                
+                                    if (r.data.coitem_memo && r.data.coitem_memo.length) {
+                                        return String.format('{0}', r.data.coitem_memo);
+                                        if (r.data.coitem_memo != v) {
+                                            r.set('item_descrip1', r.data.coitem_memo);
+                                        }
+                                        
+                                    }
+                                    if (v && v.length > 49) {
+                                        return String.format('<span style="color:orange" qtip="line may be too long to print">{0}</span>', v);
+                                    }
+                                    
+                                    return String.format('{0}', v); 
+                                    
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        allowBlank : false
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_status',
+                                header : 'Status',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_qtyord',
+                                header : 'Qty',
+                                width : 40,
+                                renderer : function(v,x,r) { 
+                                    var v = parseInt(v);
+                                    //var aq = parseInt(r.data.avail_qty);
+                                    //aq = isNaN(aq) ? 0 : aq;
+                                   
+                                    var rate = _this.form.findField('taxzone_rate').getValue();
+                                    r.data.coitem_subtotal =  v * r.data.coitem_price;
+                                    r.data.coitem_subtotal_tax = v * r.data.coitem_price * ( 1 + rate * 1);
+                                    return String.format('{0}', v); 
+                                    
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        allowDecimals : false,
+                                        decimalPrecision : 0,
+                                        minValue : 1,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_price',
+                                header : 'Sell @',
+                                width : 70,
+                                renderer : function(v,x,r) { 
+                                
+                                    var rate = _this.form.findField('taxzone_rate').getValue();
+                                    r.data.coitem_subtotal = v * r.data.coitem_qtyord;
+                                    r.data.coitem_subtotal_tax = v * ( 1 + rate * 1 ) * r.data.coitem_qtyord;
+                                    r.data.coitem_price_tax = v * ( 1 + rate * 1 );
+                                    if (parseInt(v) < 1) {
+                                        return String.format('<b style="color:red;">{0}</b>', Roo.util.Format.number(v,3)); 
+                                    }
+                                    
+                                    
+                                    //r.set('coitem_subtotal', v * r.data.coitem_qtyord);
+                                    
+                                    return  String.format('{0}', Roo.util.Format.number(v,3)); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 3,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_price_tax',
+                                header : 'Sell @w/GST',
+                                hidden : true,
+                                width : 70,
+                                renderer : function(v,x,r) { 
+                                    
+                                    if (parseInt(v) < 1) {
+                                        return String.format('<b style="color:red;">{0}</b>', Roo.util.Format.number(v,3)); 
+                                    }
+                                    
+                                    return  String.format('{0}', Roo.util.Format.number(v,3)); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 3,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_linedisc',
+                                header : 'Disc%',
+                                width : 50,
+                                renderer : function(v,x,r) { 
+                                
+                                    // coitem_custprice = coitem_price * ((100 - coitem_disc)/ 100) 
+                                    
+                                    //                      12 * (( 100 - 0) / 100)
+                                    // coitem_custprice / coitem_price = ((100 - coitem_disc)/ 100) 
+                                    // 100 - ((coitem_custprice / coitem_price) * 100)  = coitem_disc
+                                    //                             100 -  97 =        100 -3 
+                                
+                                   // r.data.coitem_linedisc = 100 - (
+                                    //           (parseFloat(r.data.coitem_custprice) /
+                                     //               parseFloat(r.data.coitem_price)
+                                       //        ) * 100.00);
+                                    var fl = parseFloat(r.data.coitem_linedisc);
+                                    if ( isNaN(fl) || fl == 0.0 || r.data.coitem_price > r.data.coitem_custprice)  {
+                                        return '';
+                                    }
+                                    return  String.format('<span style="color:green">{0}%</span>', Roo.util.Format.number( r.data.coitem_linedisc,2)); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 2,
+                                        maxValue : 100,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_custprice',
+                                header : 'List Price',
+                                width : 70,
+                                renderer : function(v,x,r) { 
+                                    
+                                    var rate = _this.form.findField('taxzone_rate').getValue();
+                                    r.data.coitem_custprice_tax = v * ( 1 + rate * 1 );
+                                    
+                                    var tip = 'No WRP available';
+                                    if ((r.data.coitem_wrpprice * 1) > 0) {
+                                        tip = "WRP : " + Roo.util.Format.number(r.data.coitem_wrpprice,3);
+                                    }
+                                    // less than zero, show as red..
+                                    if (parseFloat(v) < 1) {
+                                        return String.format('<b qtip="{1}" style="color:red;">{0}</b>', 
+                                            Roo.util.Format.number(v,3), tip); 
+                                    }
+                                    if (r.data.customer_price_each != v) {
+                                          return String.format('<b qtip="{1}" style="color:pink;">{0}</b>', 
+                                            Roo.util.Format.number(v,3), 
+                                            "List Price = " +  Roo.util.Format.number(r.data.customer_price_each,3)
+                                        ); 
+                                    }
+                                    
+                                    
+                                    
+                                    //r.data.coitem_subtotal = v * r.data.coitem_qtyord;
+                                    
+                                    //r.set('coitem_subtotal', v * r.data.coitem_qtyord);
+                                    
+                                    return  String.format('<span qtip="{1}">{0}</span>', Roo.util.Format.number(v,3), tip); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 3,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_custprice_tax',
+                                header : 'List Price w/GST',
+                                hidden : true,
+                                width : 70,
+                                renderer : function(v,x,r) { 
+                                    var rate = _this.form.findField('taxzone_rate').getValue();
+                                    var tip = 'No WRP available';
+                                    if ((r.data.coitem_wrpprice * 1) > 0) {
+                                        tip = "WRP : " + Roo.util.Format.number(r.data.coitem_wrpprice,3);
+                                    }
+                                    
+                                    if (parseFloat(v) < 1) {
+                                        return String.format('<b qtip="{1}" style="color:red;">{0}</b>', 
+                                            Roo.util.Format.number(v,3), tip); 
+                                    }
+                                    if (r.data.customer_price_each != v) {
+                                          return String.format('<b qtip="{1}" style="color:pink;">{0}</b>', 
+                                            Roo.util.Format.number(v,3), 
+                                            "List Price = " +  Roo.util.Format.number(r.data.customer_price_each * ( 1 + rate * 1 ),3)
+                                        ); 
+                                    }
+                                    
+                                    return  String.format('<span qtip="{1}">{0}</span>', Roo.util.Format.number(v,3), tip); 
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            focus : function (_self)
+                                            {
+                                                if (this.value == 0.0) {
+                                                    this.el.dom.value = '';
+                                                }
+                                            }
+                                        },
+                                        decimalPrecision : 3,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_subtotal',
+                                header : 'SubTotal',
+                                width : 70,
+                                renderer : function(v) {
+                                
+                                    if (parseInt(v) < 1) {
+                                        return String.format('<b style="color:red;">{0}</b>', Roo.util.Format.number(v,2)); 
+                                    }
+                                
+                                    
+                                
+                                 return Roo.util.Format.number( v, 2);
+                                  }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_subtotal_tax',
+                                header : 'SubTotal w/GST',
+                                hidden : true,
+                                width : 70,
+                                renderer : function(v,x,r) { 
+                                   
+                                    if (parseInt(v) < 1) {
+                                        return String.format('<b style="color:red;">{0}</b>', Roo.util.Format.number(v,2)); 
+                                    }
+                                    
+                                    return  String.format('{0}', Roo.util.Format.number(v,2)); 
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_unitcost_in_order_cur',
+                                header : 'Unit Cost',
+                                width : 50,
+                                renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_taxtype_id',
+                                header : 'Taxed',
+                                width : 50,
+                                renderer : function(v,x,r) { return String.format('{0}', r.data.coitem_taxtype_id_taxtype_name); },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        allowBlank : false,
+                                        displayField : 'taxtype_name',
+                                        editable : false,
+                                        emptyText : "Select Tax Type",
+                                        forceSelection : true,
+                                        hiddenName : 'coitem_taxtype_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'coitem_taxtype_id_taxtype_name',
+                                        pageSize : 20,
+                                        qtip : "Select taxtype",
+                                        queryParam : 'query[taxtype_id]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{taxtype_name}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        valueField : 'taxtype_id',
+                                        width : 40,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                    
+                                                    
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'taxtype_name' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/taxtype.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'taxtype_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"taxtype_id","type":"int"},"taxtype_name"]
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'avail_qty',
+                                header : '#avail',
+                                width : 50,
+                                renderer : function(v,x,r) { 
+                                
+                                    var oq  = parseInt(r.data.coitem_qtyord);
+                                    var aq = parseInt(r.data.avail_qty);
+                                    var sq = parseInt(r.data.coitem_qtyshipped);
+                                    aq = isNaN(aq) ? 0 : aq;
+                                    oq = isNaN(oq) ? 0 : oq;
+                                    sq = isNaN(sq) ? 0 : sq;
+                                    
+                                    var unshipped = oq - sq;
+                                    
+                                    if ( aq < 0 || (unshipped > 0  &&  aq < unshipped))  {
+                                       return String.format('<b style="color:red;">{0}</b>', parseInt(aq));
+                                    }
+                                     
+                                    return String.format('{0}', aq); 
+                                    
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'shipitem_shipped',
+                                header : '#reserved',
+                                width : 50,
+                                renderer : function(v,x,r) { 
+                                
+                                    
+                                    var vv = parseInt(v);
+                                    vv = isNaN(vv) ? 0 : vv;
+                                    
+                                    var ov = parseInt(r.data.coitem_qtyord);
+                                    ov = isNaN(ov) ? 0 : ov;
+                                    
+                                    var qs = parseInt(r.data.coitem_qtyshipped);
+                                    qs = isNaN(qs) ? 0 : qs;
+                                    
+                                    
+                                    
+                                    if (vv < ov) {
+                                        // not enough reserved yet.
+                                        return String.format('<b style="background-color:red;color:yellow">{0}</b>', vv - qs);
+                                    }
+                                    
+                                    return String.format('{0}', vv -  qs); 
+                                    
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_qtyshipped',
+                                header : '#shipped',
+                                width : 50,
+                                renderer : function(v,x,r) { 
+                                    
+                                    var vv = parseInt(v);
+                                    vv = isNaN(vv) ? 0 : vv;
+                                    
+                                    var ov = parseInt(r.data.coitem_qtyord);
+                                    ov = isNaN(ov) ? 0 : ov;
+                                    
+                                
+                                    if (vv != ov) {
+                                        // not enought shipped.
+                                        // or too many shipped.
+                                        return String.format('<b style="background-color:red;color:yellow">{0}</b>',  vv);
+                                    }
+                                
+                                    
+                                    
+                                    return String.format('{0}', vv); 
+                                    
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'cobill_billed',
+                                header : '#invoiced',
+                                width : 50,
+                                renderer : function(v,x,r) { 
+                                    
+                                    var vv = parseInt(v);
+                                    vv = isNaN(vv) ? 0 : vv;
+                                    
+                                    var ov = parseInt(r.data.coitem_qtyord);
+                                    ov = isNaN(ov) ? 0 : ov;
+                                    
+                                
+                                    if (vv !=ov) {
+                                            return String.format('<b style="background-color:red;color:yellow">{0}</b>', vv); 
+                                    }
+                                    return String.format('{0}', vv); 
+                                    
+                                }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function (_self)
+                        {
+                            _this.shipinvtab = _self;
+                        }
+                    },
+                    region : 'center',
+                    title : "Shipments / Invoices",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.shippanel = this;
+                                        if (_this.shipgrid) {
+                                            _this.shipgrid.ds.load({});
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'north',
+                                tableName : 'shiphead',
+                                title : "shiphead",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.shipgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.shippanel.active) {
+                                               this.ds.load({});
+                                            }
+                                        },
+                                        rowdblclick : function (_self, rowIndex, e)
+                                        {
+                                            var rec = this.ds.getAt(rowIndex);
+                                            if (!rec.json.shiphead_shipdate.length) {
+                                                 Roo.MessageBox.alert("Error", "You can not edit voided shipments, create a new one, and use the restore feature");
+                                                 return;
+                                             }
+                                        
+                                           Pman.Dialog.XtupleShipment.show({
+                                                shiphead_id : rec.data.shiphead_id
+                                        
+                                            }, function() {
+                                                _self.ds.load({});
+                                            
+                                            });
+                                           
+                                        }
+                                    },
+                                    autoExpandColumn : 'shiphead_shipvia',
+                                    loadMask : true,
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, options)
+                                            {
+                                                 options.params = options.params || {};
+                                                 options.params.shiphead_order_id = _this.form.findField('cohead_id').getValue() * 1;
+                                                if (options.params.shiphead_order_id < 1) {
+                                                    return false;
+                                                }
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'shiphead_shipvia', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/shiphead.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'shiphead_number',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'shiphead_shipvia',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'shiphead_shipdate',
+                                                    'type': 'date'
+                                                },
+                                                {
+                                                    'name': 'shiphead_sfstatus'
+                                                },
+                                                {
+                                                    'name': 'shiphead_tracknum',
+                                                    'type': 'string'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                         var sel  = _this.shipgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a shipment");
+                                                            return;
+                                                        }
+                                                        if (sel.data.shiphead_shipped) {
+                                                            Roo.MessageBox.alert("Error", "Shipment is already confirmed");
+                                                            return;
+                                                        }
+                                                        
+                                                        
+                                                        // check current status of shipment..
+                                                        
+                                                            
+                                                        new Pman.Request({ 
+                                                               mask : 'Sending',
+                                                            url : baseURL + '/Roo/shiphead',
+                                                            method : 'POST',
+                                                            timeout : 90000,
+                                                            params : {
+                                                                shiphead_id : sel.data.shiphead_id,
+                                                                _confirm : 1
+                                                            },
+                                                            success : function() {
+                                                                _this.shipgrid.ds.load({});
+                                                            }
+                                                        });
+                                                             
+                                                         
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Confirm Shipment",
+                                                icon : rootURL + '/Pman/templates/images/lock.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                         var sel  = _this.shipgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a shipment");
+                                                            return;
+                                                        }
+                                                    
+                                                        
+                                                        // check current status of shipment..
+                                                        
+                                                            
+                                                       new Pman.Download({
+                                                            url : baseURL + '/Roo/shiphead',
+                                                            method : 'GET',
+                                                            params : {
+                                                               _download :sel.data.shiphead_id
+                                                                 
+                                                            }
+                                                        });
+                                                             
+                                                         
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Download (as xls)",
+                                                icon : rootURL + '/Pman/templates/images/save.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                        var sel  = _this.shipgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a shipment");
+                                                            return;
+                                                        }
+                                                        // check current status of shipment..
+                                                     
+                                                            new Pman.Download({
+                                                                url : baseURL + '/Xtuple/Print',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    template : 'picking-slip',
+                                                                    param : "shiphead_id:integer='" + sel.data.shiphead_id + "'",
+                                                                    filename : 'picking-slip-' + sel.data.shiphead_number
+                                                                },
+                                                                success : function() {
+                                                    
+                                                                }
+                                                            })
+                                                                
+                                                                
+                                                       
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Print Picking Slip",
+                                                icon : rootURL + '/Pman/templates/images/pdf.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                        var sel  = _this.shipgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a shipment");
+                                                            return;
+                                                        }
+                                                        // check current status of shipment..
+                                                    
+                                                            new Pman.Download({
+                                                                url : baseURL + '/Xtuple/Print',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    template : 'delivery-note-',
+                                                                    param : "shiphead_id:integer='" + sel.data.shiphead_id + "'",
+                                                                    filename : 'delivery-note-' + sel.data.shiphead_number
+                                                                },
+                                                                success : function() {
+                                                    
+                                                                }
+                                                            })
+                                                                
+                                                                
+                                                       
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Print Delivery Note",
+                                                icon : rootURL + '/Pman/templates/images/pdf.gif'
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {   
+                                                        if (!_this.form.findField('cohead_id').getValue()) {
+                                                            Roo.MessageBox.alert("Error", "Save Order first");
+                                                            return;
+                                                        }
+                                                        var rv = _this.form.getFieldValues();
+                                                        
+                                                        Pman.Dialog.XtupleShipmentNew.show({
+                                                                shiphead_order_id : rv.cohead_id,
+                                                                shiphead_shipdate :  _this.form.findField('cohead_targetdate').getValue().format('Y-m-d')
+                                                            },
+                                                            function() { 
+                                                                 _this.shipgrid.ds.load({});
+                                                            }
+                                                        );
+                                                    },
+                                                    render : function (_self)
+                                                    {
+                                                      _this.addShipmentBtn = _self;
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        var sel  = _this.shipgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a shipment");
+                                                            return;
+                                                        }
+                                                        // check current status of shipment..
+                                                        
+                                                        var msg = sel.data.shiphead_shipped ? 
+                                                            "Are you sure you want to un-confirm that shipment? - It will remove items from unposted invoices" : 
+                                                            "Are you sure you want to void that shipment?";
+                                                        
+                                                        Roo.MessageBox.confirm("Are you sure", msg,
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                                new Pman.Request({
+                                                                    mask : 'Sending',
+                                                                     timeout : 90000,
+                                                                    url : baseURL + '/Roo/shiphead',
+                                                                    method : 'POST',
+                                                                    
+                                                                    params : {
+                                                                        shiphead_id : sel.data.shiphead_id,
+                                                                        _void : 1
+                                                                    },
+                                                                    success : function() {
+                                                                        _this.shipgrid.ds.load({});
+                                                                    }
+                                                                })
+                                                                
+                                                            }
+                                                        );
+                                                                
+                                                                
+                                                        
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Void / Unconfirm",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'shiphead_number',
+                                            header : 'number',
+                                            width : 80,
+                                            renderer : function(v,x,r) {
+                                                if (r.json.shiphead_shipdate.length) {
+                                                     return String.format('{0}', v); 
+                                                 }
+                                                 return String.format('<s>{0}</s>', v); 
+                                             }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'shiphead_location_id_location_name',
+                                            header : 'From Location',
+                                            width : 100,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'shiphead_shipto_id_shipto_name',
+                                            header : 'Ship to',
+                                            width : 100,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            header : 'shipdate',
+                                            width : 75,
+                                            dataIndex : 'shiphead_shipdate',
+                                            renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'shiphead_sfstatus',
+                                            header : 'Status',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                            
+                                            
+                                            
+                                              
+                                                if (r.json.shiphead_shipdate.length) {
+                                                
+                                                    if (r.json.shiphead_shipped) {
+                                                        return "Confirmed";
+                                                    }
+                                                
+                                                     return '<span style="color:red">Draft</span>';
+                                                }
+                                                 
+                                                return 'VOID';
+                                               
+                                            
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            header : 'shipvia',
+                                            width : 200,
+                                            dataIndex : 'shiphead_shipvia',
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            header : 'tracknum',
+                                            width : 200,
+                                            dataIndex : 'shiphead_tracknum',
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        }
+                                    ]
+                                }
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.invpanel = this;
+                                        if (_this.invgrid) {
+                                            _this.invgrid.ds.load({});
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'cobmisc',
+                                title : "Invoices",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.invgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.invpanel.active) {
+                                               this.ds.load({});
+                                            }
+                                        },
+                                        rowdblclick : function (_self, rowIndex, e)
+                                        {
+                                        
+                                            var ri = this.ds.getAt(rowIndex);
+                                            if ( ri.data.cobmisc_id < 0) { // skip summary row..
+                                                return;
+                                            }
+                                            var rv = _this.form.getFieldValues();
+                                           Pman.Dialog.XtupleInvoice.show({
+                                                cobmisc_id : ri.data.cobmisc_id,
+                                                // below parms for add credit memo
+                                                cmdata : {
+                                                    cm_cust_id : rv.cohead_cust_id,
+                                                    cm_cust_id_cust_name : rv.cohead_cust_id_cust_name,
+                                                    cm_curr_id : rv.cohead_curr_id,
+                                                    cm_curr_id_curr_name : rv.cohead_curr_id_curr_name,
+                                                    cm_terms_id : rv.cohead_terms_id,
+                                                    cm_terms_id_terms_descrip : rv.cohead_terms_id_terms_descrip,
+                                                    cm_salesrep_id : rv.cohead_salesrep_id,
+                                                    cm_salesrep_id_salesrep_name : rv.cohead_salesrep_id_salesrep_name,
+                                                    cm_docdate : new Date(),
+                                                    cm_taxzone_id : rv.cohead_taxzone_id,
+                                                    cm_taxzone_id_taxzone_descrip : rv.cohead_taxzone_id_taxzone_descrip,
+                                                    cm_billto_cntct_id : rv.cohead_billto_cntct_id,
+                                                    cm_billto_cntct_id_cntct_name : rv.cohead_billto_cntct_id_cntct_name,
+                                                    cm_location_src : rv.cohead_location_src,
+                                                    cm_location_src_location_name : rv.cohead_location_src_location_name,
+                                                    cm_billto_address : rv.billto_address
+                                                }
+                                            },
+                                                function() { 
+                                                 _this.invgrid.ds.load({});
+                                            });
+                                           
+                                        }
+                                    },
+                                    autoExpandColumn : 'invchead_invcnumber',
+                                    loadMask : true,
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, options)
+                                            {
+                                            
+                                                options.params = options.params || {};
+                                                options.params.cobmisc_cohead_id = _this.form.findField('cohead_id').getValue() * 1;
+                                                if (options.params.cobmisc_cohead_id < 1) {
+                                                    return false;
+                                                }
+                                                
+                                                options.params._with_other_payment = 1;
+                                                //options.params['query[invchead_ordernumber]']  = _this.form.findField('cohead_number').getValue()
+                                                
+                                            },
+                                            load : function (_self, records, options)
+                                            {
+                                                var total = 0;
+                                                var done = 0;
+                                                var totalic = 0.0;
+                                                var totalfreight = 0.0;    
+                                                var totalmisc = 0.0;        
+                                                var totaltax = 0.0;        
+                                               
+                                                Roo.each(records, function(r)
+                                                {
+                                                    if(r.data.cobmisc_id > 1){
+                                                        done += parseInt(r.data.cobmisc_qty);
+                                                        totalic += parseFloat(r.data.cobmisc_itemcost).toFixed(2)*1;        
+                                                        totalmisc += parseFloat(r.data.cobmisc_misc).toFixed(2)*1;        
+                                                        totalfreight += parseFloat(r.data.cobmisc_freight).toFixed(2)*1;                
+                                                        totaltax += parseFloat(r.data.cobmisc_tax).toFixed(2)*1;                
+                                                        total = parseInt(r.data.cobmisc_total_qty);
+                                                    }
+                                                   
+                                                });
+                                                
+                                                _this.shipinvtab.layout.getRegion('center').getPanel(0).setTitle(
+                                                    (total == done) ?
+                                                         "Invoices (Complete)" : 
+                                                        ("Invoices prepared for " +    done + '/' + total)
+                                                );
+                                            
+                                                
+                                                var frtotal = (parseFloat(_this.form.findField('cohead_freight').getValue())  - totalfreight).toFixed(2);
+                                                var misctotal = (parseFloat(_this.form.findField('cohead_misc').getValue()) - totalmisc).toFixed(2);
+                                                var ictotal =  (parseFloat(_this.form.findField('cohead_subtotal').getValue()) - totalic).toFixed(2);
+                                                var taxtotal =  (parseFloat(_this.form.findField('cohead_tax').getValue())  - totaltax).toFixed(2);
+                                                var remtotal = frtotal*1 + misctotal*1 + ictotal*1 + taxtotal*1;
+                                                
+                                                var nr = this.reader.newRow({
+                                                    cobmisc_id : -1,
+                                                    cobmisc_invchead_id_invchead_invcnumber : "Total Remaining",
+                                                    cobmisc_qty : total - done,
+                                                    cobmisc_freight :frtotal,
+                                                    cobmisc_misc : misctotal,        
+                                                    cobmisc_itemcost  : ictotal,             
+                                                    cobmisc_tax : taxtotal,
+                                                    cobmisc_total : remtotal
+                                            
+                                                    
+                                                });
+                                                // do we need to add it somehow??
+                                                _this.invgrid.ds.add(nr);
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'invchead_invcnumber', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/cobmisc.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {
+                                                    'name': 'invchead_invcnumber',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invchead_invcdate',
+                                                    'type': 'date'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                    
+                                                         var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a invoice");
+                                                            return;
+                                                        }
+                                                        // check current status of shipment..
+                                                        
+                                                        Roo.MessageBox.confirm("Are you sure", "Are you sure you want to Post that invoice?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                                new Pman.Request({
+                                                                   mask : 'Sending',
+                                                                    url : baseURL + '/Roo/cobmisc',
+                                                                    method : 'POST',
+                                                                    params : {
+                                                                        cobmisc_id : sel.data.cobmisc_id,
+                                                                        _post : 1
+                                                                    },
+                                                                    success : function() {
+                                                                        _this.invgrid.ds.load({});
+                                                                    }
+                                                                })
+                                                                
+                                                            }
+                                                        );
+                                                                
+                                                                
+                                                       
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Post Invoice",
+                                                icon : rootURL + '/Pman/templates/images/lock.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                cls : 'x-btn-text-icon',
+                                                text : "Print",
+                                                icon : rootURL + '/Pman/templates/images/pdf.gif',
+                                                menu : {
+                                                    xtype: 'Menu',
+                                                    xns: Roo.menu,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function ()
+                                                                {
+                                                                
+                                                                     var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                                _print : 1
+                                                                            },
+                                                                            success : function() {
+                                                                
+                                                                            }
+                                                                        })
+                                                                            
+                                                                            
+                                                                   
+                                                                }
+                                                            },
+                                                            text : "Print Standard Invoice"
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                
+                                                                     var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                                _print : 'cn'
+                                                                                
+                                                                            },
+                                                                            success : function() {
+                                                                
+                                                                            }
+                                                                        })
+                                                                            
+                                                                          
+                                                                }
+                                                            },
+                                                            text : "Print Chinese Invoice With GST in line item",
+                                                            hidden : !(baseURL.match(/(hk\.php|cn\.php)$/))
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                
+                                                                     var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                                _print : 'cn-gst'
+                                                                                
+                                                                            },
+                                                                            success : function() {
+                                                                
+                                                                            }
+                                                                        })
+                                                                            
+                                                                          
+                                                                }
+                                                            },
+                                                            text : "Print Chinese Invoice",
+                                                            hidden : !(baseURL.match(/(hk\.php|cn\.php)$/))
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                
+                                                                     var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                                _print : 'au-gst'
+                                                                                
+                                                                            },
+                                                                            success : function() {
+                                                                
+                                                                            }
+                                                                        })
+                                                                            
+                                                                          
+                                                                }
+                                                            },
+                                                            text : "Print Aus - GST included Invoice",
+                                                            hidden : !(baseURL.match(/au\.php$/))
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                  var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                
+                                                                                _print : 'au-net',
+                                                                               ts: Math.random()
+                                                                            }
+                                                                        })
+                                                                
+                                                                
+                                                                }
+                                                            },
+                                                            text : "Print Bambini Pronto Invoice",
+                                                            hidden : !(baseURL.match(/au\.php$/))
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                
+                                                                     var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if (!sel.data.cobmisc_invchead_id) {
+                                                                        Roo.MessageBox.alert("Error", "Invoice has not been posted");
+                                                                        return;
+                                                                    }
+                                                                    // check current status of shipment..
+                                                                
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Roo/invchead',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                invchead_id : sel.data.cobmisc_invchead_id,
+                                                                                _print : 'au-proforma'
+                                                                                
+                                                                            },
+                                                                            success : function() {
+                                                                
+                                                                            }
+                                                                        })
+                                                                            
+                                                                          
+                                                                }
+                                                            },
+                                                            text : "Print Bambini Pro Forma Invoice",
+                                                            hidden : !(baseURL.match(/au\.php$/))
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    Pman.Dialog.XtupleDiscountOfInvoice.show({invchead_id : sel.data.cobmisc_invchead_id}, function(){
+                                                                
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Print Shipping / Commercial Invoice",
+                                                            hidden : !( baseURL.match(/au\.php$/))
+                                                        }
+                                                    ]
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                cls : 'x-btn-text-icon',
+                                                text : "Tools",
+                                                icon : Roo.rootURL + 'images/default/tree/leaf.gif',
+                                                menu : {
+                                                    xtype: 'Menu',
+                                                    xns: Roo.menu,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function(_self,e)
+                                                                    {
+                                                                    
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel || sel.data.cobmisc_id < 1) {
+                                                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                                                        return;
+                                                                    }
+                                                                    if(!sel.data.cobmisc_posted){
+                                                                        Roo.MessageBox.alert("Error", "This invoice has not been posted!");
+                                                                        return;
+                                                                    }
+                                                                    if(sel.data.cobmisc_outstanding == 0){
+                                                                        Roo.MessageBox.alert("Error", "There is no any outstanding of this invoice!");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                    if(!cust_id){
+                                                                        return;
+                                                                    }
+                                                                    var data = {
+                                                                        cashrcpt_amount : sel.data.cobmisc_outstanding,
+                                                                        cashrcpt_cust_id : cust_id,
+                                                                        cashrcpt_aropen_id : sel.data.cobmisc_aropen_id_aropen_id,
+                                                                        cashrcpt_distdate : new Date(),
+                                                                        cashrcpt_fundstype : 'C',
+                                                                        cashrcpt_curr_id : sel.data.cobmisc_curr_id_curr_id,
+                                                                        cashrcpt_curr_id_curr_name : sel.data.cobmisc_curr_id_curr_name,
+                                                                        cashrcpt_usecustdeposit : true,
+                                                                        cashrcpt_docdate : new Date(),
+                                                                        cashrcpt_salescat_id : -1,
+                                                                        cashrcpt_applydate : new Date(),
+                                                                        cashrcpt_discount : 0
+                                                                    };
+                                                                    Pman.Dialog.XtupleReceivePayment.show( data , function() {
+                                                                        _this.invgrid.ds.load({});
+                                                                    }); 
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Receive Payment",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function(_self,e)
+                                                                {
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel || sel.data.cobmisc_cobapply_aropen_id < 1) {
+                                                                        Roo.MessageBox.alert("Error", "Select a credit memo");
+                                                                        return;
+                                                                    }
+                                                                    if(!sel.data.cobmisc_posted){
+                                                                        Roo.MessageBox.alert("Error", "The invoice that credit memo has been applied to has been not posted");
+                                                                        return;
+                                                                    }
+                                                                    var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                    if(!cust_id){
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    if(!sel.data.cobmisc_outstanding || sel.data.cobmisc_outstanding == 0){
+                                                                        Roo.MessageBox.alert("Error", "The amount of this credit memo is 0!");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    var d = _this.form.getFieldValues();
+                                                                    
+                                                                    var data = {
+                                                                        'checkhead_recip_id' : cust_id,
+                                                                        'checkhead_recip_type' : 'C',
+                                                                        'checkhead_checkdate' : new Date(),
+                                                                        'checkhead_amount' : sel.data.cobmisc_outstanding,
+                                                                        'remaining_total' : sel.data.cobmisc_outstanding,
+                                                                        'checkhead_curr_id' : d.cohead_curr_id,
+                                                                        'checkhead_curr_id_curr_name' : d.cohead_curr_id_curr_name,
+                                                                        'checkhead_misc' : true,
+                                                                        'aropen_id' : sel.data.cobmisc_cobapply_aropen_id,
+                                                                       'cmhead_number' : sel.data.cobmisc_invchead_id_invchead_invcnumber,
+                                                                       'cust_name' : d.cohead_cust_id_cust_name,
+                                                                       '_create_and_post' : 1
+                                                                
+                                                                    };
+                                                                    
+                                                                    
+                                                                    Pman.Dialog.XtupleMiscellaneousCheck.show( data , function() {
+                                                                        _this.invgrid.ds.load({});
+                                                                   }); 
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Issue Refund",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function(_self,e)
+                                                                {
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel || sel.data.cobmisc_cashrcpt_id * 1 < 1) {
+                                                                        Roo.MessageBox.alert("Error", "Select a Receive Payment");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    Roo.MessageBox.confirm("Confirm", "Voiding receipt will mean you will have to re-enter the receipt refund - " + 
+                                                                                    "please take note of the details so you can enter it again correctly later.", function(r) {
+                                                                                            
+                                                                        if (r !='yes') {
+                                                                            return;
+                                                                        }
+                                                                        new Pman.Request({
+                                                                            url : baseURL + '/Roo/cashrcpt',
+                                                                            method : 'POST',
+                                                                            params : {
+                                                                                cashrcpt_id : sel.data.cobmisc_cashrcpt_id,
+                                                                                _void : 1
+                                                                            },
+                                                                            success : function() 
+                                                                            {
+                                                                                _this.invgrid.ds.load({});
+                                                                            
+                                                                            }
+                                                                        });
+                                                                    
+                                                                   })
+                                                                    
+                                                                     
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Void Receive",
+                                                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function(_self,e)
+                                                                {
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel || sel.data.cobmisc_checkhead_id * 1 < 1) {
+                                                                        Roo.MessageBox.alert("Error", "Select a Miscellaneours Check");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    Roo.MessageBox.confirm("Confirm", "Voiding refund will mean you will have to re-enter the receipt refund - " + 
+                                                                                    "please take note of the details so you can enter it again correctly later.", function(r) {
+                                                                                            
+                                                                        if (r !='yes') {
+                                                                            return;
+                                                                        }
+                                                                        new Pman.Request({
+                                                                            url : baseURL + '/Roo/checkhead',
+                                                                            method : 'POST',
+                                                                            params : {
+                                                                                checkhead_id : sel.data.cobmisc_checkhead_id,
+                                                                                _voidPosted : 1
+                                                                            },
+                                                                            success : function() 
+                                                                            {
+                                                                                _this.invgrid.ds.load({});
+                                                                            
+                                                                            }
+                                                                        });
+                                                                    
+                                                                   })
+                                                                    
+                                                                     
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Void Refund",
+                                                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function(_self,e)
+                                                                {
+                                                                    var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                                    if (!sel || sel.data.cobmisc_cobapply_aropen_id < 1) {
+                                                                        Roo.MessageBox.alert("Error", "Select a credit memo");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    if(sel.data.cobmisc_posted){
+                                                                        Roo.MessageBox.alert("Error", "You cann't void this credit memo, since the invoice that credit memo has been applied to has been posted");
+                                                                        return;
+                                                                    }
+                                                                    
+                                                                    if (sel.data.cobmisc_cobapply_id < 1) {
+                                                                        Roo.MessageBox.alert("Error", "invaild credit memo");
+                                                                        return;
+                                                                    }
+                                                                    Roo.MessageBox.confirm("Confirm", "Are you sure want to void this applied credit memo, " + 
+                                                                                "it will also void all the check that belongs to this credit memo ", function(r) {
+                                                                                            
+                                                                        if (r !='yes') {
+                                                                            return;
+                                                                        }
+                                                                        new Pman.Request({
+                                                                            url : baseURL + '/Roo/cobapply',
+                                                                            method : 'POST',
+                                                                            params : {
+                                                                                _delete : sel.data.cobmisc_cobapply_id,
+                                                                                _void : 1
+                                                                            },
+                                                                            success : function() 
+                                                                            {
+                                                                                _this.invgrid.ds.load({});
+                                                                            
+                                                                            }
+                                                                        });
+                                                                    
+                                                                   })
+                                                                     
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Void Credit Memo",
+                                                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                                                        }
+                                                    ]
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                    
+                                                        if (!_this.form.findField('cohead_id').getValue()) {
+                                                            Roo.MessageBox.alert("Error", "Save Order first");
+                                                            return;
+                                                        }
+                                                        
+                                                        var rv = _this.form.getFieldValues();
+                                                        
+                                                       
+                                                       Pman.Dialog.XtupleInvoice.show({
+                                                            cobmisc_cohead_id : rv.cohead_id,
+                                                            cobmisc_shipdate :  _this.form.findField('cohead_targetdate').getValue(),
+                                                            cobmisc_invcdate :  _this.form.findField('cohead_targetdate').getValue(),
+                                                            cobmisc_curr_id : rv.cohead_curr_id,
+                                                            cobmisc_curr_id_curr_name : rv.cohead_curr_id_curr_name,
+                                                            // below parms for add credit memo
+                                                            cmdata : {
+                                                                cm_cust_id : rv.cohead_cust_id,
+                                                                cm_cust_id_cust_name : rv.cohead_cust_id_cust_name,
+                                                                cm_curr_id : rv.cohead_curr_id,
+                                                                cm_curr_id_curr_name : rv.cohead_curr_id_curr_name,
+                                                                cm_terms_id : rv.cohead_terms_id,
+                                                                cm_terms_id_terms_descrip : rv.cohead_terms_id_terms_descrip,
+                                                                cm_salesrep_id : rv.cohead_salesrep_id,
+                                                                cm_salesrep_id_salesrep_name : rv.cohead_salesrep_id_salesrep_name,
+                                                                cm_docdate : new Date(),
+                                                                cm_taxzone_id : rv.cohead_taxzone_id,
+                                                                cm_taxzone_id_taxzone_descrip : rv.cohead_taxzone_id_taxzone_descrip,
+                                                                cm_billto_cntct_id : rv.cohead_billto_cntct_id,
+                                                                cm_billto_cntct_id_cntct_name : rv.cohead_billto_cntct_id_cntct_name,
+                                                                cm_location_src : rv.cohead_location_src,
+                                                                cm_location_src_location_name : rv.cohead_location_src_location_name,
+                                                                cm_billto_address : rv.billto_address
+                                                            }
+                                                            
+                                                        },
+                                                            function() { 
+                                                             _this.invgrid.ds.load({});
+                                                        });
+                                                       
+                                                    },
+                                                    render : function (_self)
+                                                    {
+                                                      _this.addInvoiceBtn = _self;
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function ()
+                                                    {
+                                                    
+                                                         var sel  = _this.invgrid.getSelectionModel().getSelected();
+                                                        if (!sel) {
+                                                            Roo.MessageBox.alert("Error", "Select a invoice");
+                                                            return;
+                                                        }
+                                                        // check current status of shipment..
+                                                        
+                                                        var params =  {
+                                                    //        cobmisc_id : sel.data.cobmisc_id,
+                                                            _void : 1
+                                                        };
+                                                        if (sel.data.cobmisc_id * 1) {
+                                                            params.cobmisc_id = sel.data.cobmisc_id * 1 ;
+                                                        }
+                                                        if (sel.data.cobmisc_invchead_id_invchead_id * 1) {    
+                                                            params.invchead_id  =  sel.data.cobmisc_invchead_id_invchead_id * 1;
+                                                        }
+                                                        
+                                                        Roo.MessageBox.confirm("Are you sure", "Are you sure you want to VOID that invoice?",
+                                                            function(r) {
+                                                                if (r != 'yes') {
+                                                                    return;
+                                                                }
+                                                                new Pman.Request({
+                                                                    mask : 'Sending',
+                                                                    url : baseURL + '/Roo/cobmisc',
+                                                                    method : 'POST',
+                                                                    params :  params,
+                                                                    success : function() {
+                                                                        _this.invgrid.ds.load({});
+                                                                    }
+                                                                })
+                                                                
+                                                            }
+                                                        );
+                                                                
+                                                                
+                                                       
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Void / Unpost",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'cobmisc_invchead_id_invchead_invcnumber',
+                                            header : 'Invoice #',
+                                            width : 100,
+                                            renderer : function(v,x,r) { 
+                                                   if (v && 
+                                                         r.data.cobmisc_invchead_id_invchead_id * 1 && 
+                                                        !r.data.cobmisc_invchead_id_invchead_posted) {
+                                                       return  '<span style="color:red">' + 
+                                                            "NEEDS Voiding then re-posted: " + 
+                                                            String.format('{0}', v) +
+                                                            '</span>'; 
+                                                   }
+                                            
+                                                   if(v && r.data.cobmisc_id == -2){
+                                                        return String.format('<span style="margin-left: 10px;"> - {0} (Credit Memo)</span>', v); 
+                                                   }
+                                                   if(v && r.data.cobmisc_id == -3){
+                                                        return String.format('<span style="margin-left: 20px;"> - {0} (Miscellaneous Check)</span>', v); 
+                                                   }
+                                                  if(v && r.data.cobmisc_id == -4){
+                                                        return String.format('<span style="margin-left: 10px;"> - {0} (Receive Payment) [ {1} ]</span>', v, r.data.cobmisc_cashrcpt_amount); 
+                                                   }
+                                                   
+                                                    return v ? String.format('{0}', v) : 
+                                                            '<span style="color:red">' + "Not Posted" + '</span>'; 
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'cobmisc_invcdate',
+                                            header : 'invcdate',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                    return String.format('{0}', v && r.data.cobmisc_id > 0 ? v.format('d/M/Y') : ''); 
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_qty',
+                                            header : 'Qty',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', v ? parseInt(v) : 0); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_itemcost',
+                                            header : 'Item Cost',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2)  : 0); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_freight',
+                                            header : 'Shipping',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2)  : ''); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_tax',
+                                            header : 'Tax',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                // tax is based on the % itemcost..
+                                            //    var ic  = r.data.cobmisc_itemcost;
+                                                /*
+                                                var ic  =r.data.cobmisc_itemcost - (1* r.data.cobmisc_itemcost_taxfree);
+                                                
+                                                var tax= _this.form.findField('cohead_tax').getValue() * 1.0;
+                                                var totic = _this.form.findField('cohead_subtotal').getValue() * 1.0;    
+                                                if (tax < 0.1) {
+                                                    return '';
+                                                }
+                                                var taxp = tax / totic;
+                                                var lv = taxp * ic;
+                                                */
+                                                return String.format('{0}', (1.0*v).toFixed(2) );
+                                                
+                                                
+                                             }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_cohead_id_cohead_pretax_discount',
+                                            header : 'Discount (Pretax)',
+                                            width : 100,
+                                            renderer : function(v) { return String.format('{0}', v ? (1.0*v).toFixed(2) : 0); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_misc',
+                                            header : 'Discount (Posttax)',
+                                            width : 100,
+                                            renderer : function(v,x,r) 
+                                            {
+                                                var vv = v - r.data.cobmisc_cohead_id_cohead_pretax_discount;
+                                                
+                                                return String.format('{0}', vv ? (1.0*vv).toFixed(2) : 0); 
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_total',
+                                            header : 'Total ',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                            
+                                            /*    
+                                                var ic  = r.data.cobmisc_itemcost;
+                                                var tax= _this.form.findField('cohead_tax').getValue() * 1.0;
+                                                var totic = _this.form.findField('cohead_subtotal').getValue() * 1.0;    
+                                                var     lv = 0.0;
+                                                if (tax > 0.0) {
+                                                    var taxp = tax / totic;
+                                                    lv = taxp * ic;
+                                            
+                                                }
+                                              */  
+                                              
+                                            
+                                                if(v){
+                                                    return String.format('{0}',(v * 1.0).toFixed(2) );
+                                                }
+                                                var d= r.data;
+                                            
+                                                return String.format('{0}',
+                                                   ((d.cobmisc_itemcost * 1.0) + 
+                                                   (d.cobmisc_freight * 1.0) + 
+                                                   (d.cobmisc_tax * 1.0) +
+                                                   (d.cobmisc_misc * 1.0)  
+                                            
+                                                   ).toFixed(2) );
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'cobmisc_outstanding',
+                                            header : 'Outstanding',
+                                            width : 75,
+                                            renderer : function(v,x,r) 
+                                            { 
+                                                
+                                                return String.format('{0}', v ? (v * 1.0).toFixed(2) : 0 );
+                                            }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            titlebar : true
+                        },
+                        north : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            height : 250,
+                            title : "Reserve Stock / Shipments"
+                        }
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.hpanel = this;
+                            if (_this.hgrid) {
+                                _this.hgrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'events',
+                    title : "History",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.hgrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.hpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                if (!_this.dialog) return;
+                                _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                    _this.grid.footer.onClick('first');
+                                }); 
+                            }
+                        },
+                        autoExpandColumn : 'remarks',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, options)
+                                {
+                                    options.params._related_on_table = 'cohead';
+                                    options.params._related_on_id = _this.form.findField('cohead_id').getValue();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'event_when', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/events.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'event_when',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'action',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'ipaddr',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'person_id_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'remarks',
+                                        'type': 'string'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            pageSize : 25,
+                            displayInfo : true,
+                            displayMsg : "Displaying events{0} - {1} of {2}",
+                            emptyMsg : "No events found"
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'event_when',
+                                header : 'Changed',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'action',
+                                header : 'action',
+                                width : 120,
+                                renderer : function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'ipaddr',
+                                header : 'IP address',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'person_id_name',
+                                header : 'Who',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'remarks',
+                                header : 'Notes',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'center',
+                    title : "Stock Tx",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.txpanel = this;
+                                        if (_this.txgrid) {
+                                            _this.txgrid.footer.onClick('first');
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'invdetail',
+                                title : "invdetail",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.txgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.txpanel.active) {
+                                               this.footer.onClick('first');
+                                            }
+                                        }
+                                    },
+                                    autoExpandColumn : 'item_number',
+                                    loadMask : true,
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        new Pman.Request({
+                                                            mask : 'applying',
+                                                            url : baseURL + '/Roo/Cohead',
+                                                            method : 'GET',
+                                                            params : {
+                                                                _apply_fifo : _this.form.findField('cohead_id').getValue()
+                                                            },
+                                                            success : function () {
+                                                                Roo.MessageBox.alert("Applied", "Succesfully Applied");
+                                                            }
+                                                        });
+                                                    }
+                                                },
+                                                text : "Run Apply Fifo on order"
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        new Pman.Request({
+                                                            mask : 'running',
+                                                            url : baseURL + '/Roo/Cohead',
+                                                            method : 'GET',
+                                                            params : {
+                                                                _run_void_fix : _this.form.findField('cohead_id').getValue()
+                                                            },
+                                                            success : function () {
+                                                                Roo.MessageBox.alert("Applied", "Succesfully Run");
+                                                            }
+                                                        });
+                                                    }
+                                                },
+                                                text : "Run Void flagger"
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        new Pman.Download({
+                                                            newWindow : true,
+                                                            mask : 'running',
+                                                            url : baseURL + '/Roo/Invdetail',
+                                                            method : 'GET',
+                                                            timeout :90000,
+                                                            params : {
+                                                                _post : 1,
+                                                                _reverse_all_bad : _this.form.findField('cohead_id').getValue()
+                                                            },
+                                                            success : function () {
+                                                                Roo.MessageBox.alert("Applied", "Succesfully Run");
+                                                            }
+                                                        });
+                                                    }
+                                                },
+                                                text : "Auto Reverse"
+                                            }
+                                        ]
+                                    },
+                                    sm : {
+                                        xtype: 'RowSelectionModel',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            selectionchange : function (_self)
+                                            {
+                                                _this.txdgrid.footer.onClick('first');;
+                                            }
+                                        },
+                                        singleSelect : true
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params.cohead_id = _this.form.findField('cohead_id').getValue();
+                                                if (! o.params.cohead_id ) {
+                                                    this.removeAll();
+                                                    return false;
+                                                }
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'item_number', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/invdetail.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'invdetail_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_transtype',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invhist_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_location_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_comments',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_before',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_after',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invcitem_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_expiration',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_warrpurc',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_ls_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : true,
+                                        displayMsg : "Displaying invdetail{0} - {1} of {2}",
+                                        emptyMsg : "No invdetail found",
+                                        pageSize : 9999
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'item_number',
+                                            header : 'Item',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'rec_shipped',
+                                            header : '#Ship',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'rec_returned',
+                                            header : '#Ret',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', Roo.util.Format.number(v,0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'tx_shipped',
+                                            header : '#TX ship',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'tx_returned',
+                                            header : '#TX ret',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}',  Roo.util.Format.number(v,0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'tx_total',
+                                            header : '#TX Tot',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', Roo.util.Format.number(v,0)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'total_value',
+                                            header : 'Value',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                return (v*1).toFixed(3);
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'tx_total',
+                                            header : '#Diff',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                            
+                                                var cototal = (r.data.rec_returned*1) - (r.data.rec_shipped*1);
+                                            //    Roo.log(cototal);
+                                                var diff = (v*1) - cototal;
+                                             //   Roo.log(diff);
+                                                if (diff == 0)  {
+                                                    return '';
+                                                }
+                                                return String.format('<span style="color:red">{0}</span>',  diff ); 
+                                                }
+                                        }
+                                    ]
+                                }
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.txdpanel = this;
+                                        if (_this.txdgrid) {
+                                            _this.txdgrid.footer.onClick('first');
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'east',
+                                tableName : 'invdetail',
+                                title : "invdetail",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.txdgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.txdpanel.active) {
+                                               this.footer.onClick('first');
+                                            }
+                                        },
+                                        rowclick : function (_self, rowIndex, e)
+                                        {
+                                            var s = _this.txdgrid.ds.getAt(rowIndex);
+                                            var dt = s.data.invhist_transdate.split(' ');
+                                            
+                                            _this.dateSel.setValue(new Date(dt[0]));
+                                        }
+                                    },
+                                    autoExpandColumn : 'invhist_comments',
+                                    loadMask : true,
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        var s = _this.txdgrid.selModel.getSelected();
+                                                    
+                                                        if (!s) {
+                                                            Roo.MessageBox.alert("Error", "Select a transaction");
+                                                            return;
+                                                        }
+                                                        
+                                                        var reverseSel = function() {
+                                                        
+                                                            new Pman.Request({
+                                                                mask : "Reversing",
+                                                                url : baseURL + '/Roo/invdetail',
+                                                                method : 'POST',
+                                                                params : {
+                                                                    _duplicate : s.data.invdetail_id
+                                                                }, 
+                                                                success : function() {
+                                                                    _this.txdgrid.footer.onClick('first');
+                                                                }
+                                                            });
+                                                        
+                                                        }
+                                                        
+                                                        
+                                                    
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm", 
+                                                            "This should only be used by System Administrators - are you sure you know what you are doing!",
+                                                            function(x) {
+                                                                if (x != 'yes') {
+                                                                    return;
+                                                                }
+                                                                reverseSel();
+                                                            }
+                                                        );
+                                                                            
+                                                        
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                text : "Duplicate Selected"
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'TextItem',
+                                                xns: Roo.Toolbar,
+                                                text : "Issue Date"
+                                            },
+                                            {
+                                                xtype: 'DateField',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.dateSel = _self;
+                                                    }
+                                                },
+                                                allowBlank : false,
+                                                fieldLabel : 'Issue Date',
+                                                format : 'Y-m-d',
+                                                name : 'issue_date',
+                                                width : 150
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        var s = _this.txdgrid.selModel.getSelected();
+                                                        var dt = _this.dateSel.getValue();
+                                                        if (!s) {
+                                                            Roo.MessageBox.alert("Error", "Select a transaction");
+                                                            return;
+                                                        }
+                                                        
+                                                        var reverseSel = function(force) {
+                                                        
+                                                            new Pman.Request({
+                                                                mask : "Reversing",
+                                                                url : baseURL + '/Roo/invdetail',
+                                                                method : 'POST',
+                                                                params : {
+                                                                    _reverse : s.data.invdetail_id,
+                                                                    _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                    _force : force
+                                                                }, 
+                                                                success : function() {
+                                                                    _this.txdgrid.footer.onClick('first');
+                                                                },
+                                                                failure : function(res) {
+                                                                    Roo.log(res);
+                                                                    try {
+                                                                        if (res.errors.confirm) {
+                                                                                          
+                                                                            Roo.MessageBox.confirm(
+                                                                                "Confirm", 
+                                                                                "are you really sure the totals will get messed up.",
+                                                                                function(x) {
+                                                                                    if (x != 'yes') {
+                                                                                        return;
+                                                                                    }
+                                                                                    reverseSel(1);
+                                                                                }
+                                                                            );
+                                                                            return;
+                                                                        }
+                                                                    } catch(e) { }
+                                                                    Roo.MessageBox.alert("Error", res.errorMsg);
+                                                                    
+                                                                    
+                                                                }
+                                                            });
+                                                        
+                                                        }
+                                                        
+                                                        
+                                                    
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm", 
+                                                            "This should only be used by System Administrators - are you sure you know what you are doing!",
+                                                            function(x) {
+                                                                if (x != 'yes') {
+                                                                    return;
+                                                                }
+                                                                reverseSel(0);
+                                                            }
+                                                        );
+                                                                            
+                                                        
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                text : "Reverse Selected"
+                                            }
+                                        ]
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params.cohead_id = _this.form.findField('cohead_id').getValue();
+                                                var s = _this.txgrid.selModel.getSelected();
+                                                if (!s) { 
+                                                    this.removeAll();
+                                                    return false;
+                                                }
+                                                o.params.itemsite_id = s.data.invhist_itemsite_id;
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'invdetail_id', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/invdetail.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'invdetail_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_transtype',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invhist_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_location_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_comments',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_before',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_after',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invcitem_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_expiration',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_warrpurc',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_ls_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : true,
+                                        displayMsg : "Displaying invdetail{0} - {1} of {2}",
+                                        emptyMsg : "No invdetail found",
+                                        pageSize : 9999
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invdetail_id',
+                                            header : 'TX#',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invhist_transdate',
+                                            header : 'Date',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invhist_ordnumber',
+                                            header : 'Ref#',
+                                            width : 75,
+                                            renderer : function(v,x,r) {
+                                                if (r.data.invfifo_void *1 != 0) {
+                                                    return String.format('<s>{0}</s>', v); 
+                                                }
+                                            
+                                                 return String.format('{0}', v); 
+                                             }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invhist_comments',
+                                            header : 'Notes',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invdetail_qty',
+                                            header : 'Qty Changed',
+                                            width : 50,
+                                            renderer : function(v,x,r) {
+                                                if ( r.data.coitem_shipped != v) {
+                                                    return String.format('{0} <span style="color:red">({1})</span>',
+                                                         Roo.util.Format.number(v,0),
+                                                         r.data.coitem_shipped
+                                                     );
+                                                
+                                                }
+                                                 return String.format('{0}', Roo.util.Format.number(v,0));
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invhist_value_before',
+                                            header : 'Qty Changed',
+                                            width : 75,
+                                            renderer : function(v,x,r) {
+                                                var tot = r.data.invhist_value_after*1 - v*1;
+                                                var f = '{0}';
+                                                if (r.data.invdetail_qty >0 && tot < 0) {
+                                                    f = '<span style="color:red">{0}</span>';
+                                                }
+                                                if (r.data.invdetail_qty < 0 && tot > 0) {
+                                                    f = '<span style="color:red">{0}</span>';
+                                                }    
+                                                return String.format(f, Roo.util.Format.number(tot));
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invhist_posted',
+                                            header : 'Posted',
+                                            width : 40,
+                                            renderer : function(v,x,r) { 
+                                                
+                                                var state = v   ?  '-checked' : '';
+                                                                                
+                                                return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                             }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        },
+                        east : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            split : true,
+                            width : 500
+                        }
+                    }
+                },
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'center',
+                    title : "GL Tx",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.gltxpanel = this;
+                                        if (_this.gltxgrid) {
+                                            _this.gltxgrid.footer.onClick('first');
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'invdetail',
+                                title : "invdetail",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.gltxgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.gltxpanel.active) {
+                                               this.footer.onClick('first');
+                                            }
+                                        },
+                                        cellclick : function (_self, rowIndex, columnIndex, e)
+                                        {
+                                            if (columnIndex > 0) {
+                                                return;
+                                            }
+                                            var rec = this.ds.getAt(rowIndex);
+                                            rec.set('gltrans_as_summary', rec.data.gltrans_as_summary *1 ? 0 : 1);
+                                            _this.gltxdgrid.footer.onClick('first');
+                                        }
+                                    },
+                                    autoExpandColumn : 'gltrans_accnt_id_accnt_descrip',
+                                    loadMask : true,
+                                    sm : {
+                                        xtype: 'RowSelectionModel',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            selectionchange : function (_self)
+                                            {
+                                                _this.gltxdgrid.footer.onClick('first');;
+                                            }
+                                        },
+                                        singleSelect : true
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params.cohead_id = _this.form.findField('cohead_id').getValue();
+                                                if (! o.params.cohead_id ) {
+                                                    this.removeAll();
+                                                    return false;
+                                                }
+                                                o.params._split_sales = _this.glsalesbtn.pressed ? 1 : 0;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'item_number', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/gltrans.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'invdetail_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_transtype',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invhist_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_location_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_comments',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_before',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_after',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invcitem_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_expiration',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_warrpurc',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_ls_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : true,
+                                        displayMsg : "Displaying invdetail{0} - {1} of {2}",
+                                        emptyMsg : "No invdetail found",
+                                        pageSize : 9999,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.glsalesbtn = _self;
+                                                    },
+                                                    click : function (_self, e)
+                                                    {
+                                                        (function()  { _this.gltxgrid.footer.onClick('first'); }).defer(100);
+                                                    }
+                                                },
+                                                enableToggle : true,
+                                                pressed : true,
+                                                text : "Split sales"
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_as_summary',
+                                            header : 'Summary',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                                
+                                                var state = v*1   ?  '-checked' : '';
+                                                                                
+                                                return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                             }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_accnt_id_accnt_descrip',
+                                            header : 'Account',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'gltrans_amount_credit',
+                                            header : 'Credit',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}',  Roo.util.Format.number(v,3)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'gltrans_amount_debit',
+                                            header : 'Debit',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', Roo.util.Format.number(v,3)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'gltrans_amount_total',
+                                            header : 'Sum',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('<b>{0}</b>', Roo.util.Format.number(v,3)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'gltrans_amount_total_unposted',
+                                            header : 'Unposted',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('<span style="color:red">{0}</span>', Roo.util.Format.number(v,3)); }
+                                        }
+                                    ]
+                                }
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.gltxdpanel = this;
+                                        if (_this.gltxdgrid) {
+                                            _this.gltxdgrid.footer.onClick('first');
+                                        }
+                                    }
+                                },
+                                background : false,
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'east',
+                                tableName : 'invdetail',
+                                title : "invdetail",
+                                grid : {
+                                    xtype: 'Grid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.gltxdgrid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.gltxdpanel.active) {
+                                               this.footer.onClick('first');
+                                            }
+                                        },
+                                        cellclick : function (_self, ri, ci, e)
+                                        {
+                                            
+                                              var deleteSel = function() {
+                                            
+                                                new Pman.Request({
+                                                    mask : "Reversing",
+                                                    url : baseURL + '/Roo/gltrans',
+                                                    method : 'POST',
+                                                    params : {  
+                                                        _void : 1,
+                                                        gltrans_id : rec.data.gltrans_id
+                                                        
+                                                    }, 
+                                                    success : function() {
+                                                        rec.set('gltrans_posted', false);
+                                                        rec.set('gltrans_deleted', true);
+                                                        rec.set('gltrans_docnumber', rec.data.gltrans_docnumber);
+                                                       _this.gltxgrid.footer.onClick('first');
+                                                    }
+                                                });
+                                            
+                                            }
+                                            var undeleteSel = function() {
+                                            
+                                                new Pman.Request({
+                                                    mask : "Reversing",
+                                                    url : baseURL + '/Roo/gltrans',
+                                                    method : 'POST',
+                                                    params : {  
+                                                        _unvoid : 1,
+                                                        gltrans_id : rec.data.gltrans_id
+                                                        
+                                                    }, 
+                                                    success : function() {
+                                                        rec.set('gltrans_posted', true);
+                                                        rec.set('gltrans_deleted', false);
+                                                        rec.set('gltrans_docnumber', rec.data.gltrans_docnumber);
+                                                       _this.gltxgrid.footer.onClick('first');
+                                                    }
+                                                });
+                                            
+                                            }
+                                            
+                                            var di = this.colModel.config[ci].dataIndex;
+                                            if (di != 'gltrans_posted') {
+                                                return;
+                                            }
+                                            
+                                            
+                                            
+                                            var rec = this.ds.getAt(ri);
+                                            if (rec.data.gltrans_deleted) {
+                                            
+                                                 Roo.MessageBox.confirm(
+                                                    "Confirm", 
+                                                    "This should only be used by System Administrators - are you sure you know what you are doing!",
+                                                    function(x) {
+                                                        if (x != 'yes') {
+                                                            return;
+                                                        }
+                                                        undeleteSel();
+                                                    }
+                                                );
+                                            
+                                                return false;
+                                            }
+                                        
+                                            
+                                            
+                                            if (!rec.data.gltrans_posted) {
+                                        
+                                                
+                                                
+                                                new Pman.Request({
+                                                    method : 'POST',
+                                                    url : baseURL + '/Roo/gltrans',
+                                                    mask : "Posting",
+                                                    params : {
+                                                        _post : 1,
+                                                        gltrans_id : rec.data.gltrans_id
+                                                    },
+                                                    success : function (res)
+                                                    {
+                                                        rec.set('gltrans_posted', true);
+                                                        _this.gltxgrid.footer.onClick('first');
+                                                    
+                                                    }
+                                                
+                                                
+                                                });
+                                                return;
+                                            }
+                                            
+                                            // we have a posted transaction.
+                                            // only allow recalled to be deleted..
+                                            if (!rec.data.gltrans_notes.match(/(Recall|Ship Order)/)) {
+                                                return false;
+                                            }
+                                            
+                                            
+                                         
+                                            
+                                            
+                                        
+                                            Roo.MessageBox.confirm(
+                                                "Confirm", 
+                                                "This should only be used by System Administrators - are you sure you know what you are doing!",
+                                                function(x) {
+                                                    if (x != 'yes') {
+                                                        return;
+                                                    }
+                                                    deleteSel();
+                                                }
+                                            );
+                                                  
+                                            
+                                            
+                                        }
+                                    },
+                                    autoExpandColumn : 'gltrans_notes',
+                                    loadMask : true,
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params.cohead_id = _this.form.findField('cohead_id').getValue();
+                                                var s = _this.gltxgrid.selModel.getSelected();
+                                                if (!s) { 
+                                                    this.removeAll();
+                                                    return false;
+                                                }
+                                                o.params.gltrans_accnt_id = s.data.gltrans_accnt_id;
+                                                o.params.gltrans_is_ship = s.data.gltrans_is_ship;
+                                                o.params.gltrans_as_summary =     s.data.gltrans_as_summary;
+                                                
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'gltrans_docnumber', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/gltrans.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            totalProperty : 'total',
+                                            root : 'data',
+                                            id : 'id',
+                                            fields : [
+                                                {
+                                                    'name': 'invdetail_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_transtype',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invhist_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_location_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_comments',
+                                                    'type': 'string'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_before',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_qty_after',
+                                                    'type': 'float'
+                                                },
+                                                {
+                                                    'name': 'invdetail_invcitem_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invdetail_expiration',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_warrpurc',
+                                                    'type': 'date',
+                                                    'dateFormat': 'Y-m-d'
+                                                },
+                                                {
+                                                    'name': 'invdetail_ls_id',
+                                                    'type': 'int'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    footer : {
+                                        xtype: 'PagingToolbar',
+                                        xns: Roo,
+                                        displayInfo : true,
+                                        displayMsg : "Displaying invdetail{0} - {1} of {2}",
+                                        emptyMsg : "No invdetail found",
+                                        pageSize : 9999,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        new Pman.Download( {
+                                                            grid : _this.gltxdgrid
+                                                        
+                                                        });
+                                                    }
+                                                },
+                                                text : "Download"
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_id',
+                                            header : 'Ref#',
+                                            sortable : true,
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v ); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_date',
+                                            header : 'Date',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_docnumber',
+                                            header : 'Doc#',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                                if (r.data.gltrans_deleted) {
+                                                   return String.format('<s>{0}</s>', v);     
+                                                }
+                                                return String.format('{0}', v); 
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_source',
+                                            header : 'Source',
+                                            width : 50,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_notes',
+                                            header : 'Notes',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'gltrans_amount',
+                                            header : 'Amount',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', Roo.util.Format.number(v,3)); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'gltrans_posted',
+                                            header : 'Posted',
+                                            width : 50,
+                                            renderer : function(v,x,r) { 
+                                                
+                                                var state = v   ?  '-checked' : '';
+                                                                                
+                                                return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                             }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        },
+                        east : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            split : true,
+                            width : 500
+                        }
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.profitpanel = this;
+                            
+                            try { if (MODULE.isBuilder) {
+                                return;
+                            } } catch(e) { }
+                            
+                            var id = _this.form.findField('cohead_id').getValue() * 1;
+                            if (id < 1) {
+                                Roo.MessageBox.alert("Save First", "Save the order first, before adding items");
+                                _this.dialog.layout.getRegion('center').showPanel(0);
+                                return;
+                            }
+                            
+                            if (_this.profitgrid) {
+                                _this.profitgrid.footer.onClick('first');
+                             }
+                            
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'coitem',
+                    title : "Profit",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.profitgrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.profitpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'item_number',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                
+                                    try {
+                                       this.removeAll();
+                                   } catch (e) { }
+                                   
+                                
+                                    if (!_this.data || !_this.data.cohead_id) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    
+                                    o.params.coitem_cohead_id = _this.data.cohead_id;
+                                    o.params._without_list_discount =1;
+                                    o.params._with_profit = 1;
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'coitem_linenumber,coitem_subnumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/coitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'type',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_office_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_phone',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_fax',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_email',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_company_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_role',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_remarks',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_passwd',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_owner_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_lang',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_no_reset_sent',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_action_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_project_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_by',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_deleted_dt',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'leader_firstname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_lastname',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_name_facebook',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_blog',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_twitter',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_url_linkedin',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'leader_crm_lead_percentage',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_industry_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_updated_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_created_action_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'leader_crm_type_id',
+                                        'type': 'int'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Displaying coitem{0} - {1} of {2}",
+                            emptyMsg : "No coitem found",
+                            pageSize : 25
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item Code',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'calc_subtotal',
+                                header : 'SubTotal',
+                                width : 200,
+                                renderer : function(v) {
+                                
+                                
+                                     return Roo.util.Format.number( v, 2);
+                                  }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'calc_cost_total',
+                                header : 'Cost of goods',
+                                width : 200,
+                                renderer : function(v) {
+                                
+                                    return Roo.util.Format.number( v, 2);
+                                  }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'profit',
+                                header : 'Profit',
+                                width : 200,
+                                renderer : function(v,x,r) {
+                                        
+                                   var profit = r.data.calc_subtotal - r.data.calc_cost_total;
+                                   
+                                   if(parseInt(profit) < 1){
+                                       return String.format('<b style="color:red;">{0}</b>', Roo.util.Format.number(profit,2));      
+                                   }
+                                        
+                                        
+                                    return Roo.util.Format.number( profit, 2);
+                                }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                alwaysShowTabs : true,
+                tabPosition : 'top',
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                    var id = 1* _this.form.findField('cohead_id').getValue();
+                                    if (!id) {
+                                        Roo.MessageBox.alert("Error", "Save Sales order first");
+                                        return;
+                                    
+                                    }
+                                    // check current status of shipment..
+                                
+                                        new Pman.Download({
+                                            url : baseURL + '/Roo/cohead',
+                                            method : 'GET',
+                                            params : {
+                                                cohead_id :  id,
+                                                _excel : 1
+                                            },
+                                            success : function() {
+                                
+                                            }
+                                        })
+                                            
+                                            
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Download Excel",
+                            icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                    var id = 1* _this.form.findField('cohead_id').getValue();
+                                    if (!id) {
+                                        Roo.MessageBox.alert("Error", "Save Sales order first");
+                                        return;
+                                    
+                                    }
+                                    // check current status of shipment..
+                                
+                                        new Pman.Download({
+                                            url : baseURL + '/Roo/cohead',
+                                            method : 'GET',
+                                            params : {
+                                                cohead_id :  id,
+                                                _print : 1
+                                            },
+                                            success : function() {
+                                
+                                            }
+                                        })
+                                            
+                                            
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Print",
+                            icon : rootURL + '/Pman/templates/images/pdf.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                
+                                    _this.addShipmentBtn.fireEvent('click');
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            hidden : true,
+                            text : "Add Shipment",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                
+                                   Pman.Dialog.XtupleCustomer.show({
+                                         cust_id : _this.form.findField('cohead_cust_id').getValue()
+                                  }); 
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Edit Customer",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                
+                                        _this.addInvoiceBtn.fireEvent('click');
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            hidden : true,
+                            text : "Add Invoice",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                render : function (_self, e)
+                                {
+                                    _this.voidBtn = _self;
+                                },
+                                click : function (_self, e)
+                                {
+                                     var p = {         
+                                         cohead_id : _this.form.findField('cohead_id').getValue() 
+                                     };
+                                    function call() {
+                                
+                                            
+                                       new Pman.Request({
+                                            mask : 'Sending',
+                                            url: baseURL + '/Roo/cohead',
+                                            method : 'POST',
+                                            params :  p,
+                                            success : function()
+                                            {
+                                                _this.callback();
+                                                 if ( _this.data.cohead_status == 'X') {
+                                                  _this.form.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});
+                                          
+                                                    return;
+                                                 }
+                                
+                                 
+                                                _this.dialog.hide();
+                                            }
+                                       });
+                                   }
+                                
+                                  
+                                   if (_this.data.cohead_status == 'X') {
+                                        p._unvoid = 1;
+                                        call();
+                                        return;
+                                    }
+                                    
+                                    Roo.MessageBox.confirm("Confirm", "Are you sure you want to void this?", function(r) {
+                                    
+                                        if (r !='yes') {
+                                            return;
+                                        }
+                                        p._void = 1;
+                                        call();       
+                                
+                                      
+                                    });
+                                
+                                }
+                            },
+                            text : "Void"
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    var p = {          cohead_id : _this.form.findField('cohead_id').getValue() };
+                                    
+                                    var close = 1;
+                                    if (_this.data.cohead_status == 'C') {
+                                        p._reopen = 1;
+                                        close = 0;
+                                        } else {
+                                                p._close = 1;
+                                        }
+                                        
+                                   new Pman.Request({
+                                    url: baseURL + '/Roo/cohead',
+                                    method : 'POST',
+                                    params :  p,
+                                    mask : 'Sending',
+                                    success : function()
+                                    {
+                                           _this.callback();
+                                          if (!close) {
+                                            _this.form.load({ method: 'GET', params: { '_id' : _this.data.cohead_id }});
+                                          
+                                            return;
+                                          }
+                                       
+                                        _this.dialog.hide();
+                                    }
+                                   });
+                                    
+                                },
+                                render : function (_self)
+                                {
+                                   _this.closeBtn = _self;
+                                }
+                            },
+                            text : "Completed"
+                        }
+                    ]
+                }
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                              if (_this.grid)  _this.grid.stopEditing();
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             
+                              if (_this.grid)  _this.grid.stopEditing();
+                         
+                            _this.form.doAction("submit");
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleSalesOrderCopy.bjs b/Pman.Dialog.XtupleSalesOrderCopy.bjs
new file mode 100644 (file)
index 0000000..f4a4cf1
--- /dev/null
@@ -0,0 +1,84 @@
+{
+    "id": "roo-file-310",
+    "name": "Pman.Dialog.XtupleSalesOrderCopy",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleSalesOrderCopy.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    _this.form.findField('scheddate').focus();\n}"
+            },
+            "closable": false,
+            "height": 120,
+            "modal": true,
+            "resizable": false,
+            "title": "Copy  Sales Order",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}",
+                                "actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n        this.findField('_copy_cohead_id').setValue(_this.data._copy_cohead_id);\n       return;\n    }\n    if (action.type == 'load') {\n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            // _this.form.setValues(action.result.data);\n            _this.callback.call(_this,action.result.data);\n         }\n         _this.form.reset();\n         return;\n    }\n}\n"
+                            },
+                            "labelAlign": "right",
+                            "labelWidth": 200,
+                            "method": "POST",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/cohead'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "New Expected Delivery Date",
+                                    "format": "d/m/Y",
+                                    "name": "scheddate",
+                                    "|useIso": "true",
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "_copy_cohead_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   //_this.findField('cuinfo_\n   \n   // check if customer is filled in.\n   if (!_this.form.isValid()) {\n        Roo.MessageBox.alert(\"Error\", \"Fill in a date\");\n        return;\n   }\n   _this.form.submit();\n   \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleSalesOrderCopy.js b/Pman.Dialog.XtupleSalesOrderCopy.js
new file mode 100644 (file)
index 0000000..0b4ac63
--- /dev/null
@@ -0,0 +1,144 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleSalesOrderCopy = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    _this.form.findField('scheddate').focus();
+                }
+            },
+            closable : false,
+            height : 120,
+            modal : true,
+            resizable : false,
+            title : "Copy  Sales Order",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                },
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        this.findField('_copy_cohead_id').setValue(_this.data._copy_cohead_id);
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            // _this.form.setValues(action.result.data);
+                                            _this.callback.call(_this,action.result.data);
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                }
+                            },
+                            labelAlign : 'right',
+                            labelWidth : 200,
+                            method : 'POST',
+                            url : baseURL + '/Roo/cohead',
+                            items : [
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'New Expected Delivery Date',
+                                    format : 'd/m/Y',
+                                    name : 'scheddate',
+                                    useIso : true
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : '_copy_cohead_id'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           //_this.findField('cuinfo_
+                           
+                           // check if customer is filled in.
+                           if (!_this.form.isValid()) {
+                                Roo.MessageBox.alert("Error", "Fill in a date");
+                                return;
+                           }
+                           _this.form.submit();
+                           
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleSalesOrderNew.bjs b/Pman.Dialog.XtupleSalesOrderNew.bjs
new file mode 100644 (file)
index 0000000..f8dca74
--- /dev/null
@@ -0,0 +1,176 @@
+{
+    "id": "roo-file-303",
+    "name": "Pman.Dialog.XtupleSalesOrderNew",
+    "parent": "",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleSalesOrderNew.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    _this.form.findField('cohead_cust_id').focus();\n}"
+            },
+            "closable": false,
+            "height": 180,
+            "modal": true,
+            "resizable": false,
+            "title": "Create new Sales Order",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}"
+                            },
+                            "xtype": "Form",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "add": "function (combo)\n{\n \n    Pman.Dialog.XtupleCustomer.show( { id : 0 } , function(res) {\n        Roo.log(res);\n        // fill in customer\n        _this.form.setValues({\n            cohead_cust_id: res.cust_id,\n            cohead_cust_id_cust_name : res.cust_name,\n            cohead_curr_id : res.cust_curr_id,\n            cohead_curr_id_curr_name : res.cust_curr_id_curr_name\n        });\n        \n        \n    })\n    \n}\n\n",
+                                        "select": "function (combo, record, index)\n{\n   \n   Roo.log(record);\n    _this.form.setValues({\n        cohead_curr_id : record.data.cust_curr_id,\n        cohead_curr_id_curr_name : record.data.cust_curr_id_curr_name\n    \n    });\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "fieldLabel": "Select Customer",
+                                    "forceSelection": true,
+                                    "hiddenName": "cohead_cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cohead_cust_id_cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select custinfo",
+                                    "queryParam": "query[cust_name_begin]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b>  ({cust_number})</div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "cust_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n\n  //  o.params['search[with_location]'] = 1;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "displayField": "curr_name",
+                                    "editable": false,
+                                    "emptyText": "Select Currency",
+                                    "fieldLabel": "Currency",
+                                    "forceSelection": true,
+                                    "hiddenName": "cohead_curr_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cohead_curr_id_curr_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Currency",
+                                    "queryParam": "query[curr_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{curr_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "curr_id",
+                                    "width": 285,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'curr_symbol' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/curr_symbol.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "curr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"curr_id\",\"type\":\"int\"},\"curr_symbol\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   //_this.findField('cuinfo_\n   \n   // check if customer is filled in.\n   if (_this.form.findField('cohead_cust_id').getValue() < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a customer\");\n        return;\n   }\n   \n   var data = _this.form.getFieldValues();\n   var c = _this.form.findField('cohead_cust_id').lastData;\n   \n   \n   var cur = _this.form.findField('cohead_curr_id').lastData;   \n   \n   data.cohead_curr_id      = cur.curr_id;\n//   data.cohead_curr_id_curr_name = cur.cust_curr_id_curr_name;\n   data.cohead_curr_id_curr_name = cur.curr_name;\n   \n   data.cohead_terms_id      = c.cust_terms_id;\n   data.cohead_terms_id_terms_descrip = c.cust_terms_id_terms_descrip;\n   \n   // fill in staff in/c..\n   \n   data.cohead_salesrep_id =  Pman.Login.authUser.salesrep.salesrep_id;\n   data.cohead_salesrep_id_salesrep_name =  Pman.Login.authUser.salesrep.salesrep_name;\n   \n   data.cohead_display_salesrep_id = c.cust_salesrep_id;\n   data.cohead_display_salesrep_id_salesrep_name = c.cust_salesrep_id_salesrep_name;\n   \n   data.cohead_orderdate = new Date();\n   \n   \n   data.cohead_location_src = c.default_location_id;\n   data.cohead_location_src_location_name = c.default_location_name;\n   \n   data.cohead_taxzone_id = c.cust_taxzone_id_taxzone_id;\n   data.cohead_taxzone_id_taxzone_descrip = c.cust_taxzone_id_taxzone_descrip;\n   \n   // if customer is online .. .then do not fill this stuff in..\n   \n   if (c.cust_custtype_id_custtype_code == 'ONLINE') {\n         Pman.Dialog.XtupleSalesOrder.show(data, function() {\n            _this.dialog.hide();\n            _this.callback()\n         });    \n         return;\n     }\n   \n   Roo.log(data);\n   \n   new Pman.Request({\n        url : baseURL + '/Roo/cntct.php',\n        method : 'GET',\n        params : {\n            '_customer_id' : data.cohead_cust_id,\n            'limit' : 1,\n            'sort' : 'cntct_name',\n            'dir' : 'ASC'\n        },\n        success : function (res){\n            if(res.data[0]){\n                for(var i in res.data[0]) {\n                    data['cohead_billto_cntct_id_' + i] = res.data[0][i];\n                }\n             }\n             Pman.Dialog.XtupleSalesOrder.show(data, function() {\n                _this.dialog.hide();\n                _this.callback()\n             }); \n        }\n    });\n   \n   \n   \n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleSalesOrderNew.js b/Pman.Dialog.XtupleSalesOrderNew.js
new file mode 100644 (file)
index 0000000..1468556
--- /dev/null
@@ -0,0 +1,299 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleSalesOrderNew = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    _this.form.findField('cohead_cust_id').focus();
+                }
+            },
+            closable : false,
+            height : 180,
+            modal : true,
+            resizable : false,
+            title : "Create new Sales Order",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                }
+                            },
+                            items : [
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        add : function (combo)
+                                        {
+                                         
+                                            Pman.Dialog.XtupleCustomer.show( { id : 0 } , function(res) {
+                                                Roo.log(res);
+                                                // fill in customer
+                                                _this.form.setValues({
+                                                    cohead_cust_id: res.cust_id,
+                                                    cohead_cust_id_cust_name : res.cust_name,
+                                                    cohead_curr_id : res.cust_curr_id,
+                                                    cohead_curr_id_curr_name : res.cust_curr_id_curr_name
+                                                });
+                                                
+                                                
+                                            })
+                                            
+                                        },
+                                        select : function (combo, record, index)
+                                        {
+                                           
+                                           Roo.log(record);
+                                            _this.form.setValues({
+                                                cohead_curr_id : record.data.cust_curr_id,
+                                                cohead_curr_id_curr_name : record.data.cust_curr_id_curr_name
+                                            
+                                            });
+                                        }
+                                    },
+                                    allowBlank : false,
+                                    displayField : 'cust_name',
+                                    editable : true,
+                                    fieldLabel : 'Select Customer',
+                                    forceSelection : true,
+                                    hiddenName : 'cohead_cust_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'cohead_cust_id_cust_name',
+                                    pageSize : 20,
+                                    qtip : "Select custinfo",
+                                    queryParam : 'query[cust_name_begin]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b>  ({cust_number})</div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'cust_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                            
+                                              //  o.params['search[with_location]'] = 1;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/custinfo.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'cust_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    displayField : 'curr_name',
+                                    editable : false,
+                                    emptyText : "Select Currency",
+                                    fieldLabel : 'Currency',
+                                    forceSelection : true,
+                                    hiddenName : 'cohead_curr_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'cohead_curr_id_curr_name',
+                                    pageSize : 20,
+                                    qtip : "Select Currency",
+                                    queryParam : 'query[curr_name]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{curr_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'curr_id',
+                                    width : 285,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'curr_symbol' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/curr_symbol.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'curr_id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"curr_id","type":"int"},"curr_symbol"]
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           //_this.findField('cuinfo_
+                           
+                           // check if customer is filled in.
+                           if (_this.form.findField('cohead_cust_id').getValue() < 1) {
+                                Roo.MessageBox.alert("Error", "Select a customer");
+                                return;
+                           }
+                           
+                           var data = _this.form.getFieldValues();
+                           var c = _this.form.findField('cohead_cust_id').lastData;
+                           
+                           
+                           var cur = _this.form.findField('cohead_curr_id').lastData;   
+                           
+                           data.cohead_curr_id      = cur.curr_id;
+                        //   data.cohead_curr_id_curr_name = cur.cust_curr_id_curr_name;
+                           data.cohead_curr_id_curr_name = cur.curr_name;
+                           
+                           data.cohead_terms_id      = c.cust_terms_id;
+                           data.cohead_terms_id_terms_descrip = c.cust_terms_id_terms_descrip;
+                           
+                           // fill in staff in/c..
+                           
+                           data.cohead_salesrep_id =  Pman.Login.authUser.salesrep.salesrep_id;
+                           data.cohead_salesrep_id_salesrep_name =  Pman.Login.authUser.salesrep.salesrep_name;
+                           
+                           data.cohead_display_salesrep_id = c.cust_salesrep_id;
+                           data.cohead_display_salesrep_id_salesrep_name = c.cust_salesrep_id_salesrep_name;
+                           
+                           data.cohead_orderdate = new Date();
+                           
+                           
+                           data.cohead_location_src = c.default_location_id;
+                           data.cohead_location_src_location_name = c.default_location_name;
+                           
+                           data.cohead_taxzone_id = c.cust_taxzone_id_taxzone_id;
+                           data.cohead_taxzone_id_taxzone_descrip = c.cust_taxzone_id_taxzone_descrip;
+                           
+                           // if customer is online .. .then do not fill this stuff in..
+                           
+                           if (c.cust_custtype_id_custtype_code == 'ONLINE') {
+                                 Pman.Dialog.XtupleSalesOrder.show(data, function() {
+                                    _this.dialog.hide();
+                                    _this.callback()
+                                 });    
+                                 return;
+                             }
+                           
+                           Roo.log(data);
+                           
+                           new Pman.Request({
+                                url : baseURL + '/Roo/cntct.php',
+                                method : 'GET',
+                                params : {
+                                    '_customer_id' : data.cohead_cust_id,
+                                    'limit' : 1,
+                                    'sort' : 'cntct_name',
+                                    'dir' : 'ASC'
+                                },
+                                success : function (res){
+                                    if(res.data[0]){
+                                        for(var i in res.data[0]) {
+                                            data['cohead_billto_cntct_id_' + i] = res.data[0][i];
+                                        }
+                                     }
+                                     Pman.Dialog.XtupleSalesOrder.show(data, function() {
+                                        _this.dialog.hide();
+                                        _this.callback()
+                                     }); 
+                                }
+                            });
+                           
+                           
+                           
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleSalesProductList.bjs b/Pman.Dialog.XtupleSalesProductList.bjs
new file mode 100644 (file)
index 0000000..b71d545
--- /dev/null
@@ -0,0 +1,236 @@
+{
+    "id": "roo-file-23",
+    "name": "Pman.Dialog.XtupleSalesProductList",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleSalesProductList.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n   _this.grid.footer.onClick('first');\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 600,
+            "modal": true,
+            "resizable": false,
+            "title": "Products List",
+            "width": 1000,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    \n //   if (_this.grid) {\n //       _this.grid.footer.onClick('first');\n //   }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "item",
+                    "title": "Products List",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n  //  if (_this.panel.active) {\n//      this.footer.onClick('first');\n  //  }\n    \n}",
+                                "rowdblclick": "function (_self, rowIndex, e)\n{\n    _this.dialog.hide();\n    if(!_this.callback){\n        return;\n    }\n    var s = this.ds.getAt(rowIndex);\n    if (s.data.item_id * 1 < 1 ) {\n        return;\n    }\n    \n    _this.callback.call(_this,s.data);\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "item_descrip1",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "*prop": "sm",
+                                    "singleSelect": true,
+                                    "xtype": "RowSelectionModel",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, o)\n{\n      o.params._with_prodcat = 1;\n      o.params._with_char = 1;\n      o.params._with_itemsrc_active = 1;\n      o.params._with_last_purchase_price = 1;\n      o.params._with_image = 1;\n      o.params._with_itemsite = 1;\n      o.params.cohead_cust_id = _this.data.cohead_cust_id;\n      o.params.cohead_id = _this.data.cohead_id;\n      var s = _this.searchBox.getValue();\n      if (!s.length) {\n            return false;\n        }\n        o.params['query[number_or_name]'] = s;\n      \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'item_number', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/item.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            "id": "item_id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'item_descrip1',\n        'type': 'string'\n    },\n    {\n        'name': 'item_descrip2',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_picklist',\n        'type': 'int'\n    },\n    {\n        'name': 'item_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'item_sold',\n        'type': 'int'\n    },\n    {\n        'name': 'item_fractional',\n        'type': 'int'\n    },\n    {\n        'name': 'item_active',\n        'type': 'int'\n    },\n    {\n        'name': 'item_type',\n        'type': 'string'\n    },\n    {\n        'name': 'item_prodweight',\n        'type': 'float'\n    },\n    {\n        'name': 'item_packweight',\n        'type': 'float'\n    },\n    {\n        'name': 'item_prodcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_exclusive',\n        'type': 'int'\n    },\n    {\n        'name': 'item_listprice',\n        'type': 'float'\n    },\n    {\n        'name': 'item_config',\n        'type': 'int'\n    },\n    {\n        'name': 'item_extdescrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_upccode',\n        'type': 'string'\n    },\n    {\n        'name': 'item_maxcost',\n        'type': 'float'\n    },\n    {\n        'name': 'item_inv_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_warrdays',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_tax_recoverable',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'item_price_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_price_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_code',\n        'type': 'string'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_classcode_id_classcode_code',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_mfg',\n        'type': 'int'\n    },\n    {\n        'name': 'item_classcode_id_classcode_creator',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_created',\n        'type': 'date'\n    },\n    {\n        'name': 'item_classcode_id_classcode_modifier',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_modified',\n        'type': 'date'\n    },\n    {\n        'name': 'item_classcode_id_classcode_type',\n        'type': 'string'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Double click to select the item",
+                                    "emptyMsg": "No item found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "specialkey": "function (_self, e)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                                "render": "function (_self)\n{\n    _this.searchBox = _self;\n}"
+                                            },
+                                            "xtype": "TextField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "cls": "x-btn-icon",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\r\n    _this.status_type.setValue('');\r\n    _this.grid.footer.onClick('first');\r\n}"
+                                            },
+                                            "cls": "x-btn-icon",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_image_filename",
+                                    "header": "Image",
+                                    "width": 150,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r)\r\n{\n   if(!v){\n    return '';\n   }\n   if(r.data.item_image_from_hk){\n        var url = baseURL.split('/');\n        url.pop();\n        url = url.join('/');\n        return '<img src=\"' + url + '/hk.php/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '\" width=\"150\" height=\"100\" />';     \n   }\r\n   return '<img src=\"' + baseURL + '/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '\" width=\"150\" height=\"100\" />';\r\n}",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_char_brand",
+                                    "header": "Brand",
+                                    "sortable": true,
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_char_productgroup",
+                                    "header": "Product Group",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Number",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Description",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "itemsrc_active",
+                                    "header": "Purchased",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_sold",
+                                    "header": "is Sold?",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_active",
+                                    "header": "is Active?",
+                                    "width": 55,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_type",
+                                    "header": "Type",
+                                    "width": 50,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_prodcat_id_prodcat_code",
+                                    "header": "Item prodcat",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleSalesProductList.js b/Pman.Dialog.XtupleSalesProductList.js
new file mode 100644 (file)
index 0000000..3540316
--- /dev/null
@@ -0,0 +1,504 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleSalesProductList = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                   _this.grid.footer.onClick('first');
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 600,
+            modal : true,
+            resizable : false,
+            title : "Products List",
+            width : 1000,
+            items : [
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            
+                         //   if (_this.grid) {
+                         //       _this.grid.footer.onClick('first');
+                         //   }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'item',
+                    title : "Products List",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                              //  if (_this.panel.active) {
+                            //      this.footer.onClick('first');
+                              //  }
+                                
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                _this.dialog.hide();
+                                if(!_this.callback){
+                                    return;
+                                }
+                                var s = this.ds.getAt(rowIndex);
+                                if (s.data.item_id * 1 < 1 ) {
+                                    return;
+                                }
+                                
+                                _this.callback.call(_this,s.data);
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        loadMask : true,
+                        sm : {
+                            xtype: 'RowSelectionModel',
+                            xns: Roo.grid,
+                            singleSelect : true
+                        },
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                      o.params._with_prodcat = 1;
+                                      o.params._with_char = 1;
+                                      o.params._with_itemsrc_active = 1;
+                                      o.params._with_last_purchase_price = 1;
+                                      o.params._with_image = 1;
+                                      o.params._with_itemsite = 1;
+                                      o.params.cohead_cust_id = _this.data.cohead_cust_id;
+                                      o.params.cohead_id = _this.data.cohead_id;
+                                      var s = _this.searchBox.getValue();
+                                      if (!s.length) {
+                                            return false;
+                                        }
+                                        o.params['query[number_or_name]'] = s;
+                                      
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'item_number', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/item.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'item_id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'item_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_number',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_descrip1',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_descrip2',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_picklist',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_comments',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_sold',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_fractional',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_active',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_type',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_prodweight',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'item_packweight',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'item_prodcat_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_exclusive',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_listprice',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'item_config',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_extdescrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_upccode',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_maxcost',
+                                        'type': 'float'
+                                    },
+                                    {
+                                        'name': 'item_inv_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_warrdays',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_freightclass_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_tax_recoverable',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_price_uom_id_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_price_uom_id_uom_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_price_uom_id_uom_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_price_uom_id_uom_item_weight',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_inv_uom_id_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_inv_uom_id_uom_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_inv_uom_id_uom_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_inv_uom_id_uom_item_weight',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_freightclass_id_freightclass_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_freightclass_id_freightclass_code',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_freightclass_id_freightclass_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_code',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_descrip',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_mfg',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_creator',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_created',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_modifier',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_modified',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'item_classcode_id_classcode_type',
+                                        'type': 'string'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Double click to select the item",
+                            emptyMsg : "No item found",
+                            pageSize : 25
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        specialkey : function (_self, e)
+                                        {
+                                          _this.grid.footer.onClick('first');
+                                        },
+                                        render : function (_self)
+                                        {
+                                            _this.searchBox = _self;
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.grid.footer.onClick('first');
+                                        }
+                                    },
+                                    cls : 'x-btn-icon',
+                                    icon : rootURL + '/Pman/templates/images/search.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.searchBox.setValue('');
+                                            _this.status_type.setValue('');
+                                            _this.grid.footer.onClick('first');
+                                        }
+                                    },
+                                    cls : 'x-btn-icon',
+                                    icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_image_filename',
+                                header : 'Image',
+                                width : 150,
+                                renderer : function(v,x,r)
+                                {
+                                   if(!v){
+                                    return '';
+                                   }
+                                   if(r.data.item_image_from_hk){
+                                        var url = baseURL.split('/');
+                                        url.pop();
+                                        url = url.join('/');
+                                        return '<img src="' + url + '/hk.php/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '" width="150" height="100" />';     
+                                   }
+                                   return '<img src="' + baseURL + '/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '" width="150" height="100" />';
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_char_brand',
+                                header : 'Brand',
+                                sortable : true,
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_char_productgroup',
+                                header : 'Product Group',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Number',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Description',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'itemsrc_active',
+                                header : 'Purchased',
+                                width : 75,
+                                renderer : function(v) {  
+                                    var state = v * 1 > 0 ?  '-checked' : '';
+                                
+                                    return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_sold',
+                                header : 'is Sold?',
+                                width : 50,
+                                renderer : function(v) {  
+                                    var state = v * 1 > 0 ?  '-checked' : '';
+                                
+                                    return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_active',
+                                header : 'is Active?',
+                                width : 55,
+                                renderer : function(v) {  
+                                    var state = v * 1 > 0 ?  '-checked' : '';
+                                
+                                    return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_type',
+                                header : 'Type',
+                                width : 50,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_prodcat_id_prodcat_code',
+                                header : 'Item prodcat',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleShipment.bjs b/Pman.Dialog.XtupleShipment.bjs
new file mode 100644 (file)
index 0000000..bc701e8
--- /dev/null
@@ -0,0 +1,468 @@
+{
+    "id": "roo-file-342",
+    "name": "Pman.Dialog.XtupleShipment",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleShipment.bjs",
+    "items": [
+        {
+            "closable": true,
+            "collapsible": false,
+            "height": 620,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit Shipment / Delivery",
+            "width": 800,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "region": "north",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n\n        if (_this.data.shiphead_id) {\n            this.load({ method: 'GET', params: { '_id' : _this.data.shiphead_id }});\n           return;\n       }\n       _this.grid.ds.load({});\n            _this.saveBtn.show();       \n       \n    }\n    if (action.type == 'load') {\n        var d = action.result.data;\n        \n\n        if (d.shiphead_shipped *1 > 0) {\n                Roo.MessageBox.alert(\n                        \"Warning\", \"This shipment has been confirmed, you must unconfirm it before you can edit it\"\n                    );\n\n                _this.saveBtn.hide();\n            \n        } else {\n            _this.saveBtn.show();\n        }\n        _this.grid.ds.load({});\n         \n        return;\n    }\n    if (action.type =='submit') {\n    \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                            },
+                            "method": "POST",
+                            "style": "margin:10px;",
+                            "timeout": 60000,
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/shiphead.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "width": 370,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "legend": "Details",
+                                            "style": "width:350px;height:193px;",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "labelAlign": "right",
+                                                    "labelWidth": 60,
+                                                    "width": 340,
+                                                    "xtype": "Row",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "fieldLabel": "Number#",
+                                                            "name": "shiphead_number",
+                                                            "readOnly": true,
+                                                            "value": "Automatic",
+                                                            "width": 100,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "labelAlign": "right",
+                                                    "labelWidth": 60,
+                                                    "width": 340,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "allowBlank": false,
+                                                            "fieldLabel": "Date",
+                                                            "format": "Y-m-d",
+                                                            "name": "shiphead_shipdate",
+                                                            "width": 100,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "From",
+                                                            "name": "shiphead_location_id_location_name",
+                                                            "readOnly": true,
+                                                            "width": 270,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "To",
+                                                            "name": "shiphead_shipto_id_shipto_name",
+                                                            "width": 270,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Via",
+                                                            "name": "shiphead_shipvia",
+                                                            "width": 270,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "fieldLabel": "Tracking",
+                                                            "name": "shiphead_tracknum",
+                                                            "width": 270,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "width": 350,
+                                    "xtype": "Column",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "hideLabels": true,
+                                            "legend": "Delivery Notes",
+                                            "style": "width:330px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Delivery Notes",
+                                                    "name": "shiphead_delivery_note",
+                                                    "width": 320,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "hideLabels": true,
+                                            "legend": "Shipment Notes",
+                                            "style": "width:330px",
+                                            "xtype": "FieldSet",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "fieldLabel": "Shipment Notes",
+                                                    "name": "shiphead_notes",
+                                                    "width": 320,
+                                                    "xtype": "TextArea",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form",
+                                    "name": "shiphead_order_id"
+                                },
+                                {
+                                    "name": "shiphead_sfstatus",
+                                    "value": "N",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "shiphead_location_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "shiphead_shipto_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form",
+                                    "name": "shiphead_id",
+                                    "width": 100
+                                },
+                                {
+                                    "name": "shipitems",
+                                    "width": 100,
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "*prop": "north",
+                    "height": 230,
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.panel = this;\n    \n    if (_this.isBuilder) {\n        return;\n    }\n    \n   \n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n}"
+                    },
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "coitem",
+                    "title": "Order Items",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    \n}\n",
+                                "afteredit": "function (e)\n{\n    //Roo.log('afteredit');\n   // Roo.log(e);\n    if (e.field == 'item_number') {\n        // afterselect handles this...\n        return;\n    }\n    e.record.commit();\n}"
+                            },
+                            "*prop": "grid",
+                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "autoExpandColumn": "item_descrip1",
+                            "clicksToEdit": 1,
+                            "loadMask": true,
+                            "xtype": "EditorGrid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "tabend": "function (_self)\n{\n    _this.addItemBtn.fireEvent('click', _this.addItemBtn);\n}"
+                                    },
+                                    "*prop": "sm",
+                                    "enter_is_tab": true,
+                                    "xtype": "CellSelectionModel",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "listeners": {
+                                        "|beforeload": "function (_self,o) {\n    if (! _this.form.findField('shiphead_order_id').getValue()) {\n        return false;\n    }\n    o.params = o.params || {};\n    \n    o.params.coitem_cohead_id = _this.form.findField('shiphead_order_id').getValue();\n    o.params.limit = 999;\n    o.params._stocked_only = 1;\n    o.params.shiphead_id = _this.form.findField('shiphead_id').getValue();\n    o.params.coitem_shipto_id = _this.form.findField('shiphead_shipto_id').getValue();\n    o.params['query[coitem_location_src]'] = _this.form.findField('shiphead_location_id').getValue();\n     \n    \n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'coitem_linenumber', direction: 'ASC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/coitem.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "|xns": "Roo.data",
+                                            "xtype": "JsonReader",
+                                            "totalProperty": "total",
+                                            "root": "data",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"},{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"},{\"table\":\"coitem\",\"column\":\"coitem_unitcost\",\"columnshort\":\"coitem_unitcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Unit Cost\"},{\"table\":\"coitem\",\"column\":\"coitem_price\",\"columnshort\":\"coitem_price\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Price\"},{\"table\":\"coitem\",\"column\":\"coitem_custprice\",\"columnshort\":\"coitem_custprice\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust Price\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreturned\",\"columnshort\":\"coitem_qtyreturned\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#Returned\"},{\"table\":\"coitem\",\"column\":\"coitem_prcost\",\"columnshort\":\"coitem_prcost\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"prcost?\"},{\"table\":\"coitem\",\"column\":\"coitem_price_uom_id\",\"columnshort\":\"coitem_price_uom_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"uom_id\",\"deps\":[{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_name\",\"columnshort\":\"uom_name\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_descrip\",\"columnshort\":\"uom_descrip\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"uom\",\"column\":\"coitem_price_uom_id_uom_item_weight\",\"columnshort\":\"uom_item_weight\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"Unit of\"},{\"table\":\"coitem\",\"column\":\"coitem_qtyreserved\",\"columnshort\":\"coitem_qtyreserved\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#reserved\"}],\"cols_ex\":[\"coitem_price_uom_id_uom_descrip\"],\"table\":\"coitem\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "|fields": "[\n    {\n        'name': 'coitem_linenumber',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyord'\n    },\n    {\n        'name': 'coitem_unitcost'\n    },\n    {\n        'name': 'coitem_price'\n    },\n    {\n        'name': 'coitem_custprice'\n    },\n    {\n        'name': 'coitem_qtyreturned'\n    },\n    {\n        'name': 'coitem_prcost'\n    },\n    {\n        'name': 'coitem_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'coitem_qtyreserved'\n    }\n]"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "click": "function (_self, e)\n{\n    _this.grid.ds.each(function(r) {\n        r.set('shipitem_qty', Math.max(r.data.coitem_qtyord - r.data.shipitem_shipped));\n    });\n}"
+                                            },
+                                            "text": "Fullfill all",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Separator"
+                                        },
+                                        {
+                                            "text": "Restore From",
+                                            "xtype": "TextItem",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|select": "function (combo, record, index)\n{\n  //_this.grid.footer.onClick('first');\n  \n   (function() { \n    combo.setValue('');\n   }).defer(100);\n   var data = record.json.data;\n   \n   _this.grid.ds.each(function (r) {\n        if (typeof(data[r.data.coitem_itemsite_id+'']) == 'undefined') {\n            return;\n        }\n        r.set('shipitem_qty', parseInt(data[r.data.coitem_itemsite_id+'']));\n   \n   });\n   \n   \n   \n  \n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "name",
+                                            "editable": false,
+                                            "emptyText": "Restore from",
+                                            "forceSelection": true,
+                                            "listWidth": 300,
+                                            "loadingText": "Searching...",
+                                            "name": "name",
+                                            "pageSize": 20,
+                                            "qtip": "Select Action",
+                                            "queryParam": "query[action]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "valueField": "name",
+                                            "width": 300,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n     \n    o.params._stash = _this.form.findField('shiphead_order_id').getValue();\n\n}"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'action' , direction : 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/Shiphead.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "name",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\n    {\n        'name': 'name',\n        'type': 'string'\n    }\n \n]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "xtype": "Fill",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n     _this.grid.ds.each(function(r) {\n        r.set('shipitem_qty', 0);\n    });\n}\n"
+                                            },
+                                            "text": "Reset",
+                                            "xtype": "Button",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_linenumber\",\"columnshort\":\"coitem_linenumber\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Item#\"}",
+                                    "dataIndex": "coitem_linenumber",
+                                    "header": "Item#",
+                                    "sortable": true,
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n    if (r.data.coitem_subnumber * 1 > 0)  {\n         return String.format('{0}.{1}', v, r.data.coitem_subnumber ); \n     }\n     return String.format('{0}', v); \n }\n ",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "item_number",
+                                    "header": "Item Code",
+                                    "sortable": true,
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                    "dataIndex": "item_descrip1",
+                                    "header": "Item Description",
+                                    "width": "150.00",
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v, x, r) {\n\n    var vv = v;\n    if (r.data.coitem_memo && r.data.coitem_memo.length) {\n        vv = r.data.coitem_memo;\n    }\n    return String.format('{0}', vv); \n \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"}",
+                                    "align": "right",
+                                    "dataIndex": "coitem_qtyord",
+                                    "header": "Ordered Qty",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"}",
+                                    "align": "right",
+                                    "dataIndex": "shipitem_shipped",
+                                    "header": "Remaining Qty",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n\n     return String.format('{0}', r.data.coitem_qtyord - v); \n }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_qtyord\",\"columnshort\":\"coitem_qtyord\",\"ctype\":\"numeric\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Qty\"}",
+                                    "align": "right",
+                                    "dataIndex": "shipitem_qty",
+                                    "header": "Ship Qty",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { \n    \n    var vv = parseInt(v);\n    vv = isNaN(vv) ? 0 : vv;\n    r.data.shipitem_qty = vv; // get rid of decimal.\n    if (r.data.shipitem_shipped + vv > r.data.coitem_qtyord) {\n            return String.format('<b style=\"background-color:red;color:yellow\">{0}</b>', vv); \n    }\n    // not fully fullfilled\n    if (r.data.shipitem_shipped + vv != r.data.coitem_qtyord) {\n            return String.format('<b style=\"background-color:blue;color:yellow\">{0}</b>', vv); \n    }   \n    return String.format('{0}', vv); \n    \n}",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "editor",
+                                            "xtype": "GridEditor",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "*prop": "field",
+                                                    "allowDecimals": true,
+                                                    "allowNegative": false,
+                                                    "decimalPrecision": 0,
+                                                    "minValue": 0,
+                                                    "style": "text-align:right",
+                                                    "xtype": "NumberField",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n     Roo.Ajax.timeout = 120000; // 2 minutes timeout..\n     var ar = [];\n\n    _this.grid.ds.each(function(r) {\n        ar.push({\n            shipitem_orderitem_id : r.data.coitem_id,\n            shipitem_qty : r.data.shipitem_qty \n        });\n        \n    });\n    \n    _this.form.findField('shipitems').setValue(JSON.stringify(ar));\n    _this.form.doAction(\"submit\");\n    \n}",
+                        "render": "function (_self)\n{\n _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleShipment.js b/Pman.Dialog.XtupleShipment.js
new file mode 100644 (file)
index 0000000..1915743
--- /dev/null
@@ -0,0 +1,670 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleShipment = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : true,
+            collapsible : false,
+            height : 620,
+            modal : true,
+            resizable : false,
+            title : "Edit Shipment / Delivery",
+            width : 800,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'north',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                
+                                        if (_this.data.shiphead_id) {
+                                            this.load({ method: 'GET', params: { '_id' : _this.data.shiphead_id }});
+                                           return;
+                                       }
+                                       _this.grid.ds.load({});
+                                            _this.saveBtn.show();       
+                                       
+                                    }
+                                    if (action.type == 'load') {
+                                        var d = action.result.data;
+                                        
+                                
+                                        if (d.shiphead_shipped *1 > 0) {
+                                                Roo.MessageBox.alert(
+                                                        "Warning", "This shipment has been confirmed, you must unconfirm it before you can edit it"
+                                                    );
+                                
+                                                _this.saveBtn.hide();
+                                            
+                                        } else {
+                                            _this.saveBtn.show();
+                                        }
+                                        _this.grid.ds.load({});
+                                         
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                    
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                },
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                }
+                            },
+                            method : 'POST',
+                            style : 'margin:10px;',
+                            timeout : 60000,
+                            url : baseURL + '/Roo/shiphead.php',
+                            items : [
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : 370,
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            legend : "Details",
+                                            style : 'width:350px;height:193px;',
+                                            items : [
+                                                {
+                                                    xtype: 'Row',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'right',
+                                                    labelWidth : 60,
+                                                    width : 340,
+                                                    items : [
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Number#',
+                                                            name : 'shiphead_number',
+                                                            readOnly : true,
+                                                            value : "Automatic",
+                                                            width : 100
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    xtype: 'Column',
+                                                    xns: Roo.form,
+                                                    labelAlign : 'right',
+                                                    labelWidth : 60,
+                                                    width : 340,
+                                                    items : [
+                                                        {
+                                                            xtype: 'DateField',
+                                                            xns: Roo.form,
+                                                            allowBlank : false,
+                                                            fieldLabel : 'Date',
+                                                            format : 'Y-m-d',
+                                                            name : 'shiphead_shipdate',
+                                                            width : 100
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'From',
+                                                            name : 'shiphead_location_id_location_name',
+                                                            readOnly : true,
+                                                            width : 270
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'To',
+                                                            name : 'shiphead_shipto_id_shipto_name',
+                                                            width : 270
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Via',
+                                                            name : 'shiphead_shipvia',
+                                                            width : 270
+                                                        },
+                                                        {
+                                                            xtype: 'TextField',
+                                                            xns: Roo.form,
+                                                            fieldLabel : 'Tracking',
+                                                            name : 'shiphead_tracknum',
+                                                            width : 270
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Column',
+                                    xns: Roo.form,
+                                    width : 350,
+                                    items : [
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            hideLabels : true,
+                                            legend : "Delivery Notes",
+                                            style : 'width:330px',
+                                            items : [
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Delivery Notes',
+                                                    name : 'shiphead_delivery_note',
+                                                    width : 320
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            xtype: 'FieldSet',
+                                            xns: Roo.form,
+                                            hideLabels : true,
+                                            legend : "Shipment Notes",
+                                            style : 'width:330px',
+                                            items : [
+                                                {
+                                                    xtype: 'TextArea',
+                                                    xns: Roo.form,
+                                                    fieldLabel : 'Shipment Notes',
+                                                    name : 'shiphead_notes',
+                                                    width : 320
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_order_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_sfstatus',
+                                    value : "N"
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_location_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_shipto_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_id',
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shipitems',
+                                    width : 100
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.panel = this;
+                            
+                            if (_this.isBuilder) {
+                                return;
+                            }
+                            
+                           
+                            if (_this.grid) {
+                                _this.grid.ds.load({});
+                            }
+                        }
+                    },
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'coitem',
+                    title : "Order Items",
+                    grid : {
+                        xtype: 'EditorGrid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.grid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                if (_this.panel.active) {
+                                   this.ds.load({});
+                                }
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                                
+                            },
+                            afteredit : function (e)
+                            {
+                                //Roo.log('afteredit');
+                               // Roo.log(e);
+                                if (e.field == 'item_number') {
+                                    // afterselect handles this...
+                                    return;
+                                }
+                                e.record.commit();
+                            }
+                        },
+                        autoExpandColumn : 'item_descrip1',
+                        clicksToEdit : 1,
+                        loadMask : true,
+                        sm : {
+                            xtype: 'CellSelectionModel',
+                            xns: Roo.grid,
+                            listeners : {
+                                tabend : function (_self)
+                                {
+                                    _this.addItemBtn.fireEvent('click', _this.addItemBtn);
+                                }
+                            },
+                            enter_is_tab : true
+                        },
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self,o) {
+                                    if (! _this.form.findField('shiphead_order_id').getValue()) {
+                                        return false;
+                                    }
+                                    o.params = o.params || {};
+                                    
+                                    o.params.coitem_cohead_id = _this.form.findField('shiphead_order_id').getValue();
+                                    o.params.limit = 999;
+                                    o.params._stocked_only = 1;
+                                    o.params.shiphead_id = _this.form.findField('shiphead_id').getValue();
+                                    o.params.coitem_shipto_id = _this.form.findField('shiphead_shipto_id').getValue();
+                                    o.params['query[coitem_location_src]'] = _this.form.findField('shiphead_location_id').getValue();
+                                     
+                                    
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'coitem_linenumber', direction: 'ASC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/coitem.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                totalProperty : 'total',
+                                root : 'data',
+                                id : 'id',
+                                fields : [
+                                    {
+                                        'name': 'coitem_linenumber',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_itemsite_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyord'
+                                    },
+                                    {
+                                        'name': 'coitem_unitcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price'
+                                    },
+                                    {
+                                        'name': 'coitem_custprice'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreturned'
+                                    },
+                                    {
+                                        'name': 'coitem_prcost'
+                                    },
+                                    {
+                                        'name': 'coitem_price_uom_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'coitem_qtyreserved'
+                                    }
+                                ]
+                            }
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.grid.ds.each(function(r) {
+                                                r.set('shipitem_qty', Math.max(r.data.coitem_qtyord - r.data.shipitem_shipped));
+                                            });
+                                        }
+                                    },
+                                    text : "Fullfill all"
+                                },
+                                {
+                                    xtype: 'Separator',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'TextItem',
+                                    xns: Roo.Toolbar,
+                                    text : "Restore From"
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    listeners : {
+                                        select : function (combo, record, index)
+                                        {
+                                          //_this.grid.footer.onClick('first');
+                                          
+                                           (function() { 
+                                            combo.setValue('');
+                                           }).defer(100);
+                                           var data = record.json.data;
+                                           
+                                           _this.grid.ds.each(function (r) {
+                                                if (typeof(data[r.data.coitem_itemsite_id+'']) == 'undefined') {
+                                                    return;
+                                                }
+                                                r.set('shipitem_qty', parseInt(data[r.data.coitem_itemsite_id+'']));
+                                           
+                                           });
+                                           
+                                           
+                                           
+                                          
+                                        }
+                                    },
+                                    allowBlank : true,
+                                    displayField : 'name',
+                                    editable : false,
+                                    emptyText : "Restore from",
+                                    forceSelection : true,
+                                    listWidth : 300,
+                                    loadingText : "Searching...",
+                                    name : 'name',
+                                    pageSize : 20,
+                                    qtip : "Select Action",
+                                    queryParam : 'query[action]',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'name',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                                o.params = o.params || {};
+                                                // staff can see all logs, other companies can only see their own.
+                                                 
+                                                o.params._stash = _this.form.findField('shiphead_order_id').getValue();
+                                            
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'action' , direction : 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/Shiphead.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'name',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {
+                                                    'name': 'name',
+                                                    'type': 'string'
+                                                }
+                                             
+                                            ]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                             _this.grid.ds.each(function(r) {
+                                                r.set('shipitem_qty', 0);
+                                            });
+                                        }
+                                    },
+                                    text : "Reset"
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'coitem_linenumber',
+                                header : 'Item#',
+                                sortable : true,
+                                width : 75,
+                                renderer : function(v,x,r) {
+                                    if (r.data.coitem_subnumber * 1 > 0)  {
+                                         return String.format('{0}.{1}', v, r.data.coitem_subnumber ); 
+                                     }
+                                     return String.format('{0}', v); 
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_number',
+                                header : 'Item Code',
+                                sortable : true,
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'item_descrip1',
+                                header : 'Item Description',
+                                width : '150.00',
+                                renderer : function(v, x, r) {
+                                
+                                    var vv = v;
+                                    if (r.data.coitem_memo && r.data.coitem_memo.length) {
+                                        vv = r.data.coitem_memo;
+                                    }
+                                    return String.format('{0}', vv); 
+                                 
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'coitem_qtyord',
+                                header : 'Ordered Qty',
+                                width : 100,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'shipitem_shipped',
+                                header : 'Remaining Qty',
+                                width : 100,
+                                renderer : function(v,x,r) {
+                                
+                                     return String.format('{0}', r.data.coitem_qtyord - v); 
+                                 }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                align : 'right',
+                                dataIndex : 'shipitem_qty',
+                                header : 'Ship Qty',
+                                width : 100,
+                                renderer : function(v,x,r) { 
+                                    
+                                    var vv = parseInt(v);
+                                    vv = isNaN(vv) ? 0 : vv;
+                                    r.data.shipitem_qty = vv; // get rid of decimal.
+                                    if (r.data.shipitem_shipped + vv > r.data.coitem_qtyord) {
+                                            return String.format('<b style="background-color:red;color:yellow">{0}</b>', vv); 
+                                    }
+                                    // not fully fullfilled
+                                    if (r.data.shipitem_shipped + vv != r.data.coitem_qtyord) {
+                                            return String.format('<b style="background-color:blue;color:yellow">{0}</b>', vv); 
+                                    }   
+                                    return String.format('{0}', vv); 
+                                    
+                                },
+                                editor : {
+                                    xtype: 'GridEditor',
+                                    xns: Roo.grid,
+                                    field : {
+                                        xtype: 'NumberField',
+                                        xns: Roo.form,
+                                        allowDecimals : true,
+                                        allowNegative : false,
+                                        decimalPrecision : 0,
+                                        minValue : 0,
+                                        style : 'text-align:right'
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            north : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                height : 230
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                             Roo.Ajax.timeout = 120000; // 2 minutes timeout..
+                             var ar = [];
+                        
+                            _this.grid.ds.each(function(r) {
+                                ar.push({
+                                    shipitem_orderitem_id : r.data.coitem_id,
+                                    shipitem_qty : r.data.shipitem_qty 
+                                });
+                                
+                            });
+                            
+                            _this.form.findField('shipitems').setValue(JSON.stringify(ar));
+                            _this.form.doAction("submit");
+                            
+                        },
+                        render : function (_self)
+                        {
+                         _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleShipmentNew.bjs b/Pman.Dialog.XtupleShipmentNew.bjs
new file mode 100644 (file)
index 0000000..b842710
--- /dev/null
@@ -0,0 +1,187 @@
+{
+    "id": "roo-file-301",
+    "name": "Pman.Dialog.XtupleShipmentNew",
+    "parent": false,
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleShipmentNew.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    _this.form.findField('shiphead_location_id').focus();\n}"
+            },
+            "closable": false,
+            "height": 130,
+            "modal": true,
+            "resizable": false,
+            "title": "Create new Shipment",
+            "width": 500,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "rendered": "function (form)\n{\n  _this.form = form;\n}",
+                                "actioncomplete": "function (_self, action)\n{\n    if (action.type == 'setdata') {\n        // see if there are multiple possilbe targets\n        new Pman.Request({\n            url : baseURL + '/Roo/cohead',\n            method : 'GET',\n            params : {\n                cohead_id : _this.data.shiphead_order_id,\n                _has_multiple_ship : 1\n            },\n            success : function(res) {\n                // if there is one row returned, then assign values, and press OK\n                // otherwise.. cary on..\n                if (res.total === 1) {\n                    _this.form.setValues( {\n                    \n                        shiphead_location_id : res.data[0].coitem_location_src,\n                        shiphead_location_id_location_name : res.data[0].coitem_location_src_name,                        \n                        shiphead_shipto_id : res.data[0].coitem_shipto_id,\n                        shiphead_shipto_id_shipto_name : res.data[0].coitem_shipto_id_name\n                    });\n                    _this.okButton.fireEvent('click');\n                }\n                \n            },\n            failure : function(res) {\n\n                Roo.MessageBox.alert(\"Error\", res.errorMsg);\n                _this.dialog.hide();\n                \n            }\n        });\n            \n    \n    }\n  \n}"
+                            },
+                            "xtype": "Form",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "alwaysQuery": true,
+                                    "displayField": "location_name",
+                                    "editable": false,
+                                    "emptyText": "Select location",
+                                    "fieldLabel": "From Location",
+                                    "forceSelection": true,
+                                    "hiddenName": "shiphead_location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "shiphead_location_id_location_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select location",
+                                    "queryParam": "",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "location_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params['query[for_cohead_id]'] = _this.data.shiphead_order_id;\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/location.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "alwaysQuery": true,
+                                    "displayField": "shipto_name",
+                                    "editable": false,
+                                    "emptyText": "Select Ship to name",
+                                    "fieldLabel": "To",
+                                    "forceSelection": true,
+                                    "hiddenName": "shiphead_shipto_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "shiphead_shipto_id_shipto_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Ship to name",
+                                    "queryParam": "",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{shipto_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "shipto_id",
+                                    "width": 300,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params['query[for_cohead_id]'] = _this.data.shiphead_order_id;\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'shipto_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/shiptoinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"shipto_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "name": "shiphead_order_id",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "name": "shiphead_shipdate",
+                                    "xtype": "Hidden",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   _this.dialog.hide();\n \n }"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   //_this.findField('cuinfo_\n   \n   // check if customer is filled in.\n   if (_this.form.findField('shiphead_location_id').getValue() < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select a source location\");\n        return;\n   }\n   if (_this.form.findField('shiphead_shipto_id').getValue() < 1) {\n        Roo.MessageBox.alert(\"Error\", \"Select where to ship to\");\n        return;\n   }\n\n     var rv = _this.form.getFieldValues();\n\n    \n    Pman.Dialog.XtupleShipment.show(rv ,\n        function() { \n              _this.dialog.hide();\n             _this.callback()\n        }\n    );\n    \n }",
+                        "render": "function (_self)\n{\n    _this.okButton = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "OK",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleShipmentNew.js b/Pman.Dialog.XtupleShipmentNew.js
new file mode 100644 (file)
index 0000000..92ee4c0
--- /dev/null
@@ -0,0 +1,274 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleShipmentNew = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    _this.form.findField('shiphead_location_id').focus();
+                }
+            },
+            closable : false,
+            height : 130,
+            modal : true,
+            resizable : false,
+            title : "Create new Shipment",
+            width : 500,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                  _this.form = form;
+                                },
+                                actioncomplete : function (_self, action)
+                                {
+                                    if (action.type == 'setdata') {
+                                        // see if there are multiple possilbe targets
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/cohead',
+                                            method : 'GET',
+                                            params : {
+                                                cohead_id : _this.data.shiphead_order_id,
+                                                _has_multiple_ship : 1
+                                            },
+                                            success : function(res) {
+                                                // if there is one row returned, then assign values, and press OK
+                                                // otherwise.. cary on..
+                                                if (res.total === 1) {
+                                                    _this.form.setValues( {
+                                                    
+                                                        shiphead_location_id : res.data[0].coitem_location_src,
+                                                        shiphead_location_id_location_name : res.data[0].coitem_location_src_name,                        
+                                                        shiphead_shipto_id : res.data[0].coitem_shipto_id,
+                                                        shiphead_shipto_id_shipto_name : res.data[0].coitem_shipto_id_name
+                                                    });
+                                                    _this.okButton.fireEvent('click');
+                                                }
+                                                
+                                            },
+                                            failure : function(res) {
+                                
+                                                Roo.MessageBox.alert("Error", res.errorMsg);
+                                                _this.dialog.hide();
+                                                
+                                            }
+                                        });
+                                            
+                                    
+                                    }
+                                  
+                                }
+                            },
+                            items : [
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    alwaysQuery : true,
+                                    displayField : 'location_name',
+                                    editable : false,
+                                    emptyText : "Select location",
+                                    fieldLabel : 'From Location',
+                                    forceSelection : true,
+                                    hiddenName : 'shiphead_location_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'shiphead_location_id_location_name',
+                                    pageSize : 20,
+                                    qtip : "Select location",
+                                    queryParam : '',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'location_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                o.params['query[for_cohead_id]'] = _this.data.shiphead_order_id;
+                                                // set more here
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'location_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/location.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ComboBox',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    alwaysQuery : true,
+                                    displayField : 'shipto_name',
+                                    editable : false,
+                                    emptyText : "Select Ship to name",
+                                    fieldLabel : 'To',
+                                    forceSelection : true,
+                                    hiddenName : 'shiphead_shipto_id',
+                                    listWidth : 400,
+                                    loadingText : "Searching...",
+                                    minChars : 2,
+                                    name : 'shiphead_shipto_id_shipto_name',
+                                    pageSize : 20,
+                                    qtip : "Select Ship to name",
+                                    queryParam : '',
+                                    selectOnFocus : true,
+                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{shipto_name}</b> </div>',
+                                    triggerAction : 'all',
+                                    typeAhead : true,
+                                    valueField : 'shipto_id',
+                                    width : 300,
+                                    store : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o){
+                                                o.params = o.params || {};
+                                                // set more here
+                                                 o.params['query[for_cohead_id]'] = _this.data.shiphead_order_id;
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { direction : 'ASC', field: 'shipto_name' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Roo/shiptoinfo.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [{"name":"id","type":"int"},{"name":"shipto_name","type":"string"}]
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_order_id'
+                                },
+                                {
+                                    xtype: 'Hidden',
+                                    xns: Roo.form,
+                                    name : 'shiphead_shipdate'
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           _this.dialog.hide();
+                         
+                         }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           //_this.findField('cuinfo_
+                           
+                           // check if customer is filled in.
+                           if (_this.form.findField('shiphead_location_id').getValue() < 1) {
+                                Roo.MessageBox.alert("Error", "Select a source location");
+                                return;
+                           }
+                           if (_this.form.findField('shiphead_shipto_id').getValue() < 1) {
+                                Roo.MessageBox.alert("Error", "Select where to ship to");
+                                return;
+                           }
+                        
+                             var rv = _this.form.getFieldValues();
+                        
+                            
+                            Pman.Dialog.XtupleShipment.show(rv ,
+                                function() { 
+                                      _this.dialog.hide();
+                                     _this.callback()
+                                }
+                            );
+                            
+                         },
+                        render : function (_self)
+                        {
+                            _this.okButton = _self;
+                        }
+                    },
+                    text : "OK"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleTransfer.bjs b/Pman.Dialog.XtupleTransfer.bjs
new file mode 100644 (file)
index 0000000..6dfd70c
--- /dev/null
@@ -0,0 +1,938 @@
+{
+    "id": "roo-file-33",
+    "name": "Pman.Dialog.XtupleTransfer",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleTransfer.bjs",
+    "items": [
+        {
+            "listeners": {
+                "show": "function (_self)\n{\n    this.layout.getRegion('center').showPanel(0);\n}"
+            },
+            "closable": false,
+            "collapsible": false,
+            "height": 660,
+            "modal": true,
+            "resizable": false,
+            "title": "Edit / Create Inventory Transfer",
+            "width": 800,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "*prop": "center",
+                    "tabPosition": "top",
+                    "xtype": "LayoutRegion",
+                    "|xns": "Roo"
+                },
+                {
+                    "region": "center",
+                    "title": "Inventory Transfer",
+                    "xtype": "NestedLayoutPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "BorderLayout",
+                            "*prop": "layout",
+                            "items": [
+                                {
+                                    "*prop": "north",
+                                    "height": 260,
+                                    "xtype": "LayoutRegion",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "LayoutRegion",
+                                    "*prop": "center"
+                                },
+                                {
+                                    "region": "north",
+                                    "xtype": "ContentPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|actioncomplete": "function(_self,action)\n{\n    if (action.type == 'setdata') {\n       //_this.dialog.el.mask(\"Loading\");\n       Roo.log('setdata');\n       Roo.log(_this.data);       \n       // reversal...\n       _this.grid.setColumns();\n       _this.saveBtn.show();            \n       if (_this.data.createFromRev) {\n            Roo.log('recvg');\n            this.load({ method: 'GET', params: { '_createFromRecv' : _this.data.createFromRev }});       \n            return;\n       \n       }\n       \n        if (_this.data.invhist_transfer_id) {\n        \n        \n            var tdb = baseURL.split('/').pop().split('.').shift();\n            if (tdb != _this.data._roo_office) {\n                this.el.mask('Remote Transfer - Read Only');\n                _this.grid.view.headerPanel.mask(\"\");\n                _this.uploadBtn.hide();\n                _this.saveBtn.hide();                \n            } else {\n                this.el.unmask();\n                _this.grid.view.headerPanel.unmask();\n                _this.uploadBtn.show();\n                _this.saveBtn.show();                \n            }\n            \n        \n        \n            this.load({ method: 'GET', params: {\n                 _id : _this.data.invhist_transfer_id,\n                 _roo_office  : _this.data._roo_office\n           }});\n            return;\n        } \n        _this.grid.ds.removeAll();\n        _this.form.setValues({\n            invhist_transfer_transdate : \n                    typeof(_this.data.invhist_transfer_transdate) == 'undefined' ? \n                            (new Date()).format('Y-m-d') :\n                            _this.data.invhist_transfer_transdate\n                        ,\n            invhist_transfer_number : 'AUTOMATIC',\n            _roo_office :  _this.data._roo_office\n        });\n        \n        if(_this.data._createReverse){\n            if(_this.grid){\n                new Pman.Request({\r\n                    url : baseURL + '/Roo/invhist_transfer_item',\r\n                    method : 'GET',\r\n                    params : {\r\n                        invhist_transfer_item_invhist_transfer_id : _this.data._createReverse,\r\n                        'query[at_location]' : _this.data.invhist_transfer_from,\n                        _requestMeta : 1,\n                        limit : 999,\n                        sort : 'invhist_transfer_item_line',\n                        dir : 'ASC'\r\n                    },\r\n                    success : function (res) \r\n                    {\n                        Roo.log('loadData');\n                        Roo.log(res); \r\n                       _this.grid.ds.loadData(res,false);\r\n                    }\r\n                });\n            }\n        }\n        \n        this.setValues({\n            invhist_transfer_salesrep_id : Pman.Login.authUser.salesrep.salesrep_id,\n            invhist_transfer_salesrep_id_salesrep_name : Pman.Login.authUser.salesrep.salesrep_name\n        });\n        \n        \n        if (typeof(_this.data._ns_autofill) != 'undefined') {\n            Roo.log(\"autofill: \" +  _this.data._ns_autofill);\n        \n           \n            var locid = _this.data._ns_autofill === 1 ?_this.data.invhist_transfer_to  : _this.data.invhist_transfer_from; \n            // clear it so it's not done again..\n            \n            Roo.log(\"locid: \" + locid);\n            \n             var rn = 0;\n             var addRow = function(r) {\n                    \n                    var nsQty = r.netsuite_qty*1;\n                    nsQty = nsQty < 1 ? 0 : nsQty;\n                    \n                    var ourQty = r.itemsite_qty *1;\n                    var addQty = 0;\n                    if (_this.data._ns_autofill === 1) {\n                        // then we are trying to transfer from somewhere to her, to increase the qty to match\n                        // so if  ourQty < nsQty\n                        if (ourQty < nsQty) {\n                            addQty = nsQty - ourQty;\n                        }\n                        \n                    } else {\n                        // we are trying to transfer out to get rid of stock to match..\n                        if (nsQty < ourQty) {\n                            addQty = ourQty - nsQty;\n                        }\n                    }\n                    \n                    if (addQty * 1 < 1) {\n                    \n                        return;\n                    }\n                    \n                   var nr = _this.grid.ds.reader.newRow({\n                        invhist_transfer_item_line : rn + 1,\n                        item_id : r.itemsite_item_id,    \n                        invhist_transfer_item_itemsite_id :         r.itemsite_id,    \n                        item_number : r.itemsite_item_id_item_number,\n                        item_descrip1 : r.itemsite_item_id_item_descrip1,\n                        invhist_transfer_item_qty : addQty,\n                        item_availqty : 0 \n                       // invhist_transfer_item_transfer_id : tid << we do not know this?!?\n                   });\n                     _this.grid.ds.insert(rn++, nr); \n                \n            };\n            \n            \n            \n            \n            // do the request..\n            new Pman.Request({\n                url : baseURL + '/Roo/itemsite',\n                mask: \"Fetching Stock Quantities\",\n                method : 'GET',\n                params : {\n                    limit : 99999,\n                    location_id : locid,\n                    _as_of : _this.data.invhist_transfer_transdate,\n                    _with_stock_and_value : 1,\n                    _with_ns_all_stock : 1,\n                    'sort' :  'itemsite_item_id_item_number',\n                    'dir' : 'ASC'\n                },\n                success : function(res) {\n                    Roo.log(res);\n                     Roo.each(res.data, addRow);\n                     _this.data._ns_autofill = undefined;\n                }\n            });\n        }\n        \n       return;\n    }\n    if (action.type == 'load') {\n    \n        // fix date..\n        this.findField('_roo_office').setValue(  _this.data._roo_office );\n        Roo.log(action);\n        _this.data = action.result.data;\n        if(_this.data.invhist_transfer_void){\n            _this.saveBtn.hide();\n        }\n        var dt = Date.parseDate(_this.data.invhist_transfer_transdate.split(' ')[0], \"Y-m-d\");\n        _this.form.findField('invhist_transfer_transdate').setValue(dt);\n        var dt = Date.parseDate(_this.data.invhist_transfer_arrivaldate.split(' ')[0],\"Y-m-d\");\n        _this.form.findField('invhist_transfer_arrivaldate').setValue(dt);\n        _this.grid.ds.load({});\n        \n        return;\n    }\n    if (action.type =='submit') {\n    \n        \n        _this.dialog.hide();\n    \n         if (_this.callback) {\n            _this.callback.call(_this, _this.form.getValues());\n         }\n         _this.form.reset();\n         return;\n    }\n}\n",
+                                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                                            },
+                                            "method": "POST",
+                                            "style": "margin:10px;",
+                                            "xtype": "Form",
+                                            "|url": "baseURL + '/Xtuple/Roo/invhist_transfer.php'",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "width": 400,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "legend": "Transfer Details",
+                                                            "style": "width: 380px;height:220px;",
+                                                            "xtype": "FieldSet",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "allowBlank": false,
+                                                                    "fieldLabel": "Date",
+                                                                    "format": "Y-m-d",
+                                                                    "name": "invhist_transfer_transdate",
+                                                                    "width": 100,
+                                                                    "xtype": "DateField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "allowBlank": true,
+                                                                    "fieldLabel": "Arrival date",
+                                                                    "format": "Y-m-d",
+                                                                    "name": "invhist_transfer_arrivaldate",
+                                                                    "width": 100,
+                                                                    "xtype": "DateField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "fieldLabel": "Reference #",
+                                                                    "name": "invhist_transfer_number",
+                                                                    "readOnly": true,
+                                                                    "width": 200,
+                                                                    "xtype": "TextField",
+                                                                    "|xns": "Roo.form"
+                                                                },
+                                                                {
+                                                                    "allowBlank": true,
+                                                                    "displayField": "salesrep_name",
+                                                                    "editable": false,
+                                                                    "emptyText": "Select salesrep",
+                                                                    "fieldLabel": "Sales Rep",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "invhist_transfer_salesrep_id",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "invhist_transfer_salesrep_id_salesrep_name",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select salesrep",
+                                                                    "queryParam": "query[salesrep_name]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "typeAhead": true,
+                                                                    "valueField": "salesrep_id",
+                                                                    "width": 250,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'salesrep_name' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "method": "GET",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "|url": "baseURL + '/Roo/salesrep.php'"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "id": "salesrep_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"},\"salesrep_name\"]"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "render": "function (_self)\n{\n    _this.fromLocation = _self;\n}"
+                                                                    },
+                                                                    "allowBlank": false,
+                                                                    "displayField": "location_descrip",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select location",
+                                                                    "fieldLabel": "From Location",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "invhist_transfer_from",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "invhist_transfer_from_location_descrip",
+                                                                    "pageSize": 200,
+                                                                    "qtip": "Select location",
+                                                                    "queryParam": "query[location_name]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> - {location_descrip} </div>",
+                                                                    "triggerAction": "all",
+                                                                    "valueField": "location_id",
+                                                                    "width": 250,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n \n        o.params._notinternalcompany = 1;\n \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "id": "id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "select": "function (combo, record, index)\n{\n    combo._is_internalcompany = false;\n    \n    if(record.data.cust_to_internalcompany.length){\n        combo._is_internalcompany = true;\n    }\n    \n    _this.grid.setColumns();\n}",
+                                                                        "render": "function (_self)\n{\n    _this.toLocation = _self;\n}"
+                                                                    },
+                                                                    "allowBlank": false,
+                                                                    "displayField": "location_descrip",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select location",
+                                                                    "fieldLabel": "To Location",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "invhist_transfer_to",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "invhist_transfer_to_location_descrip",
+                                                                    "pageSize": 200,
+                                                                    "qtip": "Select location",
+                                                                    "queryParam": "query[location_name]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b>  - <b style=\"color:red\">{location_cust_id_char_internalcompany} </b> {location_descrip} </div>",
+                                                                    "triggerAction": "all",
+                                                                    "valueField": "location_id",
+                                                                    "width": 250,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.location_restrict = 0;\n    o.params._with_internalcompany = 1;\n    \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|xns": "Roo.data",
+                                                                                    "id": "id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "style": "margin-left: 10px; float: left;",
+                                                    "width": 280,
+                                                    "xtype": "Column",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "hideLabels": true,
+                                                            "legend": "Transfer Delivery Note Reference",
+                                                            "style": "width: 260px",
+                                                            "xtype": "FieldSet",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "invhist_transfer_delivery_note",
+                                                                    "name": "invhist_transfer_delivery_note",
+                                                                    "width": 250,
+                                                                    "xtype": "TextArea",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "hideLabels": true,
+                                                            "legend": "Transfer Description",
+                                                            "style": "width: 260px",
+                                                            "xtype": "FieldSet",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "fieldLabel": "invhist_transfer_descrip",
+                                                                    "name": "invhist_transfer_descrip",
+                                                                    "width": 250,
+                                                                    "xtype": "TextArea",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "Row",
+                                                            "items": [
+                                                                {
+                                                                    "allowBlank": true,
+                                                                    "displayField": "desc",
+                                                                    "editable": false,
+                                                                    "fieldLabel": "Transfer Price",
+                                                                    "hiddenName": "invhist_transfer_price",
+                                                                    "listWidth": 200,
+                                                                    "mode": "local",
+                                                                    "name": "invhist_transfer_price_desc",
+                                                                    "triggerAction": "all",
+                                                                    "value": "",
+                                                                    "valueField": "code",
+                                                                    "width": 150,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "store",
+                                                                            "xtype": "SimpleStore",
+                                                                            "|data": "[ \n    [ 'PRICELIST', \"At Transfer Price\"],\n    [ 'LASTPLUS' , \"Last Purchase +10% + 15% or stdcost +15%\"],\n    [ 'STDCOST' , \"stdcost - for old transfers only%\"]\n\n]\n",
+                                                                            "|fields": "[  'code', 'desc']",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "name": "transfer_items",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "_roo_office",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "name": "invhist_transfer_id",
+                                                    "xtype": "Hidden",
+                                                    "|xns": "Roo.form"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.ds.load({});\n    }\n}"
+                                    },
+                                    "fitContainer": true,
+                                    "fitToframe": true,
+                                    "region": "center",
+                                    "tableName": "invhist_transfer_item",
+                                    "title": "invhist_transfer_item",
+                                    "xtype": "GridPanel",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.ds.load({});\n    }\n}",
+                                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                                                "beforeedit": "function (e)\n{\n    if(_this.data.invhist_transfer_posted){\n        Roo.MessageBox.alert('Error', 'This transfer has been posted');\n        return false;\n    }\n    if(_this.data.invhist_transfer_void){\n        Roo.MessageBox.alert('Error', 'This transfer has been voided');\n        return false;\n    }\n    \n    if(e.field == 'invhist_transfer_item_unit_price' && (!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length) && !_this.toLocation._is_internalcompany){\n        Roo.MessageBox.alert('Error', 'Not a inter-comany transfer');\n        return false;\n    }\n    \n    \n    \n}"
+                                            },
+                                            "*prop": "grid",
+                                            "autoExpandColumn": "item_descrip1",
+                                            "clicksToEdit": 1,
+                                            "loadMask": true,
+                                            "xtype": "EditorGrid",
+                                            "|setColumns": "function() {\n    var cm = _this.grid.getColumnModel();\n    \n    function cid(str) {\n        return cm.getIndexByDataIndex(str);\n    }\n    \n    if((!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length) && !_this.toLocation._is_internalcompany){\n        cm.setHidden(cid('invhist_transfer_item_unit_price'), true);\n        cm.setHidden(cid('invhist_transfer_item_unit_price_default'), true);\n        return;\n    }\n    \n    cm.setHidden(cid('invhist_transfer_item_unit_price'), false);\n    cm.setHidden(cid('invhist_transfer_item_unit_price_default'), false);\n}\n",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "tabend": "function (_self)\n{\n    _this.addItemBtn.fireEvent('click', _this.addItemBtn);\n}"
+                                                    },
+                                                    "*prop": "sm",
+                                                    "xtype": "CellSelectionModel",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "beforeload": "function (_self, o)\n{\n   \n    o.params = o.params || {};\n    if (!_this.form) {\n        return false;\n    }\n    \n    o.params.invhist_transfer_item_invhist_transfer_id = _this.form.findField('invhist_transfer_id').getValue() * 1;\n    \n    if ( !o.params.invhist_transfer_item_invhist_transfer_id) {\n        _this.grid.ds.removeAll();\n        return false;\n    }\n\n    o.params['query[at_location]'] = _this.form.findField('invhist_transfer_from').getValue();\n    o.params.limit = 999;\n    o.params._roo_office =  _this.form.findField('_roo_office').getValue();\n    \n    _this.grid.setColumns();\n        \n    if(!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length){\n        return;\n    }\n    \n    o.params._inter_transfer = 1;    \n\n    \n    \n}"
+                                                    },
+                                                    "*prop": "dataSource",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ field : 'invhist_transfer_item_line', direction: 'ASC' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Xtuple/Roo/invhist_transfer_item.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\n    {\n        'name': 'invhist_transfer_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_item_invhist_transfer_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_item_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_item_qty',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_item_line',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_invhist_id',\n        'type': 'int'\n    }, \n    'item_id',\n    'item_number',    \n    'item_descrip1',\n    'avail_at_location'\n    \n    \n]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "toolbar",
+                                                    "xtype": "Toolbar",
+                                                    "|xns": "Roo",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n    \n     if (_this.data.invhist_transfer_posted) {\n        Roo.MessageBox.alert(\"Error\", \"Transfer has been posted, void it first\");\n        return;\n    }\n    \n    // work out last \n    var grid = _this.grid;\n    var last = 0;\n    \n    _this.grid.ds.each(function(r) {\n        last = r.data.invhist_transfer_item_line;\n    });\n    \n    last++;\n    \n    var nr = _this.grid.ds.reader.newRow({\n        invhist_transfer_item_line : last,\n        item_number : '',\n        item_descrip1 : '',\n        invhist_transfer_item_qty : 0,\n        item_availqty : 0,\n        invhist_transfer_item_transfer_id : _this.form.findField('invhist_transfer_id').getValue()\n   });\n\n    grid.stopEditing();\n    grid.ds.insert(grid.ds.getCount(), nr); \n    grid.startEditing(grid.ds.getCount()-1, 1); // type..\n}\n",
+                                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Add",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Fill based on Stock",
+                                                            "xtype": "Button",
+                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                            "|xns": "Roo.Toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Menu",
+                                                                    "*prop": "menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|click": "function()\n{\n    var    rn =      _this.grid.ds.getCount();\n    var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();\n    var addRow = function(r) {\n    \n        if (r.itemsite_qty * 1 < 1) {\n        \n            return;\n            }\n      var nr = _this.grid.ds.reader.newRow({\n            invhist_transfer_item_line : rn + 1,\n            item_id : r.itemsite_item_id,    \n            invhist_transfer_item_itemsite_id :         r.itemsite_id,    \n            item_number : r.itemsite_item_id_item_number,\n            item_descrip1 : r.itemsite_item_id_item_descrip1,\n            invhist_transfer_item_qty : r.itemsite_qty,\n            item_availqty : 0,\n            invhist_transfer_item_transfer_id : tid\n       });\n         _this.grid.ds.insert(rn++, nr); \n    \n    };\n     \n    var loc  = _this.form.findField('invhist_transfer_from').getValue()*1;\n    var dt  = _this.form.findField('invhist_transfer_transdate').getValue().format('Y-m-d');    \n    \n    _this.grid.stopEditing();\n    \n    new Pman.Request({\n        url :  baseURL + '/Roo/itemsite',\n        mask : 'Fetching stock',\n        method : 'GET',\n        params : {\n            limit : 2000, // alot!\n            _with_stock_and_value : 1,\n            _viewtype : 1,\n            location_id : loc,\n            _as_of : dt,\n            'sort' : 'itemsite_item_id_item_number',\n            'dir'  : 'ASC'\n        },\n        success : function(r) {\n            Roo.log(r);\n            Roo.each(r.data, addRow);\n            \n        \n        }\n    \n    });\n\n    \n\n    \n\n    \n     \n}\n",
+                                                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Transfer all from Location",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|click": "function()\n{\n var    rn =      _this.grid.ds.getCount();\n        var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();\n        \n        \n        var addRow = function(r) {\n        \n            if (r.itemsite_qty * 1 > -1) {\n            \n                return;\n            }\n          var nr = _this.grid.ds.reader.newRow({\n                invhist_transfer_item_line : rn + 1,\n                item_id : r.itemsite_item_id,    \n                invhist_transfer_item_itemsite_id :         r.itemsite_id,    \n                item_number : r.itemsite_item_id_item_number,\n                item_descrip1 : r.itemsite_item_id_item_descrip1,\n                invhist_transfer_item_qty : Math.abs(r.itemsite_qty),\n                item_availqty : 0,\n                invhist_transfer_item_transfer_id : tid\n           });\n             _this.grid.ds.insert(rn++, nr); \n        \n        };\n         \n        var loc  = _this.form.findField('invhist_transfer_to').getValue()*1;\n        var dt  = _this.form.findField('invhist_transfer_transdate').getValue().format('Y-m-d');    \n        \n        _this.grid.stopEditing();\n        \n        new Pman.Request({\n            url :  baseURL + '/Roo/itemsite',\n            mask : 'Fetching stock',\n            method : 'GET',\n            params : {\n                limit : 2000, // alot!\n                _with_stock_and_value : 1,\n                _viewtype : -1,\n                location_id : loc,\n                _as_of : dt,\n                'sort' : 'itemsite_item_id_item_number',\n                'dir'  : 'ASC'\n            },\n            success : function(r) {\n                Roo.log(r);\n                Roo.each(r.data, addRow);\n                \n            \n            }\n        \n        });\n    \n    \n\n    \n\n    \n     \n}\n",
+                                                                                "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                                                            },
+                                                                            "cls": "x-btn-text-icon",
+                                                                            "text": "Fill negative at Target",
+                                                                            "xtype": "Item",
+                                                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                            "|xns": "Roo.menu"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "|click": "function()\n{\n     _this.grid.stopEditing();     \n\n     if (_this.data.invhist_transfer_posted) {\n        Roo.MessageBox.alert(\"Error\", \"Transfer has been posted, void it first\");\n        return;\n    }\n\n    var rc= _this.grid.selModel.getSelectedCell();\n     if (!rc) {\n        Roo.MessageBox.alert(\"Error\", \"Select a item to delete\");\n        return;\n     }\n         \n     var rec = _this.grid.ds.getAt(rc[0]);\n     _this.grid.ds.remove(rec);\n     \n\n    rec = _this.grid.ds.getAt(rc[0]);\n    if (rec) {\n        _this.grid.selModel.select(rc[0], 2);\n        return;\n    }\n    var ln = rc[0]-1;\n    if (ln < 0) {\n      return;\n    } // nothing left to select..\n    _this.grid.selModel.select(rc[0]-1, 2);\n     \n    \n    \n    \n}\n        "
+                                                            },
+                                                            "cls": "x-btn-text-icon",
+                                                            "text": "Delete",
+                                                            "xtype": "Button",
+                                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "invhist_transfer_item_line",
+                                                    "header": "Line",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    ".builderCfg": "{\"table\":\"coitem\",\"column\":\"coitem_itemsite_id\",\"columnshort\":\"coitem_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\",\"maps_to\":\"itemsite_id\",\"deps\":[{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_item_id\",\"columnshort\":\"itemsite_item_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warehous_id\",\"columnshort\":\"itemsite_warehous_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_qtyonhand\",\"columnshort\":\"itemsite_qtyonhand\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_reorderlevel\",\"columnshort\":\"itemsite_reorderlevel\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordertoqty\",\"columnshort\":\"itemsite_ordertoqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cyclecountfreq\",\"columnshort\":\"itemsite_cyclecountfreq\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastcount\",\"columnshort\":\"itemsite_datelastcount\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_datelastused\",\"columnshort\":\"itemsite_datelastused\",\"ctype\":\"date\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_loccntrl\",\"columnshort\":\"itemsite_loccntrl\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_safetystock\",\"columnshort\":\"itemsite_safetystock\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_minordqty\",\"columnshort\":\"itemsite_minordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_multordqty\",\"columnshort\":\"itemsite_multordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_leadtime\",\"columnshort\":\"itemsite_leadtime\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_abcclass\",\"columnshort\":\"itemsite_abcclass\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_issuemethod\",\"columnshort\":\"itemsite_issuemethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_controlmethod\",\"columnshort\":\"itemsite_controlmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_active\",\"columnshort\":\"itemsite_active\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_plancode_id\",\"columnshort\":\"itemsite_plancode_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costcat_id\",\"columnshort\":\"itemsite_costcat_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_eventfence\",\"columnshort\":\"itemsite_eventfence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_sold\",\"columnshort\":\"itemsite_sold\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_stocked\",\"columnshort\":\"itemsite_stocked\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_freeze\",\"columnshort\":\"itemsite_freeze\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_id\",\"columnshort\":\"itemsite_location_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparams\",\"columnshort\":\"itemsite_useparams\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_useparamsmanual\",\"columnshort\":\"itemsite_useparamsmanual\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_soldranking\",\"columnshort\":\"itemsite_soldranking\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createpr\",\"columnshort\":\"itemsite_createpr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location\",\"columnshort\":\"itemsite_location\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_location_comments\",\"columnshort\":\"itemsite_location_comments\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_notes\",\"columnshort\":\"itemsite_notes\",\"ctype\":\"text\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_perishable\",\"columnshort\":\"itemsite_perishable\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_nnqoh\",\"columnshort\":\"itemsite_nnqoh\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoabcclass\",\"columnshort\":\"itemsite_autoabcclass\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup\",\"columnshort\":\"itemsite_ordergroup\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_disallowblankwip\",\"columnshort\":\"itemsite_disallowblankwip\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_maxordqty\",\"columnshort\":\"itemsite_maxordqty\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_mps_timefence\",\"columnshort\":\"itemsite_mps_timefence\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createwo\",\"columnshort\":\"itemsite_createwo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_warrpurc\",\"columnshort\":\"itemsite_warrpurc\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_autoreg\",\"columnshort\":\"itemsite_autoreg\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_costmethod\",\"columnshort\":\"itemsite_costmethod\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_value\",\"columnshort\":\"itemsite_value\",\"ctype\":\"numeric\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_ordergroup_first\",\"columnshort\":\"itemsite_ordergroup_first\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_supply_itemsite_id\",\"columnshort\":\"itemsite_supply_itemsite_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_planning_type\",\"columnshort\":\"itemsite_planning_type\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_wosupply\",\"columnshort\":\"itemsite_wosupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_posupply\",\"columnshort\":\"itemsite_posupply\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_lsseq_id\",\"columnshort\":\"itemsite_lsseq_id\",\"ctype\":\"int4\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_cosdefault\",\"columnshort\":\"itemsite_cosdefault\",\"ctype\":\"bpchar\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopr\",\"columnshort\":\"itemsite_createsopr\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_createsopo\",\"columnshort\":\"itemsite_createsopo\",\"ctype\":\"bool\",\"desc\":\"\"},{\"table\":\"itemsite\",\"column\":\"coitem_itemsite_id_itemsite_dropship\",\"columnshort\":\"itemsite_dropship\",\"ctype\":\"bool\",\"desc\":\"\"}],\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                                                    "dataIndex": "item_id",
+                                                    "header": "Item Code",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    return String.format('{0}', r.data.item_number);\n }",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.grid",
+                                                            "xtype": "GridEditor",
+                                                            "*prop": "editor",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "beforeselect": "function (combo, record, index)\n{\n  // set _this.data values ..\n  var ar = _this.grid.activeEditor.record;\n  //Roo.log('beforeselect');\n  (function() { \n     //  Roo.log('beforeselect-cb');\n      ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);\n     // ar.set('coitem_price', record.data.item_listprice);\n     // ar.set('coitem_custprice', record.data.item_price);\n       ar.set('invhist_transfer_item_itemsite_id', record.data.itemsite_id);\n      ar.set('item_number', record.data.itemsite_item_id_item_number);\n      ar.set('avail_at_location', record.data.avail_at_location);\n      ar.commit();\n  }).defer(100);\n  \n}"
+                                                                    },
+                                                                    "*prop": "field",
+                                                                    "allowBlank": false,
+                                                                    "displayField": "itemsite_item_id_item_number",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select item",
+                                                                    "forceSelection": true,
+                                                                    "hiddenName": "itemsite_item_id_item_number",
+                                                                    "listWidth": 400,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "name": "item_number",
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select item",
+                                                                    "queryParam": "query[number]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b>  {itemsite_item_id_item_descrip1} ({avail_at_location})</div>",
+                                                                    "triggerAction": "all",
+                                                                    "valueField": "item_number",
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n    o.params['query[at_location]'] = _this.form.findField('invhist_transfer_from').getValue();\n    \n}\n"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ direction : 'ASC', field: 'itemsite_item_id_item_number' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "shipto_id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[{\"name\":\"item_id\",\"type\":\"int\"},\"item_number\"]",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "dataIndex": "item_descrip1",
+                                                    "header": "Description",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "avail_at_location",
+                                                    "header": "Cur. Avail",
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { return String.format('{0}', v); }",
+                                                    "|xns": "Roo.grid"
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invhist_transfer_item_qty",
+                                                    "header": "Qty",
+                                                    "width": "50.00",
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) { \n    var vv = parseInt(v);\n    //var aq = parseInt(r.data.avail_qty);\n    //aq = isNaN(aq) ? 0 : aq;\n   \n   \n   \n   \n    return String.format('{0}', vv.toFixed(0)); \n    \n}",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "editor",
+                                                            "xtype": "GridEditor",
+                                                            "|xns": "Roo.grid",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "field",
+                                                                    "allowDecimals": false,
+                                                                    "decimalPrecision": 0,
+                                                                    "minValue": 1,
+                                                                    "style": "text-align:right",
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invhist_transfer_item_unit_price",
+                                                    "header": "Unit Price",
+                                                    "hidden": true,
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{ \n    if(!v && v !== 0){\n        return '';\n    }\n    var color = '#666'; // orignal color\n    \n    if(r.data.invhist_transfer_item_unit_price_default != v){\n        color = 'red';\n    }\n    \n    return String.format('<span style=\"color:{0};\">{1} {2}</span>', color, (r.data.invhist_transfer_item_curr_name) ? r.data.invhist_transfer_item_curr_name : '' , Roo.util.Format.number(v,2)); \n}",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.grid",
+                                                            "xtype": "GridEditor",
+                                                            "*prop": "editor",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "field",
+                                                                    "allowBlank": false,
+                                                                    "allowDecimals": true,
+                                                                    "decimalPrecision": 2,
+                                                                    "style": "text-align:right",
+                                                                    "xtype": "NumberField",
+                                                                    "|xns": "Roo.form"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "*prop": "colModel[]",
+                                                    "align": "right",
+                                                    "dataIndex": "invhist_transfer_item_unit_price_default",
+                                                    "header": "Default Price",
+                                                    "hidden": true,
+                                                    "width": 75,
+                                                    "xtype": "ColumnModel",
+                                                    "|renderer": "function(v,x,r) \n{ \n    if(!v && v !== 0){\n        return '';\n    }\n    return String.format('{0} {1}', (r.data.invhist_transfer_item_curr_name) ? r.data.invhist_transfer_item_curr_name : '' , Roo.util.Format.number(v,2)); \n}",
+                                                    "|xns": "Roo.grid"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.ipanel = this;\n    if (_this.igrid) {\n        _this.igrid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": false,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "Images",
+                    "title": "Reference Files",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() { \n    _this.igrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    //if (_this.panel.active) {\n    //   this.footer.onClick('first');\n    //}\n}",
+                                "|rowdblclick": "function (_self, rowIndex, e)\n{\n  \n   var s =  _self.getDataSource().getAt(rowIndex);\n   new Pman.Download({\n        url : baseURL + '/Images/' + s.data.id\n         \n    });\n   \n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "id",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|beforeload": "function (_self, o)\n{\n    //o.params.ontable = 'Companies';\n    \n  //   o.params.imgtype = 'PressRelease';\n    \n    o.params = o.params || {};\n    o.params.onid = _this.form.findField('invhist_transfer_id').getValue();\n    o.params.ontable = 'invhist_transfer';\n    Roo.log(_this);\n    \n}",
+                                        "|load": "function (_self, records, options)\n{\n _this.panel.el.unmask();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field: 'created' , direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'filename',\n        'type': 'string'\n    },\n    {\n        'name': 'ontable',\n        'type': 'string'\n    },\n    {\n        'name': 'onid',\n        'type': 'int'\n    },\n    {\n        'name': 'mimetype',\n        'type': 'string'\n    },\n    {\n        'name': 'width',\n        'type': 'int'\n    },\n    {\n        'name': 'height',\n        'type': 'int'\n    },\n    {\n        'name': 'filesize',\n        'type': 'int'\n    },\n    {\n        'name': 'displayorder',\n        'type': 'int'\n    },\n    {\n        'name': 'language',\n        'type': 'string'\n    },\n    {\n        'name': 'parent_image_id',\n        'type': 'int'\n    },\n    {\n        'name': 'created',\n        'type': 'date',\n        'dateFormat' : 'Y-m-d H:i:s'\n    },\n    {\n        'name': 'imgtype',\n        'type': 'string'\n    },\n    {\n        'name': 'linkurl',\n        'type': 'string'\n    },\n    {\n        'name': 'descript',\n        'type': 'string'\n    },\n    {\n        'name': 'title',\n        'type': 'string'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "proxy",
+                                            "xtype": "HttpProxy",
+                                            "method": "GET",
+                                            "|url": "baseURL + '/Roo/Images.php'",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "xtype": "PagingToolbar",
+                                    "pageSize": 25,
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying Images  {0} - {1} of {2}",
+                                    "emptyMsg": "No Images found",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "toolbar",
+                                    "xtype": "Toolbar",
+                                    "|xns": "Roo",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n{\n            \n    //var sel = Pman.Tab.PressReleaseCompanies  ? Pman.Tab.PressReleaseCompanies.grid.getSelectionModel().getSelected() : false\n     \n    Pman.Dialog.Image.show({\n        id : 0, \n        ontable: 'invhist_transfer',\n        onid: _this.form.findField('invhist_transfer_id').getValue(),\n        imgtype : ''\n    }, function(data){\n        if (!data) { return; } \n        _this.igrid.footer.onClick('first');\n    }); \n\n}       "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Add",
+                                            "xtype": "Button",
+                                            "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function()\n        {\n        Pman.genericDelete(_this, 'Images'); \n        }\n        "
+                                            },
+                                            "cls": "x-btn-text-icon",
+                                            "text": "Delete",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "created",
+                                    "header": "Created",
+                                    "sortable": true,
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) {\n       return String.format('{0}<br/><i>{1}</i><br/>{2}<br/><i>{3}x{4}</i>',\n            v.format('d/M/Y'), r.data.mimetype, r.data.filename,\n    r.data.width, r.data.height\n    ); \n}\n     ",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "id",
+                                    "header": "Image",
+                                    "width": 100,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('<img src=\"{0}/Images/Thumb/100/{1}/{2}\" height=\"100\">', baseURL, v, r.data.filename); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "|activate": "function() {\n    _this.hpanel = this;\n    if (_this.hgrid) {\n        _this.hgrid.footer.onClick('first');\n    }\n}"
+                    },
+                    "background": true,
+                    "fitContainer": true,
+                    "fitToframe": true,
+                    "region": "center",
+                    "tableName": "events",
+                    "title": "History",
+                    "xtype": "GridPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|render": "function() \n{\n    _this.hgrid = this; \n    if (_this.hpanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                            },
+                            "*prop": "grid",
+                            "autoExpandColumn": "remarks",
+                            "loadMask": true,
+                            "xtype": "Grid",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "beforeload": "function (_self, options)\n{\n    options.params = options.params || {};\n    \n    options.params.on_table = 'invhist_transfer';\n    options.params.on_id = _this.form.findField('invhist_transfer_id').getValue();\n}"
+                                    },
+                                    "*prop": "dataSource",
+                                    "remoteSort": true,
+                                    "xtype": "Store",
+                                    "|sortInfo": "{ field : 'event_when', direction: 'DESC' }",
+                                    "|xns": "Roo.data",
+                                    "items": [
+                                        {
+                                            "*prop": "proxy",
+                                            "method": "GET",
+                                            "xtype": "HttpProxy",
+                                            "|url": "baseURL + '/Roo/events.php'",
+                                            "|xns": "Roo.data"
+                                        },
+                                        {
+                                            "*prop": "reader",
+                                            "id": "id",
+                                            "root": "data",
+                                            "totalProperty": "total",
+                                            "xtype": "JsonReader",
+                                            "|fields": "[\n    {\n        'name': 'event_when',\n        'type': 'date'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    }\n]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "*prop": "footer",
+                                    "displayInfo": true,
+                                    "displayMsg": "Displaying events{0} - {1} of {2}",
+                                    "emptyMsg": "No Events found",
+                                    "pageSize": 25,
+                                    "xtype": "PagingToolbar",
+                                    "|xns": "Roo"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "event_when",
+                                    "header": "Changed",
+                                    "width": 120,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "action",
+                                    "header": "Action",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "ipaddr",
+                                    "header": "IP Address",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "person_id_name",
+                                    "header": "Who",
+                                    "width": 75,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                },
+                                {
+                                    "*prop": "colModel[]",
+                                    "dataIndex": "remarks",
+                                    "header": "Notes",
+                                    "width": 200,
+                                    "xtype": "ColumnModel",
+                                    "|renderer": "function(v) { return String.format('{0}', v); }",
+                                    "|xns": "Roo.grid"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n   \n    var rn =      _this.grid.ds.getCount();\n    var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();\n    var addRow = function(r) {\n        if (r.itemsite_qty * 1 < 1) {\n            return;\n        }\n        \n        var nr = _this.grid.ds.reader.newRow({\n            invhist_transfer_item_line : rn + 1,\n            item_id : r.itemsite_item_id,    \n            invhist_transfer_item_itemsite_id : r.itemsite_id,    \n            item_number : r.itemsite_item_id_item_number,\n            item_descrip1 : r.itemsite_item_id_item_descrip1,\n            invhist_transfer_item_qty : r.itemsite_qty,\n            item_availqty : 0,\n            avail_at_location : '',\n            invhist_transfer_item_transfer_id : tid,\n            invhist_transfer_item_unit_price : r.unit_price,\n            invhist_transfer_item_unit_price_default : r.unit_price,\n        });\n        _this.grid.ds.insert(rn++, nr); \n    \n    };\n   \n    Pman.Dialog.Image.show(\n       {\n            _url : baseURL + '/Xtuple/Import/Transfer'\n        \n       },\n       function (r) {\n            Roo.log(r);\n            Roo.each(r.items, addRow);\n            \n            if (typeof(r.Date) !='undefined') {\n                _this.form.findField('invhist_transfer_transdate').setValue( Date.parseDate((r.Date) ? r.Date : (new Date()).format('Y-m-d'), \"Y-m-d\"));\n            }\n            if (typeof(r.ArrivalDate) !='undefined') {            \n                _this.form.findField('invhist_transfer_arrivaldate').setValue(Date.parseDate((r.ArrivalDate) ? r.ArrivalDate : (new Date()).format('Y-m-d'), \"Y-m-d\"));\n            }\n            if(r.invhist_transfer_from){\n                _this.fromLocation.setValue(r.invhist_transfer_from);\n                _this.fromLocation.el.dom.value = r.invhist_transfer_from_location_name;\n            }\n            if(r.invhist_transfer_to){\n                _this.toLocation.setValue(r.invhist_transfer_to);\n                _this.toLocation.el.dom.value = r.invhist_transfer_to_location_name;\n            }\n            \n            if(r.isInter == 1){\n                _this.toLocation._is_internalcompany = true;\n            }\n            _this.grid.setColumns();\r\n       }\n   );\n}",
+                        "render": "function (_self)\n{\n    _this.uploadBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Upload (Excel)",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n\n   new Pman.Download({\n        url : baseURL + '/Xtuple/Roo/invhist_transfer',\n        method : 'GET',\n        params : {\n            _roo_office : _this.form.findField('_roo_office').getValue(),\n           _download : _this.data.invhist_transfer_id \n             \n        }\n    });\n    \n    \n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Download (Excel)",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.grid.stopEditing();\n    if (_this.data.invhist_transfer_posted || _this.data.invhist_transfer_void) {\n        _this.dialog.hide();\n        return;\n    }\n    \n    if (_this.data.createFromRev) {\n        Roo.MessageBox.alert(\"Warning\", \"A draft item reciept has been created - please void it if it is not needed\");\n        _this.dialog.hide();        \n        return;\n    }\n    \n    \n\n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to cancel, all changes will be lost\", function(r) {\n    \n        if (r !='yes') {\n            return;\n        }\n        _this.dialog.hide();\n    \n   })\n    \n    \n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    // do some checks?\n    _this.grid.stopEditing();\n    var ar = []; \n    var err = false;\n    _this.grid.ds.each(function (r) {\n        var missingqty = r.data.invhist_transfer_item_qty < 1;\n        var missingsku = r.data.invhist_transfer_item_itemsite_id < 1;\n        if (missingsku && missingqty) {\n            return;\n        }\n        \n    \n        if (missingqty) {\n            err = \"Missing Quantity on line : \" + r.data.invhist_transfer_item_line;\n        }\n        if (missingsku) {\n           err = \"Missing SKU on line : \" + r.data.invhist_transfer_item_line;\n        }\n        ar.push({\n            id: r.data.invhist_transfer_item_id,\n            itemsite_id : r.data.invhist_transfer_item_itemsite_id,\n            line:  r.data.invhist_transfer_item_line,\n            qty: r.data.invhist_transfer_item_qty,\n            price : r.data.invhist_transfer_item_unit_price\n        });\n        \n     });\n     if (err) { \n        Roo.MessageBox.alert(\"Error\", err);\n        return;\n     }\n     if (!ar.length) {\n       Roo.MessageBox.alert(\"Error\", \"Nothing listed to transfer\");\n        return;\n     }\n     _this.form.findField('transfer_items').setValue(  Roo.encode(ar));\n    \n    var arrivaldate = _this.form.findField('invhist_transfer_arrivaldate').getValue();\n    var transferprice = _this.form.findField('invhist_transfer_price').getValue();\n    \n    if(_this.toLocation._is_internalcompany && !arrivaldate){\n        Roo.MessageBox.alert(\"Error\", \"Arrival date must be filled in\");\n        return;\n    }\n    if(_this.toLocation._is_internalcompany && !transferprice.length){\n        Roo.MessageBox.alert(\"Error\", \"For inter company transfer a price must be set\");\n        return;\n    }\n    if(!arrivaldate){\n        _this.form.findField('invhist_transfer_arrivaldate').setValue(_this.form.findField('invhist_transfer_transdate').getValue());\n    }\n    _this.form.doAction(\"submit\");\n    \n\n\n\n}",
+                        "render": "function (_self)\n{\n    _this.saveBtn = _self;\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleTransfer.js b/Pman.Dialog.XtupleTransfer.js
new file mode 100644 (file)
index 0000000..509184c
--- /dev/null
@@ -0,0 +1,1756 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleTransfer = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            listeners : {
+                show : function (_self)
+                {
+                    this.layout.getRegion('center').showPanel(0);
+                }
+            },
+            closable : false,
+            collapsible : false,
+            height : 660,
+            modal : true,
+            resizable : false,
+            title : "Edit / Create Inventory Transfer",
+            width : 800,
+            items : [
+                {
+                    xtype: 'NestedLayoutPanel',
+                    xns: Roo,
+                    region : 'center',
+                    title : "Inventory Transfer",
+                    layout : {
+                        xtype: 'BorderLayout',
+                        xns: Roo,
+                        items : [
+                            {
+                                xtype: 'ContentPanel',
+                                xns: Roo,
+                                region : 'north',
+                                items : [
+                                    {
+                                        xtype: 'Form',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            actioncomplete : function(_self,action)
+                                            {
+                                                if (action.type == 'setdata') {
+                                                   //_this.dialog.el.mask("Loading");
+                                                   Roo.log('setdata');
+                                                   Roo.log(_this.data);       
+                                                   // reversal...
+                                                   _this.grid.setColumns();
+                                                   _this.saveBtn.show();            
+                                                   if (_this.data.createFromRev) {
+                                                        Roo.log('recvg');
+                                                        this.load({ method: 'GET', params: { '_createFromRecv' : _this.data.createFromRev }});       
+                                                        return;
+                                                   
+                                                   }
+                                                   
+                                                    if (_this.data.invhist_transfer_id) {
+                                                    
+                                                    
+                                                        var tdb = baseURL.split('/').pop().split('.').shift();
+                                                        if (tdb != _this.data._roo_office) {
+                                                            this.el.mask('Remote Transfer - Read Only');
+                                                            _this.grid.view.headerPanel.mask("");
+                                                            _this.uploadBtn.hide();
+                                                            _this.saveBtn.hide();                
+                                                        } else {
+                                                            this.el.unmask();
+                                                            _this.grid.view.headerPanel.unmask();
+                                                            _this.uploadBtn.show();
+                                                            _this.saveBtn.show();                
+                                                        }
+                                                        
+                                                    
+                                                    
+                                                        this.load({ method: 'GET', params: {
+                                                             _id : _this.data.invhist_transfer_id,
+                                                             _roo_office  : _this.data._roo_office
+                                                       }});
+                                                        return;
+                                                    } 
+                                                    _this.grid.ds.removeAll();
+                                                    _this.form.setValues({
+                                                        invhist_transfer_transdate : 
+                                                                typeof(_this.data.invhist_transfer_transdate) == 'undefined' ? 
+                                                                        (new Date()).format('Y-m-d') :
+                                                                        _this.data.invhist_transfer_transdate
+                                                                    ,
+                                                        invhist_transfer_number : 'AUTOMATIC',
+                                                        _roo_office :  _this.data._roo_office
+                                                    });
+                                                    
+                                                    if(_this.data._createReverse){
+                                                        if(_this.grid){
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/invhist_transfer_item',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    invhist_transfer_item_invhist_transfer_id : _this.data._createReverse,
+                                                                    'query[at_location]' : _this.data.invhist_transfer_from,
+                                                                    _requestMeta : 1,
+                                                                    limit : 999,
+                                                                    sort : 'invhist_transfer_item_line',
+                                                                    dir : 'ASC'
+                                                                },
+                                                                success : function (res) 
+                                                                {
+                                                                    Roo.log('loadData');
+                                                                    Roo.log(res); 
+                                                                   _this.grid.ds.loadData(res,false);
+                                                                }
+                                                            });
+                                                        }
+                                                    }
+                                                    
+                                                    this.setValues({
+                                                        invhist_transfer_salesrep_id : Pman.Login.authUser.salesrep.salesrep_id,
+                                                        invhist_transfer_salesrep_id_salesrep_name : Pman.Login.authUser.salesrep.salesrep_name
+                                                    });
+                                                    
+                                                    
+                                                    if (typeof(_this.data._ns_autofill) != 'undefined') {
+                                                        Roo.log("autofill: " +  _this.data._ns_autofill);
+                                                    
+                                                       
+                                                        var locid = _this.data._ns_autofill === 1 ?_this.data.invhist_transfer_to  : _this.data.invhist_transfer_from; 
+                                                        // clear it so it's not done again..
+                                                        
+                                                        Roo.log("locid: " + locid);
+                                                        
+                                                         var rn = 0;
+                                                         var addRow = function(r) {
+                                                                
+                                                                var nsQty = r.netsuite_qty*1;
+                                                                nsQty = nsQty < 1 ? 0 : nsQty;
+                                                                
+                                                                var ourQty = r.itemsite_qty *1;
+                                                                var addQty = 0;
+                                                                if (_this.data._ns_autofill === 1) {
+                                                                    // then we are trying to transfer from somewhere to her, to increase the qty to match
+                                                                    // so if  ourQty < nsQty
+                                                                    if (ourQty < nsQty) {
+                                                                        addQty = nsQty - ourQty;
+                                                                    }
+                                                                    
+                                                                } else {
+                                                                    // we are trying to transfer out to get rid of stock to match..
+                                                                    if (nsQty < ourQty) {
+                                                                        addQty = ourQty - nsQty;
+                                                                    }
+                                                                }
+                                                                
+                                                                if (addQty * 1 < 1) {
+                                                                
+                                                                    return;
+                                                                }
+                                                                
+                                                               var nr = _this.grid.ds.reader.newRow({
+                                                                    invhist_transfer_item_line : rn + 1,
+                                                                    item_id : r.itemsite_item_id,    
+                                                                    invhist_transfer_item_itemsite_id :         r.itemsite_id,    
+                                                                    item_number : r.itemsite_item_id_item_number,
+                                                                    item_descrip1 : r.itemsite_item_id_item_descrip1,
+                                                                    invhist_transfer_item_qty : addQty,
+                                                                    item_availqty : 0 
+                                                                   // invhist_transfer_item_transfer_id : tid << we do not know this?!?
+                                                               });
+                                                                 _this.grid.ds.insert(rn++, nr); 
+                                                            
+                                                        };
+                                                        
+                                                        
+                                                        
+                                                        
+                                                        // do the request..
+                                                        new Pman.Request({
+                                                            url : baseURL + '/Roo/itemsite',
+                                                            mask: "Fetching Stock Quantities",
+                                                            method : 'GET',
+                                                            params : {
+                                                                limit : 99999,
+                                                                location_id : locid,
+                                                                _as_of : _this.data.invhist_transfer_transdate,
+                                                                _with_stock_and_value : 1,
+                                                                _with_ns_all_stock : 1,
+                                                                'sort' :  'itemsite_item_id_item_number',
+                                                                'dir' : 'ASC'
+                                                            },
+                                                            success : function(res) {
+                                                                Roo.log(res);
+                                                                 Roo.each(res.data, addRow);
+                                                                 _this.data._ns_autofill = undefined;
+                                                            }
+                                                        });
+                                                    }
+                                                    
+                                                   return;
+                                                }
+                                                if (action.type == 'load') {
+                                                
+                                                    // fix date..
+                                                    this.findField('_roo_office').setValue(  _this.data._roo_office );
+                                                    Roo.log(action);
+                                                    _this.data = action.result.data;
+                                                    if(_this.data.invhist_transfer_void){
+                                                        _this.saveBtn.hide();
+                                                    }
+                                                    var dt = Date.parseDate(_this.data.invhist_transfer_transdate.split(' ')[0], "Y-m-d");
+                                                    _this.form.findField('invhist_transfer_transdate').setValue(dt);
+                                                    var dt = Date.parseDate(_this.data.invhist_transfer_arrivaldate.split(' ')[0],"Y-m-d");
+                                                    _this.form.findField('invhist_transfer_arrivaldate').setValue(dt);
+                                                    _this.grid.ds.load({});
+                                                    
+                                                    return;
+                                                }
+                                                if (action.type =='submit') {
+                                                
+                                                    
+                                                    _this.dialog.hide();
+                                                
+                                                     if (_this.callback) {
+                                                        _this.callback.call(_this, _this.form.getValues());
+                                                     }
+                                                     _this.form.reset();
+                                                     return;
+                                                }
+                                            },
+                                            rendered : function (form)
+                                            {
+                                                _this.form= form;
+                                            }
+                                        },
+                                        method : 'POST',
+                                        style : 'margin:10px;',
+                                        url : baseURL + '/Xtuple/Roo/invhist_transfer.php',
+                                        items : [
+                                            {
+                                                xtype: 'Column',
+                                                xns: Roo.form,
+                                                width : 400,
+                                                items : [
+                                                    {
+                                                        xtype: 'FieldSet',
+                                                        xns: Roo.form,
+                                                        legend : "Transfer Details",
+                                                        style : 'width: 380px;height:220px;',
+                                                        items : [
+                                                            {
+                                                                xtype: 'DateField',
+                                                                xns: Roo.form,
+                                                                allowBlank : false,
+                                                                fieldLabel : 'Date',
+                                                                format : 'Y-m-d',
+                                                                name : 'invhist_transfer_transdate',
+                                                                width : 100
+                                                            },
+                                                            {
+                                                                xtype: 'DateField',
+                                                                xns: Roo.form,
+                                                                allowBlank : true,
+                                                                fieldLabel : 'Arrival date',
+                                                                format : 'Y-m-d',
+                                                                name : 'invhist_transfer_arrivaldate',
+                                                                width : 100
+                                                            },
+                                                            {
+                                                                xtype: 'TextField',
+                                                                xns: Roo.form,
+                                                                fieldLabel : 'Reference #',
+                                                                name : 'invhist_transfer_number',
+                                                                readOnly : true,
+                                                                width : 200
+                                                            },
+                                                            {
+                                                                xtype: 'ComboBox',
+                                                                xns: Roo.form,
+                                                                allowBlank : true,
+                                                                displayField : 'salesrep_name',
+                                                                editable : false,
+                                                                emptyText : "Select salesrep",
+                                                                fieldLabel : 'Sales Rep',
+                                                                forceSelection : true,
+                                                                hiddenName : 'invhist_transfer_salesrep_id',
+                                                                listWidth : 400,
+                                                                loadingText : "Searching...",
+                                                                minChars : 2,
+                                                                name : 'invhist_transfer_salesrep_id_salesrep_name',
+                                                                pageSize : 20,
+                                                                qtip : "Select salesrep",
+                                                                queryParam : 'query[salesrep_name]',
+                                                                selectOnFocus : true,
+                                                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                                                                triggerAction : 'all',
+                                                                typeAhead : true,
+                                                                valueField : 'salesrep_id',
+                                                                width : 250,
+                                                                store : {
+                                                                    xtype: 'Store',
+                                                                    xns: Roo.data,
+                                                                    listeners : {
+                                                                        beforeload : function (_self, o){
+                                                                            o.params = o.params || {};
+                                                                            // set more here
+                                                                        }
+                                                                    },
+                                                                    remoteSort : true,
+                                                                    sortInfo : { direction : 'ASC', field: 'salesrep_name' },
+                                                                    proxy : {
+                                                                        xtype: 'HttpProxy',
+                                                                        xns: Roo.data,
+                                                                        method : 'GET',
+                                                                        url : baseURL + '/Roo/salesrep.php'
+                                                                    },
+                                                                    reader : {
+                                                                        xtype: 'JsonReader',
+                                                                        xns: Roo.data,
+                                                                        id : 'salesrep_id',
+                                                                        root : 'data',
+                                                                        totalProperty : 'total',
+                                                                        fields : [{"name":"salesrep_id","type":"int"},"salesrep_name"]
+                                                                    }
+                                                                }
+                                                            },
+                                                            {
+                                                                xtype: 'ComboBox',
+                                                                xns: Roo.form,
+                                                                listeners : {
+                                                                    render : function (_self)
+                                                                    {
+                                                                        _this.fromLocation = _self;
+                                                                    }
+                                                                },
+                                                                allowBlank : false,
+                                                                displayField : 'location_descrip',
+                                                                editable : true,
+                                                                emptyText : "Select location",
+                                                                fieldLabel : 'From Location',
+                                                                forceSelection : true,
+                                                                hiddenName : 'invhist_transfer_from',
+                                                                listWidth : 400,
+                                                                loadingText : "Searching...",
+                                                                minChars : 2,
+                                                                name : 'invhist_transfer_from_location_descrip',
+                                                                pageSize : 200,
+                                                                qtip : "Select location",
+                                                                queryParam : 'query[location_name]',
+                                                                selectOnFocus : true,
+                                                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> - {location_descrip} </div>',
+                                                                triggerAction : 'all',
+                                                                valueField : 'location_id',
+                                                                width : 250,
+                                                                store : {
+                                                                    xtype: 'Store',
+                                                                    xns: Roo.data,
+                                                                    listeners : {
+                                                                        beforeload : function (_self, o){
+                                                                            o.params = o.params || {};
+                                                                            // set more here
+                                                                         
+                                                                                o.params._notinternalcompany = 1;
+                                                                         
+                                                                        }
+                                                                    },
+                                                                    remoteSort : true,
+                                                                    sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                                    proxy : {
+                                                                        xtype: 'HttpProxy',
+                                                                        xns: Roo.data,
+                                                                        method : 'GET',
+                                                                        url : baseURL + '/Roo/location.php'
+                                                                    },
+                                                                    reader : {
+                                                                        xtype: 'JsonReader',
+                                                                        xns: Roo.data,
+                                                                        id : 'id',
+                                                                        root : 'data',
+                                                                        totalProperty : 'total',
+                                                                        fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                                                    }
+                                                                }
+                                                            },
+                                                            {
+                                                                xtype: 'ComboBox',
+                                                                xns: Roo.form,
+                                                                listeners : {
+                                                                    select : function (combo, record, index)
+                                                                    {
+                                                                        combo._is_internalcompany = false;
+                                                                        
+                                                                        if(record.data.cust_to_internalcompany.length){
+                                                                            combo._is_internalcompany = true;
+                                                                        }
+                                                                        
+                                                                        _this.grid.setColumns();
+                                                                    },
+                                                                    render : function (_self)
+                                                                    {
+                                                                        _this.toLocation = _self;
+                                                                    }
+                                                                },
+                                                                allowBlank : false,
+                                                                displayField : 'location_descrip',
+                                                                editable : true,
+                                                                emptyText : "Select location",
+                                                                fieldLabel : 'To Location',
+                                                                forceSelection : true,
+                                                                hiddenName : 'invhist_transfer_to',
+                                                                listWidth : 400,
+                                                                loadingText : "Searching...",
+                                                                minChars : 2,
+                                                                name : 'invhist_transfer_to_location_descrip',
+                                                                pageSize : 200,
+                                                                qtip : "Select location",
+                                                                queryParam : 'query[location_name]',
+                                                                selectOnFocus : true,
+                                                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b>  - <b style="color:red">{location_cust_id_char_internalcompany} </b> {location_descrip} </div>',
+                                                                triggerAction : 'all',
+                                                                valueField : 'location_id',
+                                                                width : 250,
+                                                                store : {
+                                                                    xtype: 'Store',
+                                                                    xns: Roo.data,
+                                                                    listeners : {
+                                                                        beforeload : function (_self, o){
+                                                                            o.params = o.params || {};
+                                                                            o.params.location_restrict = 0;
+                                                                            o.params._with_internalcompany = 1;
+                                                                            
+                                                                        }
+                                                                    },
+                                                                    remoteSort : true,
+                                                                    sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                                    proxy : {
+                                                                        xtype: 'HttpProxy',
+                                                                        xns: Roo.data,
+                                                                        method : 'GET',
+                                                                        url : baseURL + '/Roo/location.php'
+                                                                    },
+                                                                    reader : {
+                                                                        xtype: 'JsonReader',
+                                                                        xns: Roo.data,
+                                                                        id : 'id',
+                                                                        root : 'data',
+                                                                        totalProperty : 'total',
+                                                                        fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                                                    }
+                                                                }
+                                                            }
+                                                        ]
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'Column',
+                                                xns: Roo.form,
+                                                style : 'margin-left: 10px; float: left;',
+                                                width : 280,
+                                                items : [
+                                                    {
+                                                        xtype: 'FieldSet',
+                                                        xns: Roo.form,
+                                                        hideLabels : true,
+                                                        legend : "Transfer Delivery Note Reference",
+                                                        style : 'width: 260px',
+                                                        items : [
+                                                            {
+                                                                xtype: 'TextArea',
+                                                                xns: Roo.form,
+                                                                fieldLabel : 'invhist_transfer_delivery_note',
+                                                                name : 'invhist_transfer_delivery_note',
+                                                                width : 250
+                                                            }
+                                                        ]
+                                                    },
+                                                    {
+                                                        xtype: 'FieldSet',
+                                                        xns: Roo.form,
+                                                        hideLabels : true,
+                                                        legend : "Transfer Description",
+                                                        style : 'width: 260px',
+                                                        items : [
+                                                            {
+                                                                xtype: 'TextArea',
+                                                                xns: Roo.form,
+                                                                fieldLabel : 'invhist_transfer_descrip',
+                                                                name : 'invhist_transfer_descrip',
+                                                                width : 250
+                                                            }
+                                                        ]
+                                                    },
+                                                    {
+                                                        xtype: 'Row',
+                                                        xns: Roo.form,
+                                                        items : [
+                                                            {
+                                                                xtype: 'ComboBox',
+                                                                xns: Roo.form,
+                                                                allowBlank : true,
+                                                                displayField : 'desc',
+                                                                editable : false,
+                                                                fieldLabel : 'Transfer Price',
+                                                                hiddenName : 'invhist_transfer_price',
+                                                                listWidth : 200,
+                                                                mode : 'local',
+                                                                name : 'invhist_transfer_price_desc',
+                                                                triggerAction : 'all',
+                                                                value : "",
+                                                                valueField : 'code',
+                                                                width : 150,
+                                                                store : {
+                                                                    xtype: 'SimpleStore',
+                                                                    xns: Roo.data,
+                                                                    data : [ 
+                                                                        [ 'PRICELIST', "At Transfer Price"],
+                                                                        [ 'LASTPLUS' , "Last Purchase +10% + 15% or stdcost +15%"],
+                                                                        [ 'STDCOST' , "stdcost - for old transfers only%"]
+                                                                    
+                                                                    ],
+                                                                    fields : [  'code', 'desc']
+                                                                }
+                                                            }
+                                                        ]
+                                                    }
+                                                ]
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'transfer_items'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : '_roo_office'
+                                            },
+                                            {
+                                                xtype: 'Hidden',
+                                                xns: Roo.form,
+                                                name : 'invhist_transfer_id'
+                                            }
+                                        ]
+                                    }
+                                ]
+                            },
+                            {
+                                xtype: 'GridPanel',
+                                xns: Roo,
+                                listeners : {
+                                    activate : function() {
+                                        _this.panel = this;
+                                        if (_this.grid) {
+                                            _this.grid.ds.load({});
+                                        }
+                                    }
+                                },
+                                fitContainer : true,
+                                fitToframe : true,
+                                region : 'center',
+                                tableName : 'invhist_transfer_item',
+                                title : "invhist_transfer_item",
+                                grid : {
+                                    xtype: 'EditorGrid',
+                                    xns: Roo.grid,
+                                    listeners : {
+                                        render : function() 
+                                        {
+                                            _this.grid = this; 
+                                            //_this.dialog = Pman.Dialog.FILL_IN
+                                            if (_this.panel.active) {
+                                               this.ds.load({});
+                                            }
+                                        },
+                                        rowdblclick : function (_self, rowIndex, e)
+                                        {
+                                            if (!_this.dialog) return;
+                                            _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                                                _this.grid.footer.onClick('first');
+                                            }); 
+                                        },
+                                        beforeedit : function (e)
+                                        {
+                                            if(_this.data.invhist_transfer_posted){
+                                                Roo.MessageBox.alert('Error', 'This transfer has been posted');
+                                                return false;
+                                            }
+                                            if(_this.data.invhist_transfer_void){
+                                                Roo.MessageBox.alert('Error', 'This transfer has been voided');
+                                                return false;
+                                            }
+                                            
+                                            if(e.field == 'invhist_transfer_item_unit_price' && (!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length) && !_this.toLocation._is_internalcompany){
+                                                Roo.MessageBox.alert('Error', 'Not a inter-comany transfer');
+                                                return false;
+                                            }
+                                            
+                                            
+                                            
+                                        }
+                                    },
+                                    autoExpandColumn : 'item_descrip1',
+                                    clicksToEdit : 1,
+                                    loadMask : true,
+                                    setColumns : function() {
+                                        var cm = _this.grid.getColumnModel();
+                                        
+                                        function cid(str) {
+                                            return cm.getIndexByDataIndex(str);
+                                        }
+                                        
+                                        if((!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length) && !_this.toLocation._is_internalcompany){
+                                            cm.setHidden(cid('invhist_transfer_item_unit_price'), true);
+                                            cm.setHidden(cid('invhist_transfer_item_unit_price_default'), true);
+                                            return;
+                                        }
+                                        
+                                        cm.setHidden(cid('invhist_transfer_item_unit_price'), false);
+                                        cm.setHidden(cid('invhist_transfer_item_unit_price_default'), false);
+                                    },
+                                    sm : {
+                                        xtype: 'CellSelectionModel',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            tabend : function (_self)
+                                            {
+                                                _this.addItemBtn.fireEvent('click', _this.addItemBtn);
+                                            }
+                                        }
+                                    },
+                                    dataSource : {
+                                        xtype: 'Store',
+                                        xns: Roo.data,
+                                        listeners : {
+                                            beforeload : function (_self, o)
+                                            {
+                                               
+                                                o.params = o.params || {};
+                                                if (!_this.form) {
+                                                    return false;
+                                                }
+                                                
+                                                o.params.invhist_transfer_item_invhist_transfer_id = _this.form.findField('invhist_transfer_id').getValue() * 1;
+                                                
+                                                if ( !o.params.invhist_transfer_item_invhist_transfer_id) {
+                                                    _this.grid.ds.removeAll();
+                                                    return false;
+                                                }
+                                            
+                                                o.params['query[at_location]'] = _this.form.findField('invhist_transfer_from').getValue();
+                                                o.params.limit = 999;
+                                                o.params._roo_office =  _this.form.findField('_roo_office').getValue();
+                                                
+                                                _this.grid.setColumns();
+                                                    
+                                                if(!_this.data.cust_to_internalcompany || !_this.data.cust_to_internalcompany.length){
+                                                    return;
+                                                }
+                                                
+                                                o.params._inter_transfer = 1;    
+                                            
+                                                
+                                                
+                                            }
+                                        },
+                                        remoteSort : true,
+                                        sortInfo : { field : 'invhist_transfer_item_line', direction: 'ASC' },
+                                        proxy : {
+                                            xtype: 'HttpProxy',
+                                            xns: Roo.data,
+                                            method : 'GET',
+                                            url : baseURL + '/Xtuple/Roo/invhist_transfer_item.php'
+                                        },
+                                        reader : {
+                                            xtype: 'JsonReader',
+                                            xns: Roo.data,
+                                            id : 'id',
+                                            root : 'data',
+                                            totalProperty : 'total',
+                                            fields : [
+                                                {
+                                                    'name': 'invhist_transfer_item_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invhist_transfer_item_invhist_transfer_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invhist_transfer_item_itemsite_id',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invhist_transfer_item_qty',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invhist_transfer_item_line',
+                                                    'type': 'int'
+                                                },
+                                                {
+                                                    'name': 'invhist_transfer_invhist_id',
+                                                    'type': 'int'
+                                                }, 
+                                                'item_id',
+                                                'item_number',    
+                                                'item_descrip1',
+                                                'avail_at_location'
+                                                
+                                                
+                                            ]
+                                        }
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                        
+                                                         if (_this.data.invhist_transfer_posted) {
+                                                            Roo.MessageBox.alert("Error", "Transfer has been posted, void it first");
+                                                            return;
+                                                        }
+                                                        
+                                                        // work out last 
+                                                        var grid = _this.grid;
+                                                        var last = 0;
+                                                        
+                                                        _this.grid.ds.each(function(r) {
+                                                            last = r.data.invhist_transfer_item_line;
+                                                        });
+                                                        
+                                                        last++;
+                                                        
+                                                        var nr = _this.grid.ds.reader.newRow({
+                                                            invhist_transfer_item_line : last,
+                                                            item_number : '',
+                                                            item_descrip1 : '',
+                                                            invhist_transfer_item_qty : 0,
+                                                            item_availqty : 0,
+                                                            invhist_transfer_item_transfer_id : _this.form.findField('invhist_transfer_id').getValue()
+                                                       });
+                                                    
+                                                        grid.stopEditing();
+                                                        grid.ds.insert(grid.ds.getCount(), nr); 
+                                                        grid.startEditing(grid.ds.getCount()-1, 1); // type..
+                                                    },
+                                                    render : function (_self)
+                                                    {
+                                                        _this.addItemBtn = _self;
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Add",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                cls : 'x-btn-text-icon',
+                                                text : "Fill based on Stock",
+                                                icon : Roo.rootURL + 'images/default/dd/drop-add.gif',
+                                                menu : {
+                                                    xtype: 'Menu',
+                                                    xns: Roo.menu,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function()
+                                                                {
+                                                                    var    rn =      _this.grid.ds.getCount();
+                                                                    var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();
+                                                                    var addRow = function(r) {
+                                                                    
+                                                                        if (r.itemsite_qty * 1 < 1) {
+                                                                        
+                                                                            return;
+                                                                            }
+                                                                      var nr = _this.grid.ds.reader.newRow({
+                                                                            invhist_transfer_item_line : rn + 1,
+                                                                            item_id : r.itemsite_item_id,    
+                                                                            invhist_transfer_item_itemsite_id :         r.itemsite_id,    
+                                                                            item_number : r.itemsite_item_id_item_number,
+                                                                            item_descrip1 : r.itemsite_item_id_item_descrip1,
+                                                                            invhist_transfer_item_qty : r.itemsite_qty,
+                                                                            item_availqty : 0,
+                                                                            invhist_transfer_item_transfer_id : tid
+                                                                       });
+                                                                         _this.grid.ds.insert(rn++, nr); 
+                                                                    
+                                                                    };
+                                                                     
+                                                                    var loc  = _this.form.findField('invhist_transfer_from').getValue()*1;
+                                                                    var dt  = _this.form.findField('invhist_transfer_transdate').getValue().format('Y-m-d');    
+                                                                    
+                                                                    _this.grid.stopEditing();
+                                                                    
+                                                                    new Pman.Request({
+                                                                        url :  baseURL + '/Roo/itemsite',
+                                                                        mask : 'Fetching stock',
+                                                                        method : 'GET',
+                                                                        params : {
+                                                                            limit : 2000, // alot!
+                                                                            _with_stock_and_value : 1,
+                                                                            _viewtype : 1,
+                                                                            location_id : loc,
+                                                                            _as_of : dt,
+                                                                            'sort' : 'itemsite_item_id_item_number',
+                                                                            'dir'  : 'ASC'
+                                                                        },
+                                                                        success : function(r) {
+                                                                            Roo.log(r);
+                                                                            Roo.each(r.data, addRow);
+                                                                            
+                                                                        
+                                                                        }
+                                                                    
+                                                                    });
+                                                                
+                                                                    
+                                                                
+                                                                    
+                                                                
+                                                                    
+                                                                     
+                                                                },
+                                                                render : function (_self)
+                                                                {
+                                                                    _this.addItemBtn = _self;
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Transfer all from Location",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function()
+                                                                {
+                                                                 var    rn =      _this.grid.ds.getCount();
+                                                                        var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();
+                                                                        
+                                                                        
+                                                                        var addRow = function(r) {
+                                                                        
+                                                                            if (r.itemsite_qty * 1 > -1) {
+                                                                            
+                                                                                return;
+                                                                            }
+                                                                          var nr = _this.grid.ds.reader.newRow({
+                                                                                invhist_transfer_item_line : rn + 1,
+                                                                                item_id : r.itemsite_item_id,    
+                                                                                invhist_transfer_item_itemsite_id :         r.itemsite_id,    
+                                                                                item_number : r.itemsite_item_id_item_number,
+                                                                                item_descrip1 : r.itemsite_item_id_item_descrip1,
+                                                                                invhist_transfer_item_qty : Math.abs(r.itemsite_qty),
+                                                                                item_availqty : 0,
+                                                                                invhist_transfer_item_transfer_id : tid
+                                                                           });
+                                                                             _this.grid.ds.insert(rn++, nr); 
+                                                                        
+                                                                        };
+                                                                         
+                                                                        var loc  = _this.form.findField('invhist_transfer_to').getValue()*1;
+                                                                        var dt  = _this.form.findField('invhist_transfer_transdate').getValue().format('Y-m-d');    
+                                                                        
+                                                                        _this.grid.stopEditing();
+                                                                        
+                                                                        new Pman.Request({
+                                                                            url :  baseURL + '/Roo/itemsite',
+                                                                            mask : 'Fetching stock',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                limit : 2000, // alot!
+                                                                                _with_stock_and_value : 1,
+                                                                                _viewtype : -1,
+                                                                                location_id : loc,
+                                                                                _as_of : dt,
+                                                                                'sort' : 'itemsite_item_id_item_number',
+                                                                                'dir'  : 'ASC'
+                                                                            },
+                                                                            success : function(r) {
+                                                                                Roo.log(r);
+                                                                                Roo.each(r.data, addRow);
+                                                                                
+                                                                            
+                                                                            }
+                                                                        
+                                                                        });
+                                                                    
+                                                                    
+                                                                
+                                                                    
+                                                                
+                                                                    
+                                                                     
+                                                                },
+                                                                render : function (_self)
+                                                                {
+                                                                    _this.addItemBtn = _self;
+                                                                }
+                                                            },
+                                                            cls : 'x-btn-text-icon',
+                                                            text : "Fill negative at Target",
+                                                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                        }
+                                                    ]
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function()
+                                                    {
+                                                         _this.grid.stopEditing();     
+                                                    
+                                                         if (_this.data.invhist_transfer_posted) {
+                                                            Roo.MessageBox.alert("Error", "Transfer has been posted, void it first");
+                                                            return;
+                                                        }
+                                                    
+                                                        var rc= _this.grid.selModel.getSelectedCell();
+                                                         if (!rc) {
+                                                            Roo.MessageBox.alert("Error", "Select a item to delete");
+                                                            return;
+                                                         }
+                                                             
+                                                         var rec = _this.grid.ds.getAt(rc[0]);
+                                                         _this.grid.ds.remove(rec);
+                                                         
+                                                    
+                                                        rec = _this.grid.ds.getAt(rc[0]);
+                                                        if (rec) {
+                                                            _this.grid.selModel.select(rc[0], 2);
+                                                            return;
+                                                        }
+                                                        var ln = rc[0]-1;
+                                                        if (ln < 0) {
+                                                          return;
+                                                        } // nothing left to select..
+                                                        _this.grid.selModel.select(rc[0]-1, 2);
+                                                         
+                                                        
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                cls : 'x-btn-text-icon',
+                                                text : "Delete",
+                                                icon : rootURL + '/Pman/templates/images/trash.gif'
+                                            }
+                                        ]
+                                    },
+                                    colModel : [
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'invhist_transfer_item_line',
+                                            header : 'Line',
+                                            width : 75,
+                                            renderer : function(v) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'item_id',
+                                            header : 'Item Code',
+                                            width : 75,
+                                            renderer : function(v,x,r) { 
+                                                return String.format('{0}', r.data.item_number);
+                                             },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        beforeselect : function (combo, record, index)
+                                                        {
+                                                          // set _this.data values ..
+                                                          var ar = _this.grid.activeEditor.record;
+                                                          //Roo.log('beforeselect');
+                                                          (function() { 
+                                                             //  Roo.log('beforeselect-cb');
+                                                              ar.set('item_descrip1', record.data.itemsite_item_id_item_descrip1);
+                                                             // ar.set('coitem_price', record.data.item_listprice);
+                                                             // ar.set('coitem_custprice', record.data.item_price);
+                                                               ar.set('invhist_transfer_item_itemsite_id', record.data.itemsite_id);
+                                                              ar.set('item_number', record.data.itemsite_item_id_item_number);
+                                                              ar.set('avail_at_location', record.data.avail_at_location);
+                                                              ar.commit();
+                                                          }).defer(100);
+                                                          
+                                                        }
+                                                    },
+                                                    allowBlank : false,
+                                                    displayField : 'itemsite_item_id_item_number',
+                                                    editable : true,
+                                                    emptyText : "Select item",
+                                                    forceSelection : true,
+                                                    hiddenName : 'itemsite_item_id_item_number',
+                                                    listWidth : 400,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    name : 'item_number',
+                                                    pageSize : 20,
+                                                    qtip : "Select item",
+                                                    queryParam : 'query[number]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b>  {itemsite_item_id_item_descrip1} ({avail_at_location})</div>',
+                                                    triggerAction : 'all',
+                                                    valueField : 'item_number',
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o){
+                                                                o.params = o.params || {};
+                                                                
+                                                                o.params['query[at_location]'] = _this.form.findField('invhist_transfer_from').getValue();
+                                                                
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { direction : 'ASC', field: 'itemsite_item_id_item_number' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/itemsite.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'shipto_id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [{"name":"item_id","type":"int"},"item_number"]
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            dataIndex : 'item_descrip1',
+                                            header : 'Description',
+                                            width : 75,
+                                            renderer : function(v,x,r) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'avail_at_location',
+                                            header : 'Cur. Avail',
+                                            width : 75,
+                                            renderer : function(v,x,r) { return String.format('{0}', v); }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invhist_transfer_item_qty',
+                                            header : 'Qty',
+                                            width : '50.00',
+                                            renderer : function(v,x,r) { 
+                                                var vv = parseInt(v);
+                                                //var aq = parseInt(r.data.avail_qty);
+                                                //aq = isNaN(aq) ? 0 : aq;
+                                               
+                                               
+                                               
+                                               
+                                                return String.format('{0}', vv.toFixed(0)); 
+                                                
+                                            },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'NumberField',
+                                                    xns: Roo.form,
+                                                    allowDecimals : false,
+                                                    decimalPrecision : 0,
+                                                    minValue : 1,
+                                                    style : 'text-align:right'
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invhist_transfer_item_unit_price',
+                                            header : 'Unit Price',
+                                            hidden : true,
+                                            width : 75,
+                                            renderer : function(v,x,r) 
+                                            { 
+                                                if(!v && v !== 0){
+                                                    return '';
+                                                }
+                                                var color = '#666'; // orignal color
+                                                
+                                                if(r.data.invhist_transfer_item_unit_price_default != v){
+                                                    color = 'red';
+                                                }
+                                                
+                                                return String.format('<span style="color:{0};">{1} {2}</span>', color, (r.data.invhist_transfer_item_curr_name) ? r.data.invhist_transfer_item_curr_name : '' , Roo.util.Format.number(v,2)); 
+                                            },
+                                            editor : {
+                                                xtype: 'GridEditor',
+                                                xns: Roo.grid,
+                                                field : {
+                                                    xtype: 'NumberField',
+                                                    xns: Roo.form,
+                                                    allowBlank : false,
+                                                    allowDecimals : true,
+                                                    decimalPrecision : 2,
+                                                    style : 'text-align:right'
+                                                }
+                                            }
+                                        },
+                                        {
+                                            xtype: 'ColumnModel',
+                                            xns: Roo.grid,
+                                            align : 'right',
+                                            dataIndex : 'invhist_transfer_item_unit_price_default',
+                                            header : 'Default Price',
+                                            hidden : true,
+                                            width : 75,
+                                            renderer : function(v,x,r) 
+                                            { 
+                                                if(!v && v !== 0){
+                                                    return '';
+                                                }
+                                                return String.format('{0} {1}', (r.data.invhist_transfer_item_curr_name) ? r.data.invhist_transfer_item_curr_name : '' , Roo.util.Format.number(v,2)); 
+                                            }
+                                        }
+                                    ]
+                                }
+                            }
+                        ],
+                        north : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo,
+                            height : 260
+                        },
+                        center : {
+                            xtype: 'LayoutRegion',
+                            xns: Roo
+                        }
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.ipanel = this;
+                            if (_this.igrid) {
+                                _this.igrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : false,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'Images',
+                    title : "Reference Files",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() { 
+                                _this.igrid = this; 
+                                //_this.dialog = Pman.Dialog.FILL_IN
+                                //if (_this.panel.active) {
+                                //   this.footer.onClick('first');
+                                //}
+                            },
+                            rowdblclick : function (_self, rowIndex, e)
+                            {
+                              
+                               var s =  _self.getDataSource().getAt(rowIndex);
+                               new Pman.Download({
+                                    url : baseURL + '/Images/' + s.data.id
+                                     
+                                });
+                               
+                            }
+                        },
+                        autoExpandColumn : 'id',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, o)
+                                {
+                                    //o.params.ontable = 'Companies';
+                                    
+                                  //   o.params.imgtype = 'PressRelease';
+                                    
+                                    o.params = o.params || {};
+                                    o.params.onid = _this.form.findField('invhist_transfer_id').getValue();
+                                    o.params.ontable = 'invhist_transfer';
+                                    Roo.log(_this);
+                                    
+                                },
+                                load : function (_self, records, options)
+                                {
+                                 _this.panel.el.unmask();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field: 'created' , direction: 'DESC' },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'filename',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'ontable',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'onid',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'mimetype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'width',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'height',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'filesize',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'displayorder',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'language',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'parent_image_id',
+                                        'type': 'int'
+                                    },
+                                    {
+                                        'name': 'created',
+                                        'type': 'date',
+                                        'dateFormat' : 'Y-m-d H:i:s'
+                                    },
+                                    {
+                                        'name': 'imgtype',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'linkurl',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'descript',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'title',
+                                        'type': 'string'
+                                    }
+                                ]
+                            },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/Images.php'
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            pageSize : 25,
+                            displayInfo : true,
+                            displayMsg : "Displaying Images  {0} - {1} of {2}",
+                            emptyMsg : "No Images found"
+                        },
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                        {
+                                                    
+                                            //var sel = Pman.Tab.PressReleaseCompanies  ? Pman.Tab.PressReleaseCompanies.grid.getSelectionModel().getSelected() : false
+                                             
+                                            Pman.Dialog.Image.show({
+                                                id : 0, 
+                                                ontable: 'invhist_transfer',
+                                                onid: _this.form.findField('invhist_transfer_id').getValue(),
+                                                imgtype : ''
+                                            }, function(data){
+                                                if (!data) { return; } 
+                                                _this.igrid.footer.onClick('first');
+                                            }); 
+                                        
+                                        }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Add",
+                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function()
+                                                {
+                                                Pman.genericDelete(_this, 'Images'); 
+                                                }
+                                    },
+                                    cls : 'x-btn-text-icon',
+                                    text : "Delete",
+                                    icon : rootURL + '/Pman/templates/images/trash.gif'
+                                }
+                            ]
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'created',
+                                header : 'Created',
+                                sortable : true,
+                                width : 200,
+                                renderer : function(v,x,r) {
+                                       return String.format('{0}<br/><i>{1}</i><br/>{2}<br/><i>{3}x{4}</i>',
+                                            v.format('d/M/Y'), r.data.mimetype, r.data.filename,
+                                    r.data.width, r.data.height
+                                    ); 
+                                }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'id',
+                                header : 'Image',
+                                width : 100,
+                                renderer : function(v,x,r) { return String.format('<img src="{0}/Images/Thumb/100/{1}/{2}" height="100">', baseURL, v, r.data.filename); }
+                            }
+                        ]
+                    }
+                },
+                {
+                    xtype: 'GridPanel',
+                    xns: Roo,
+                    listeners : {
+                        activate : function() {
+                            _this.hpanel = this;
+                            if (_this.hgrid) {
+                                _this.hgrid.footer.onClick('first');
+                            }
+                        }
+                    },
+                    background : true,
+                    fitContainer : true,
+                    fitToframe : true,
+                    region : 'center',
+                    tableName : 'events',
+                    title : "History",
+                    grid : {
+                        xtype: 'Grid',
+                        xns: Roo.grid,
+                        listeners : {
+                            render : function() 
+                            {
+                                _this.hgrid = this; 
+                                if (_this.hpanel.active) {
+                                   this.footer.onClick('first');
+                                }
+                            }
+                        },
+                        autoExpandColumn : 'remarks',
+                        loadMask : true,
+                        dataSource : {
+                            xtype: 'Store',
+                            xns: Roo.data,
+                            listeners : {
+                                beforeload : function (_self, options)
+                                {
+                                    options.params = options.params || {};
+                                    
+                                    options.params.on_table = 'invhist_transfer';
+                                    options.params.on_id = _this.form.findField('invhist_transfer_id').getValue();
+                                }
+                            },
+                            remoteSort : true,
+                            sortInfo : { field : 'event_when', direction: 'DESC' },
+                            proxy : {
+                                xtype: 'HttpProxy',
+                                xns: Roo.data,
+                                method : 'GET',
+                                url : baseURL + '/Roo/events.php'
+                            },
+                            reader : {
+                                xtype: 'JsonReader',
+                                xns: Roo.data,
+                                id : 'id',
+                                root : 'data',
+                                totalProperty : 'total',
+                                fields : [
+                                    {
+                                        'name': 'event_when',
+                                        'type': 'date'
+                                    },
+                                    {
+                                        'name': 'action',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'ipaddr',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'person_id_name',
+                                        'type': 'string'
+                                    },
+                                    {
+                                        'name': 'remarks',
+                                        'type': 'string'
+                                    }
+                                ]
+                            }
+                        },
+                        footer : {
+                            xtype: 'PagingToolbar',
+                            xns: Roo,
+                            displayInfo : true,
+                            displayMsg : "Displaying events{0} - {1} of {2}",
+                            emptyMsg : "No Events found",
+                            pageSize : 25
+                        },
+                        colModel : [
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'event_when',
+                                header : 'Changed',
+                                width : 120,
+                                renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y H:i:s') : ''); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'action',
+                                header : 'Action',
+                                width : 200,
+                                renderer : function(v,x,r) { return String.format('{0} - {1}', v, r.data.on_table); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'ipaddr',
+                                header : 'IP Address',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'person_id_name',
+                                header : 'Who',
+                                width : 75,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            },
+                            {
+                                xtype: 'ColumnModel',
+                                xns: Roo.grid,
+                                dataIndex : 'remarks',
+                                header : 'Notes',
+                                width : 200,
+                                renderer : function(v) { return String.format('{0}', v); }
+                            }
+                        ]
+                    }
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo,
+                tabPosition : 'top'
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                           
+                            var rn =      _this.grid.ds.getCount();
+                            var tid = 1 * _this.form.findField('invhist_transfer_id').getValue();
+                            var addRow = function(r) {
+                                if (r.itemsite_qty * 1 < 1) {
+                                    return;
+                                }
+                                
+                                var nr = _this.grid.ds.reader.newRow({
+                                    invhist_transfer_item_line : rn + 1,
+                                    item_id : r.itemsite_item_id,    
+                                    invhist_transfer_item_itemsite_id : r.itemsite_id,    
+                                    item_number : r.itemsite_item_id_item_number,
+                                    item_descrip1 : r.itemsite_item_id_item_descrip1,
+                                    invhist_transfer_item_qty : r.itemsite_qty,
+                                    item_availqty : 0,
+                                    avail_at_location : '',
+                                    invhist_transfer_item_transfer_id : tid,
+                                    invhist_transfer_item_unit_price : r.unit_price,
+                                    invhist_transfer_item_unit_price_default : r.unit_price,
+                                });
+                                _this.grid.ds.insert(rn++, nr); 
+                            
+                            };
+                           
+                            Pman.Dialog.Image.show(
+                               {
+                                    _url : baseURL + '/Xtuple/Import/Transfer'
+                                
+                               },
+                               function (r) {
+                                    Roo.log(r);
+                                    Roo.each(r.items, addRow);
+                                    
+                                    if (typeof(r.Date) !='undefined') {
+                                        _this.form.findField('invhist_transfer_transdate').setValue( Date.parseDate((r.Date) ? r.Date : (new Date()).format('Y-m-d'), "Y-m-d"));
+                                    }
+                                    if (typeof(r.ArrivalDate) !='undefined') {            
+                                        _this.form.findField('invhist_transfer_arrivaldate').setValue(Date.parseDate((r.ArrivalDate) ? r.ArrivalDate : (new Date()).format('Y-m-d'), "Y-m-d"));
+                                    }
+                                    if(r.invhist_transfer_from){
+                                        _this.fromLocation.setValue(r.invhist_transfer_from);
+                                        _this.fromLocation.el.dom.value = r.invhist_transfer_from_location_name;
+                                    }
+                                    if(r.invhist_transfer_to){
+                                        _this.toLocation.setValue(r.invhist_transfer_to);
+                                        _this.toLocation.el.dom.value = r.invhist_transfer_to_location_name;
+                                    }
+                                    
+                                    if(r.isInter == 1){
+                                        _this.toLocation._is_internalcompany = true;
+                                    }
+                                    _this.grid.setColumns();
+                               }
+                           );
+                        },
+                        render : function (_self)
+                        {
+                            _this.uploadBtn = _self;
+                        }
+                    },
+                    text : "Upload (Excel)"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                        
+                           new Pman.Download({
+                                url : baseURL + '/Xtuple/Roo/invhist_transfer',
+                                method : 'GET',
+                                params : {
+                                    _roo_office : _this.form.findField('_roo_office').getValue(),
+                                   _download : _this.data.invhist_transfer_id 
+                                     
+                                }
+                            });
+                            
+                            
+                        
+                        }
+                    },
+                    text : "Download (Excel)"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.grid.stopEditing();
+                            if (_this.data.invhist_transfer_posted || _this.data.invhist_transfer_void) {
+                                _this.dialog.hide();
+                                return;
+                            }
+                            
+                            if (_this.data.createFromRev) {
+                                Roo.MessageBox.alert("Warning", "A draft item reciept has been created - please void it if it is not needed");
+                                _this.dialog.hide();        
+                                return;
+                            }
+                            
+                            
+                        
+                            Roo.MessageBox.confirm("Confirm", "Are you sure want to cancel, all changes will be lost", function(r) {
+                            
+                                if (r !='yes') {
+                                    return;
+                                }
+                                _this.dialog.hide();
+                            
+                           })
+                            
+                            
+                        
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            // do some checks?
+                            _this.grid.stopEditing();
+                            var ar = []; 
+                            var err = false;
+                            _this.grid.ds.each(function (r) {
+                                var missingqty = r.data.invhist_transfer_item_qty < 1;
+                                var missingsku = r.data.invhist_transfer_item_itemsite_id < 1;
+                                if (missingsku && missingqty) {
+                                    return;
+                                }
+                                
+                            
+                                if (missingqty) {
+                                    err = "Missing Quantity on line : " + r.data.invhist_transfer_item_line;
+                                }
+                                if (missingsku) {
+                                   err = "Missing SKU on line : " + r.data.invhist_transfer_item_line;
+                                }
+                                ar.push({
+                                    id: r.data.invhist_transfer_item_id,
+                                    itemsite_id : r.data.invhist_transfer_item_itemsite_id,
+                                    line:  r.data.invhist_transfer_item_line,
+                                    qty: r.data.invhist_transfer_item_qty,
+                                    price : r.data.invhist_transfer_item_unit_price
+                                });
+                                
+                             });
+                             if (err) { 
+                                Roo.MessageBox.alert("Error", err);
+                                return;
+                             }
+                             if (!ar.length) {
+                               Roo.MessageBox.alert("Error", "Nothing listed to transfer");
+                                return;
+                             }
+                             _this.form.findField('transfer_items').setValue(  Roo.encode(ar));
+                            
+                            var arrivaldate = _this.form.findField('invhist_transfer_arrivaldate').getValue();
+                            var transferprice = _this.form.findField('invhist_transfer_price').getValue();
+                            
+                            if(_this.toLocation._is_internalcompany && !arrivaldate){
+                                Roo.MessageBox.alert("Error", "Arrival date must be filled in");
+                                return;
+                            }
+                            if(_this.toLocation._is_internalcompany && !transferprice.length){
+                                Roo.MessageBox.alert("Error", "For inter company transfer a price must be set");
+                                return;
+                            }
+                            if(!arrivaldate){
+                                _this.form.findField('invhist_transfer_arrivaldate').setValue(_this.form.findField('invhist_transfer_transdate').getValue());
+                            }
+                            _this.form.doAction("submit");
+                            
+                        
+                        
+                        
+                        },
+                        render : function (_self)
+                        {
+                            _this.saveBtn = _self;
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Dialog.XtupleUploadBalances.bjs b/Pman.Dialog.XtupleUploadBalances.bjs
new file mode 100644 (file)
index 0000000..806b0ab
--- /dev/null
@@ -0,0 +1,84 @@
+{
+    "id": "roo-file-178",
+    "name": "Pman.Dialog.XtupleUploadBalances",
+    "parent": "",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Dialog.XtupleUploadBalances.bjs",
+    "items": [
+        {
+            "closable": false,
+            "collapsible": false,
+            "height": 140,
+            "modal": true,
+            "resizable": false,
+            "title": "Upload new Balances",
+            "width": 400,
+            "xtype": "LayoutDialog",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "LayoutRegion",
+                    "*prop": "center"
+                },
+                {
+                    "region": "center",
+                    "xtype": "ContentPanel",
+                    "|xns": "Roo",
+                    "items": [
+                        {
+                            "listeners": {
+                                "|rendered": "function (form)\n{\n    _this.form= form;\n}\n",
+                                "actioncomplete": "function(_self,action)\r\n{\r\n    if (action.type == 'setdata') {\r\n       return;\r\n    }\r\n    if (action.type == 'load') {\r\n        return;\r\n    }\r\n    if (action.type =='submit') {\r\n    \r\n        _this.dialog.hide();\r\n\r\n         if (_this.callback) {\r\n            _this.callback.call(_this, _this.form.getValues());\r\n         }\r\n         _this.form.reset();\r\n         return;\r\n    }\r\n}\r"
+                            },
+                            "method": "GET",
+                            "style": "margin:10px;",
+                            "xtype": "Form",
+                            "|url": "baseURL + '/Roo/INGORE.php'",
+                            "|xns": "Roo.form",
+                            "items": [
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Reference",
+                                    "name": "reference",
+                                    "width": 200,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "allowBlank": false,
+                                    "fieldLabel": "Apply Date",
+                                    "format": "Y-m-d",
+                                    "name": "apply_date",
+                                    "width": 200,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    _this.dialog.hide();\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Cancel",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                },
+                {
+                    "listeners": {
+                        "click": "function (_self, e)\n{\n    var ref = _this.form.findField('reference').getValue();\n    var d = _this.form.findField('apply_date').getValue();\n    \n    if(!ref.length || !d){\n        Roo.MessageBox.alert(\"Error\", \"Referenct and Apply date must be filled in\");\n        return;\n    }\n    \n    _this.dialog.hide();\n    \n    _this.callback(_this.form.getValues());\n\n}"
+                    },
+                    "*prop": "buttons[]",
+                    "text": "Save",
+                    "xtype": "Button",
+                    "|xns": "Roo"
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Dialog.XtupleUploadBalances.js b/Pman.Dialog.XtupleUploadBalances.js
new file mode 100644 (file)
index 0000000..08e5061
--- /dev/null
@@ -0,0 +1,141 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Dialog.XtupleUploadBalances = {
+
+    dialog : false,
+    callback:  false,
+
+    show : function(data, cb)
+    {
+        if (!this.dialog) {
+            this.create();
+        }
+
+        this.callback = cb;
+        this.data = data;
+        this.dialog.show(this.data._el);
+        if (this.form) {
+           this.form.reset();
+           this.form.setValues(data);
+           this.form.fireEvent('actioncomplete', this.form,  { type: 'setdata', data: data });
+        }
+
+    },
+
+    create : function()
+    {
+        var _this = this;
+        this.dialog = Roo.factory({
+            xtype: 'LayoutDialog',
+            xns: Roo,
+            closable : false,
+            collapsible : false,
+            height : 140,
+            modal : true,
+            resizable : false,
+            title : "Upload new Balances",
+            width : 400,
+            items : [
+                {
+                    xtype: 'ContentPanel',
+                    xns: Roo,
+                    region : 'center',
+                    items : [
+                        {
+                            xtype: 'Form',
+                            xns: Roo.form,
+                            listeners : {
+                                rendered : function (form)
+                                {
+                                    _this.form= form;
+                                },
+                                actioncomplete : function(_self,action)
+                                {
+                                    if (action.type == 'setdata') {
+                                       return;
+                                    }
+                                    if (action.type == 'load') {
+                                        return;
+                                    }
+                                    if (action.type =='submit') {
+                                    
+                                        _this.dialog.hide();
+                                
+                                         if (_this.callback) {
+                                            _this.callback.call(_this, _this.form.getValues());
+                                         }
+                                         _this.form.reset();
+                                         return;
+                                    }
+                                }
+                            },
+                            method : 'GET',
+                            style : 'margin:10px;',
+                            url : baseURL + '/Roo/INGORE.php',
+                            items : [
+                                {
+                                    xtype: 'TextField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Reference',
+                                    name : 'reference',
+                                    width : 200
+                                },
+                                {
+                                    xtype: 'DateField',
+                                    xns: Roo.form,
+                                    allowBlank : false,
+                                    fieldLabel : 'Apply Date',
+                                    format : 'Y-m-d',
+                                    name : 'apply_date',
+                                    width : 200
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ],
+            center : {
+                xtype: 'LayoutRegion',
+                xns: Roo
+            },
+            buttons : [
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            _this.dialog.hide();
+                        }
+                    },
+                    text : "Cancel"
+                },
+                {
+                    xtype: 'Button',
+                    xns: Roo,
+                    listeners : {
+                        click : function (_self, e)
+                        {
+                            var ref = _this.form.findField('reference').getValue();
+                            var d = _this.form.findField('apply_date').getValue();
+                            
+                            if(!ref.length || !d){
+                                Roo.MessageBox.alert("Error", "Referenct and Apply date must be filled in");
+                                return;
+                            }
+                            
+                            _this.dialog.hide();
+                            
+                            _this.callback(_this.form.getValues());
+                        
+                        }
+                    },
+                    text : "Save"
+                }
+            ]
+        });
+    }
+};
diff --git a/Pman.Tab.XtupleAccountsTab.bjs b/Pman.Tab.XtupleAccountsTab.bjs
new file mode 100644 (file)
index 0000000..ee5e15c
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "id": "roo-file-181",
+    "name": "Pman.Tab.XtupleAccountsTab",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleAccountsTab.bjs",
+    "items": [
+        {
+            "region": "center",
+            "title": "Accounts",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "center",
+                            "alwaysShowTabs": true,
+                            "tabPosition": "top",
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "003"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleAccountsTab.js b/Pman.Tab.XtupleAccountsTab.js
new file mode 100644 (file)
index 0000000..53b44fc
--- /dev/null
@@ -0,0 +1,34 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleAccountsTab = new Roo.XComponent({
+    part     :  ["Xtuple","AccountsTab"],
+    order    : '003-Pman.Tab.XtupleAccountsTab',
+    region   : 'center',
+    parent   : 'Pman',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            region : 'center',
+            title : "Accounts",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    alwaysShowTabs : true,
+                    tabPosition : 'top'
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleAdjustment.bjs b/Pman.Tab.XtupleAdjustment.bjs
new file mode 100644 (file)
index 0000000..af5a767
--- /dev/null
@@ -0,0 +1,564 @@
+{
+    "id": "roo-file-309",
+    "name": "Pman.Tab.XtupleAdjustment",
+    "parent": "Pman.Tab.XtupleAdjustmentTab",
+    "title": "Pman.Tab.XtupleAdjustment",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleAdjustment.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "invadj",
+            "title": "Inventory Adjustments",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "afteredit": "function (e)\n{\n   if (e.record.data.invadj_posted) {\n     return;\n   }\n   var req = [ 'invadj_transdate', 'invadj_location_id', 'invadj_itemsite_id',  \n        'invadj_qty_by', 'invadj_comments' ];\n   var valid = true;\n    Roo.each(req, function(c) {\n        var val = '' + e.record.get(c);\n        if (!val.length) {\n            valid = false;\n        }\n    });\n    if (!valid) {\n        return;\n    }\n    e.record.commit();\n        \n   \n   \n}",
+                        "validateedit": "function (e)\n{\n    switch(e.field) {\n        case 'invadj_transdate':\n           // e.record.setValue('invadj_transdate', Date.parseDate(e.value, 'Y-m-d'));\n            e.value = Date.parseDate(e.value, 'Y-m-d');\n            break;\n    }\n}",
+                        "beforeedit": "function (e)\n{\n    Roo.log(e.record);\n    if (e.record.data.invadj_posted) {\n \n        e.cancel = true;\n        return false;\n    }\n}",
+                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var c = _this.grid.colModel.config[columnIndex];\n    var di = c.dataIndex;\n    if (di != 'invadj_posted') {\n        return;\n    }\n    \n    var r = _this.grid.ds.getAt(rowIndex);\n    if (r.data.invadj_posted || !r.data.invadj_id) {\n        return;\n    }\n    // attempting to post..\n    // validation - done at other end..\n    new Pman.Request({\n        url : baseURL + '/Roo/Invadj',\n        method  : 'POST',\n        mask : 'Posting',\n        params : {\n            invadj_id : r.data.invadj_id,\n            _post : 1\n        },\n        success : function(res) {\n            r.set('invadj_posted', true);\n            if (r.data.invadj_voids_id > 0) {\n                _this.grid.ds.each(function(rr) {\n                    if (rr.data.invadj_id == r.data.invadj_voids_id) {\n                        rr.set('invadj_voided_by_id', r.data.invadj_id);\n                        rr.set('invadj_comments', rr.data.invadj_comments);\n                    }\n                });\n            \n            \n            }\n            \n            \n            \n        },\n        failure : function (res) {\n            Roo.log(res);\n            Roo.MessageBox.alert(\"Error\",res.errorMsg);\n            if (res.errors.trandate) {\n                r.set('invadj_transdate', Date.parseDate(res.errors.trandate,'Y-m-d'));\n                r.commit();\n            }\n        \n        }\n    });\n    \n    \n    \n    \n}"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "invadj_comments",
+                    "clicksToEdit": 1,
+                    "loadMask": true,
+                    "xtype": "EditorGrid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "tabend": "function (eventdata)\n{\n    _this.addBtn.fireEvent('click', this); \n\n}"
+                            },
+                            "*prop": "sm",
+                            "xtype": "CellSelectionModel",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, options)\n{\n    options.params.invadj_location_id = _this.locationCombo.getValue();\n    options.params.invadj_itemsite_id = _this.itemCombo.getValue();   \n    switch(_this.status.getValue()) {\n        case 'ALL':\n            break;\n            \n       case 'VOID':\n           options.params._show_void = 1;\n        \n            break;\n            \n        case 'POSTED':\n\n            options.params.invadj_posted = 1;\n            break;\n            \n        case 'UNPOSTED':\n            options.params.invadj_posted = 0;\n            break;    \n\n        case 'ALL-NOGROUP':\n           options.params._hide_group = 1;        \n            break;\n            \n       case 'VOID-NOGROUP':\n           options.params._show_void = 1;       \n            options.params._hide_group = 1;                     \n            break;\n            \n        case 'POSTED-NOGROUP':\n            options.params.invadj_posted = 1;\n            options.params._hide_group = 1;                     \n            break;\n            \n        case 'UNPOSTED-NOGROUP':\n            options.params._hide_group = 1;                     \n            options.params.invadj_posted = 0;\n            break;    \n            \n            \n    }\n    options.params['query[comment]'] = _this.search.getValue();\n}",
+                                "update": "function (_self, record, operation)\n{\n    \n    Roo.log(operation);\n    if (operation != 'commit' || _this.incom) {\n        return;\n    }\n\n    \n    var    p = Roo.apply({}, record.data);\n    \n    if (p.invadj_posted) {\n        return;\n    }\n    p.invadj_transdate = record.data.invadj_transdate.format('Y-m-d');\n     p.invadj_posted = 0; \n\n    _this.incom = true;    \n    new Pman.Request( {\n        url : baseURL + '/Roo/Invadj',\n        mask : 'Saving',\n        method : 'POST',\n        params : p,\n        success : function(res) {\n            record.set('invadj_id', res.data.invadj_id);\n            _this.incom = false;\n        },\n        failure : function()\n        {\n            Roo.MessageBox.alert(\"Error\", \"Saving failed\");\n            _this.incom = false;            \n        }\n    \n    });\n    \n    \n    \n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'invadj_id', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/invadj.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'invadj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invadj_transdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invadj_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invadj_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invadj_qty_by',\n        'type': 'int'\n    },\n    {\n        'name': 'invadj_posted',\n        'type': 'int'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying invadj{0} - {1} of {2}",
+                            "emptyMsg": "No invadj found",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.locationCombo = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "location_name",
+                                    "editable": true,
+                                    "emptyText": "Select location",
+                                    "fieldLabel": "location",
+                                    "forceSelection": true,
+                                    "hiddenName": "invadj_location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "invadj_location_id_location_name",
+                                    "pageSize": 100,
+                                    "qtip": "Select location",
+                                    "queryParam": "query[location_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "location_id",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/location.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.itemCombo = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "itemsite_item_id_item_number",
+                                    "editable": true,
+                                    "emptyText": "Select itemsite",
+                                    "fieldLabel": "itemsite",
+                                    "forceSelection": true,
+                                    "hiddenName": "invadj_itemsite_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "invadj_itemsite_id_item_number",
+                                    "pageSize": 20,
+                                    "qtip": "Select itemsite",
+                                    "queryParam": "query[number]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "itemsite_id",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'itemsite_item_id_item_number' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/itemsite.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"itemsite_abcclass\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Status",
+                                    "hiddenName": "cm_status",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "cm_status_name",
+                                    "triggerAction": "all",
+                                    "value": "ALL-NOGROUP",
+                                    "valueField": "ftype",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'ALL-NOGROUP', \"All (not in Group)\"],\n    [ 'UNPOSTED-NOGROUP', \"Unposted only (not in Group)\"] ,\n    [ 'POSTED-NOGROUP', \"Posted only (not in Group)\"] ,\n    [ 'VOID-NOGROUP' ,\"Void (not in Group)\"],\n    [ 'ALL', \"All\"],\n    [ 'UNPOSTED', \"Unposted only\"] ,\n    [ 'POSTED', \"Posted only\"] ,\n    [ 'VOID', \"Void only\"]  \n    \n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}",
+                                        "render": "function (_self)\n{\n    _this.search = _self;\n}"
+                                    },
+                                    "width": 100,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n    _this.locationCombo.reset();\n    _this.itemCombo.reset();\n    \n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{   \n    new Pman.Download({\n        grid : _this.grid\n    });\n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Download Excel",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n   \n    Roo.log(\"add presed\");\n     \n    // work out last \n    var grid = _this.grid;\n     \n    // uses form defaults or last row value.\n    var nr = _this.grid.ds.reader.newRow({\n        invadj_id : 0,\n        invadj_transdate : (new Date()),\n        invadj_location_id :  0,\n        invadj_location_id_location_name : '',        \n        invadj_itemsite_id : 0,                \n        invadj_itemsite_id_item_number : '',        \n        invadj_qty_by : '',  \n        invadj_comments: '',      \n        invadj_posted: false\n                \n    });\n    grid.stopEditing();\n    grid.ds.insert(0, nr); \n    grid.startEditing(0, 1); // type..\n\n}\n",
+                                        "render": "function (_self)\n{\n    _this.addBtn = _self;\n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n   \n    Roo.log(\"add presed\");\n    \n    var grid = _this.grid;\n    var r = grid.selModel.getSelectedCell();\n    \n    \n    if (!r) {\n        Roo.MessageBox.alert(\"Error\", \"Select an adjustment\");\n        return;\n    }    \n    var rec = grid.ds.getAt(r[0]);\n    \n    var nrec = Roo.apply({}, rec.data);\n    nrec.invadj_qty_by *= -1;\n    nrec.invadj_comments = (rec.data.invadj_voids_id * 1 > 1) ? 'Restore of Adjustment #' + rec.data.invadj_voids_id : 'Void of Adjustment #' + rec.data.invadj_id;\n    nrec.invadj_posted = 0;\n    nrec.invadj_id = 0;    \n    nrec.invadj_invdetail_id  = '';\n    nrec.invadj_voids_id   =  rec.data.invadj_id;\n    //nrec.invadj_transdate = rec.data.invadj_transdate.format('Y-m-d');\n    \n    var nr = _this.grid.ds.reader.newRow(nrec);\n    grid.stopEditing();\n    grid.ds.insert(r[0], nr); \n    (function() { \n        grid.ds.getAt(r[0]).commit();\n    }).defer(100);\n    \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Void",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n   \n   var g = _this.grid;\n   var s = g.selModel.getSelectedCell();\n   if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select Adjustment\");\n        return;\n    }\n    var r = g.ds.getAt(s[0]);\n    if (r.data.invadj_posted) {\n        Roo.MessageBox.alert(\"Error\", \"You can not delete posted adjustments - try voiding them\");\n        return;\n    }\n    new Pman.Request({\n        url : baseURL + '/Roo/Invadj',\n        method : 'POST',\n        params  : { _delete : r.data.invadj_id },\n        mask : 'Deleteing',\n        success : function(res) {\n            g.ds.remove(r);\n        }\n    \n    });\n   \n   \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Delete",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_id",
+                            "header": "Ref#",
+                            "sortable": true,
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_transdate",
+                            "header": "Date",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "|xns": "Roo.grid",
+                                    "xtype": "GridEditor",
+                                    "*prop": "editor",
+                                    "items": [
+                                        {
+                                            "*prop": "field",
+                                            "format": "Y-m-d",
+                                            "useIso": true,
+                                            "xtype": "DateField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_location_id",
+                            "header": "Location",
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n    return String.format('{0}', \n        r.data.invadj_location_id_location_name\n     ); \n }",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "|xns": "Roo.grid",
+                                    "xtype": "GridEditor",
+                                    "*prop": "editor",
+                                    "items": [
+                                        {
+                                            "*prop": "field",
+                                            "allowBlank": false,
+                                            "displayField": "location_name",
+                                            "editable": true,
+                                            "emptyText": "Select location",
+                                            "fieldLabel": "location",
+                                            "forceSelection": true,
+                                            "hiddenName": "invadj_location_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "invadj_location_id_location_name",
+                                            "pageSize": 200,
+                                            "qtip": "Select location",
+                                            "queryParam": "query[location_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": false,
+                                            "valueField": "location_id",
+                                            "width": 300,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/location.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_itemsite_id_item_number",
+                            "header": "Item Number",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_itemsite_id",
+                            "header": "Item",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { return String.format('{0}', r.data.invadj_itemsite_id_item_number); }",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "|xns": "Roo.grid",
+                                    "xtype": "GridEditor",
+                                    "*prop": "editor",
+                                    "items": [
+                                        {
+                                            "*prop": "field",
+                                            "allowBlank": false,
+                                            "displayField": "itemsite_item_id_item_number",
+                                            "editable": true,
+                                            "emptyText": "Select itemsite",
+                                            "fieldLabel": "itemsite",
+                                            "forceSelection": true,
+                                            "hiddenName": "invadj_itemsite_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "invadj_itemsite_id_item_number",
+                                            "pageSize": 20,
+                                            "qtip": "Select itemsite",
+                                            "queryParam": "query[number]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": false,
+                                            "valueField": "itemsite_id",
+                                            "width": 300,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'itemsite_item_id_item_number' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/itemsite.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"itemsite_abcclass\",\"type\":\"string\"}]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invadj_qty_by",
+                            "header": "Adjust By #",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "|xns": "Roo.grid",
+                                    "xtype": "GridEditor",
+                                    "*prop": "editor",
+                                    "items": [
+                                        {
+                                            "*prop": "field",
+                                            "allowDecimals": false,
+                                            "cls": "align-right",
+                                            "xtype": "NumberField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_comments",
+                            "header": "Comments",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {\n   return String.format(r.data.invfifo_void * 1 > 0 ? '<s style=\"color:#ccc\">{0}</s>' : '{0}', v); \n }\n     ",
+                            "|xns": "Roo.grid",
+                            "items": [
+                                {
+                                    "|xns": "Roo.grid",
+                                    "xtype": "GridEditor",
+                                    "*prop": "editor",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.form",
+                                            "xtype": "TextField",
+                                            "*prop": "field"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadj_posted",
+                            "header": "Posted",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "100"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleAdjustment.js b/Pman.Tab.XtupleAdjustment.js
new file mode 100644 (file)
index 0000000..24ef4b6
--- /dev/null
@@ -0,0 +1,864 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleAdjustment = new Roo.XComponent({
+    part     :  ["Xtuple","Adjustment"],
+    order    : '100-Pman.Tab.XtupleAdjustment',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleAdjustmentTab',
+    name     : "Pman.Tab.XtupleAdjustment",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'invadj',
+            title : "Inventory Adjustments",
+            grid : {
+                xtype: 'EditorGrid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        //_this.dialog = Pman.Dialog.FILL_IN
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    afteredit : function (e)
+                    {
+                       if (e.record.data.invadj_posted) {
+                         return;
+                       }
+                       var req = [ 'invadj_transdate', 'invadj_location_id', 'invadj_itemsite_id',  
+                            'invadj_qty_by', 'invadj_comments' ];
+                       var valid = true;
+                        Roo.each(req, function(c) {
+                            var val = '' + e.record.get(c);
+                            if (!val.length) {
+                                valid = false;
+                            }
+                        });
+                        if (!valid) {
+                            return;
+                        }
+                        e.record.commit();
+                            
+                       
+                       
+                    },
+                    validateedit : function (e)
+                    {
+                        switch(e.field) {
+                            case 'invadj_transdate':
+                               // e.record.setValue('invadj_transdate', Date.parseDate(e.value, 'Y-m-d'));
+                                e.value = Date.parseDate(e.value, 'Y-m-d');
+                                break;
+                        }
+                    },
+                    beforeedit : function (e)
+                    {
+                        Roo.log(e.record);
+                        if (e.record.data.invadj_posted) {
+                     
+                            e.cancel = true;
+                            return false;
+                        }
+                    },
+                    cellclick : function (_self, rowIndex, columnIndex, e)
+                    {
+                        var c = _this.grid.colModel.config[columnIndex];
+                        var di = c.dataIndex;
+                        if (di != 'invadj_posted') {
+                            return;
+                        }
+                        
+                        var r = _this.grid.ds.getAt(rowIndex);
+                        if (r.data.invadj_posted || !r.data.invadj_id) {
+                            return;
+                        }
+                        // attempting to post..
+                        // validation - done at other end..
+                        new Pman.Request({
+                            url : baseURL + '/Roo/Invadj',
+                            method  : 'POST',
+                            mask : 'Posting',
+                            params : {
+                                invadj_id : r.data.invadj_id,
+                                _post : 1
+                            },
+                            success : function(res) {
+                                r.set('invadj_posted', true);
+                                if (r.data.invadj_voids_id > 0) {
+                                    _this.grid.ds.each(function(rr) {
+                                        if (rr.data.invadj_id == r.data.invadj_voids_id) {
+                                            rr.set('invadj_voided_by_id', r.data.invadj_id);
+                                            rr.set('invadj_comments', rr.data.invadj_comments);
+                                        }
+                                    });
+                                
+                                
+                                }
+                                
+                                
+                                
+                            },
+                            failure : function (res) {
+                                Roo.log(res);
+                                Roo.MessageBox.alert("Error",res.errorMsg);
+                                if (res.errors.trandate) {
+                                    r.set('invadj_transdate', Date.parseDate(res.errors.trandate,'Y-m-d'));
+                                    r.commit();
+                                }
+                            
+                            }
+                        });
+                        
+                        
+                        
+                        
+                    }
+                },
+                autoExpandColumn : 'invadj_comments',
+                clicksToEdit : 1,
+                loadMask : true,
+                sm : {
+                    xtype: 'CellSelectionModel',
+                    xns: Roo.grid,
+                    listeners : {
+                        tabend : function (eventdata)
+                        {
+                            _this.addBtn.fireEvent('click', this); 
+                        
+                        }
+                    }
+                },
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, options)
+                        {
+                            options.params.invadj_location_id = _this.locationCombo.getValue();
+                            options.params.invadj_itemsite_id = _this.itemCombo.getValue();   
+                            switch(_this.status.getValue()) {
+                                case 'ALL':
+                                    break;
+                                    
+                               case 'VOID':
+                                   options.params._show_void = 1;
+                                
+                                    break;
+                                    
+                                case 'POSTED':
+                        
+                                    options.params.invadj_posted = 1;
+                                    break;
+                                    
+                                case 'UNPOSTED':
+                                    options.params.invadj_posted = 0;
+                                    break;    
+                        
+                                case 'ALL-NOGROUP':
+                                   options.params._hide_group = 1;        
+                                    break;
+                                    
+                               case 'VOID-NOGROUP':
+                                   options.params._show_void = 1;       
+                                    options.params._hide_group = 1;                     
+                                    break;
+                                    
+                                case 'POSTED-NOGROUP':
+                                    options.params.invadj_posted = 1;
+                                    options.params._hide_group = 1;                     
+                                    break;
+                                    
+                                case 'UNPOSTED-NOGROUP':
+                                    options.params._hide_group = 1;                     
+                                    options.params.invadj_posted = 0;
+                                    break;    
+                                    
+                                    
+                            }
+                            options.params['query[comment]'] = _this.search.getValue();
+                        },
+                        update : function (_self, record, operation)
+                        {
+                            
+                            Roo.log(operation);
+                            if (operation != 'commit' || _this.incom) {
+                                return;
+                            }
+                        
+                            
+                            var    p = Roo.apply({}, record.data);
+                            
+                            if (p.invadj_posted) {
+                                return;
+                            }
+                            p.invadj_transdate = record.data.invadj_transdate.format('Y-m-d');
+                             p.invadj_posted = 0; 
+                        
+                            _this.incom = true;    
+                            new Pman.Request( {
+                                url : baseURL + '/Roo/Invadj',
+                                mask : 'Saving',
+                                method : 'POST',
+                                params : p,
+                                success : function(res) {
+                                    record.set('invadj_id', res.data.invadj_id);
+                                    _this.incom = false;
+                                },
+                                failure : function()
+                                {
+                                    Roo.MessageBox.alert("Error", "Saving failed");
+                                    _this.incom = false;            
+                                }
+                            
+                            });
+                            
+                            
+                            
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'invadj_id', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/invadj.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'invadj_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invadj_transdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'invadj_location_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invadj_itemsite_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invadj_qty_by',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invadj_posted',
+                                'type': 'int'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying invadj{0} - {1} of {2}",
+                    emptyMsg : "No invadj found"
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.locationCombo = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'location_name',
+                            editable : true,
+                            emptyText : "Select location",
+                            fieldLabel : 'location',
+                            forceSelection : true,
+                            hiddenName : 'invadj_location_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'invadj_location_id_location_name',
+                            pageSize : 100,
+                            qtip : "Select location",
+                            queryParam : 'query[location_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : false,
+                            valueField : 'location_id',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/location.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.itemCombo = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'itemsite_item_id_item_number',
+                            editable : true,
+                            emptyText : "Select itemsite",
+                            fieldLabel : 'itemsite',
+                            forceSelection : true,
+                            hiddenName : 'invadj_itemsite_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'invadj_itemsite_id_item_number',
+                            pageSize : 20,
+                            qtip : "Select itemsite",
+                            queryParam : 'query[number]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : false,
+                            valueField : 'itemsite_id',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'itemsite_item_id_item_number' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/itemsite.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"id","type":"int"},{"name":"itemsite_abcclass","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.status = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : false,
+                            displayField : 'fname',
+                            editable : false,
+                            fieldLabel : 'Status',
+                            hiddenName : 'cm_status',
+                            listWidth : 200,
+                            mode : 'local',
+                            name : 'cm_status_name',
+                            triggerAction : 'all',
+                            value : "ALL-NOGROUP",
+                            valueField : 'ftype',
+                            width : 150,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                data : [ 
+                                    [ 'ALL-NOGROUP', "All (not in Group)"],
+                                    [ 'UNPOSTED-NOGROUP', "Unposted only (not in Group)"] ,
+                                    [ 'POSTED-NOGROUP', "Posted only (not in Group)"] ,
+                                    [ 'VOID-NOGROUP' ,"Void (not in Group)"],
+                                    [ 'ALL', "All"],
+                                    [ 'UNPOSTED', "Unposted only"] ,
+                                    [ 'POSTED', "Posted only"] ,
+                                    [ 'VOID', "Void only"]  
+                                    
+                                ],
+                                fields : [  'ftype', 'fname']
+                            }
+                        },
+                        {
+                            xtype: 'TextField',
+                            xns: Roo.form,
+                            listeners : {
+                                specialkey : function (_self, e)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                    _this.search = _self;
+                                }
+                            },
+                            width : 100
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/search.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    _this.locationCombo.reset();
+                                    _this.itemCombo.reset();
+                                    
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {   
+                                    new Pman.Download({
+                                        grid : _this.grid
+                                    });
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Download Excel",
+                            icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                   
+                                    Roo.log("add presed");
+                                     
+                                    // work out last 
+                                    var grid = _this.grid;
+                                     
+                                    // uses form defaults or last row value.
+                                    var nr = _this.grid.ds.reader.newRow({
+                                        invadj_id : 0,
+                                        invadj_transdate : (new Date()),
+                                        invadj_location_id :  0,
+                                        invadj_location_id_location_name : '',        
+                                        invadj_itemsite_id : 0,                
+                                        invadj_itemsite_id_item_number : '',        
+                                        invadj_qty_by : '',  
+                                        invadj_comments: '',      
+                                        invadj_posted: false
+                                                
+                                    });
+                                    grid.stopEditing();
+                                    grid.ds.insert(0, nr); 
+                                    grid.startEditing(0, 1); // type..
+                                
+                                },
+                                render : function (_self)
+                                {
+                                    _this.addBtn = _self;
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                   
+                                    Roo.log("add presed");
+                                    
+                                    var grid = _this.grid;
+                                    var r = grid.selModel.getSelectedCell();
+                                    
+                                    
+                                    if (!r) {
+                                        Roo.MessageBox.alert("Error", "Select an adjustment");
+                                        return;
+                                    }    
+                                    var rec = grid.ds.getAt(r[0]);
+                                    
+                                    var nrec = Roo.apply({}, rec.data);
+                                    nrec.invadj_qty_by *= -1;
+                                    nrec.invadj_comments = (rec.data.invadj_voids_id * 1 > 1) ? 'Restore of Adjustment #' + rec.data.invadj_voids_id : 'Void of Adjustment #' + rec.data.invadj_id;
+                                    nrec.invadj_posted = 0;
+                                    nrec.invadj_id = 0;    
+                                    nrec.invadj_invdetail_id  = '';
+                                    nrec.invadj_voids_id   =  rec.data.invadj_id;
+                                    //nrec.invadj_transdate = rec.data.invadj_transdate.format('Y-m-d');
+                                    
+                                    var nr = _this.grid.ds.reader.newRow(nrec);
+                                    grid.stopEditing();
+                                    grid.ds.insert(r[0], nr); 
+                                    (function() { 
+                                        grid.ds.getAt(r[0]).commit();
+                                    }).defer(100);
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Void",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                   
+                                   var g = _this.grid;
+                                   var s = g.selModel.getSelectedCell();
+                                   if (!s) {
+                                        Roo.MessageBox.alert("Error", "Select Adjustment");
+                                        return;
+                                    }
+                                    var r = g.ds.getAt(s[0]);
+                                    if (r.data.invadj_posted) {
+                                        Roo.MessageBox.alert("Error", "You can not delete posted adjustments - try voiding them");
+                                        return;
+                                    }
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Invadj',
+                                        method : 'POST',
+                                        params  : { _delete : r.data.invadj_id },
+                                        mask : 'Deleteing',
+                                        success : function(res) {
+                                            g.ds.remove(r);
+                                        }
+                                    
+                                    });
+                                   
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Delete",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_id',
+                        header : 'Ref#',
+                        sortable : true,
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_transdate',
+                        header : 'Date',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); },
+                        editor : {
+                            xtype: 'GridEditor',
+                            xns: Roo.grid,
+                            field : {
+                                xtype: 'DateField',
+                                xns: Roo.form,
+                                format : 'Y-m-d',
+                                useIso : true
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_location_id',
+                        header : 'Location',
+                        width : 150,
+                        renderer : function(v,x,r) { 
+                        
+                            return String.format('{0}', 
+                                r.data.invadj_location_id_location_name
+                             ); 
+                         },
+                        editor : {
+                            xtype: 'GridEditor',
+                            xns: Roo.grid,
+                            field : {
+                                xtype: 'ComboBox',
+                                xns: Roo.form,
+                                allowBlank : false,
+                                displayField : 'location_name',
+                                editable : true,
+                                emptyText : "Select location",
+                                fieldLabel : 'location',
+                                forceSelection : true,
+                                hiddenName : 'invadj_location_id',
+                                listWidth : 400,
+                                loadingText : "Searching...",
+                                minChars : 2,
+                                name : 'invadj_location_id_location_name',
+                                pageSize : 200,
+                                qtip : "Select location",
+                                queryParam : 'query[location_name]',
+                                selectOnFocus : true,
+                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                triggerAction : 'all',
+                                typeAhead : false,
+                                valueField : 'location_id',
+                                width : 300,
+                                store : {
+                                    xtype: 'Store',
+                                    xns: Roo.data,
+                                    listeners : {
+                                        beforeload : function (_self, o){
+                                            o.params = o.params || {};
+                                            // set more here
+                                        }
+                                    },
+                                    remoteSort : true,
+                                    sortInfo : { direction : 'ASC', field: 'location_name' },
+                                    proxy : {
+                                        xtype: 'HttpProxy',
+                                        xns: Roo.data,
+                                        method : 'GET',
+                                        url : baseURL + '/Roo/location.php'
+                                    },
+                                    reader : {
+                                        xtype: 'JsonReader',
+                                        xns: Roo.data,
+                                        id : 'id',
+                                        root : 'data',
+                                        totalProperty : 'total',
+                                        fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_itemsite_id_item_number',
+                        header : 'Item Number',
+                        hidden : true,
+                        sortable : true,
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_itemsite_id',
+                        header : 'Item',
+                        width : 100,
+                        renderer : function(v,x,r) { return String.format('{0}', r.data.invadj_itemsite_id_item_number); },
+                        editor : {
+                            xtype: 'GridEditor',
+                            xns: Roo.grid,
+                            field : {
+                                xtype: 'ComboBox',
+                                xns: Roo.form,
+                                allowBlank : false,
+                                displayField : 'itemsite_item_id_item_number',
+                                editable : true,
+                                emptyText : "Select itemsite",
+                                fieldLabel : 'itemsite',
+                                forceSelection : true,
+                                hiddenName : 'invadj_itemsite_id',
+                                listWidth : 400,
+                                loadingText : "Searching...",
+                                minChars : 2,
+                                name : 'invadj_itemsite_id_item_number',
+                                pageSize : 20,
+                                qtip : "Select itemsite",
+                                queryParam : 'query[number]',
+                                selectOnFocus : true,
+                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> </div>',
+                                triggerAction : 'all',
+                                typeAhead : false,
+                                valueField : 'itemsite_id',
+                                width : 300,
+                                store : {
+                                    xtype: 'Store',
+                                    xns: Roo.data,
+                                    listeners : {
+                                        beforeload : function (_self, o){
+                                            o.params = o.params || {};
+                                            // set more here
+                                        }
+                                    },
+                                    remoteSort : true,
+                                    sortInfo : { direction : 'ASC', field: 'itemsite_item_id_item_number' },
+                                    proxy : {
+                                        xtype: 'HttpProxy',
+                                        xns: Roo.data,
+                                        method : 'GET',
+                                        url : baseURL + '/Roo/itemsite.php'
+                                    },
+                                    reader : {
+                                        xtype: 'JsonReader',
+                                        xns: Roo.data,
+                                        id : 'id',
+                                        root : 'data',
+                                        totalProperty : 'total',
+                                        fields : [{"name":"id","type":"int"},{"name":"itemsite_abcclass","type":"string"}]
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invadj_qty_by',
+                        header : 'Adjust By #',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); },
+                        editor : {
+                            xtype: 'GridEditor',
+                            xns: Roo.grid,
+                            field : {
+                                xtype: 'NumberField',
+                                xns: Roo.form,
+                                allowDecimals : false,
+                                cls : 'align-right'
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_comments',
+                        header : 'Comments',
+                        width : 75,
+                        renderer : function(v,x,r) {
+                           return String.format(r.data.invfifo_void * 1 > 0 ? '<s style="color:#ccc">{0}</s>' : '{0}', v); 
+                         },
+                        editor : {
+                            xtype: 'GridEditor',
+                            xns: Roo.grid,
+                            field : {
+                                xtype: 'TextField',
+                                xns: Roo.form
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadj_posted',
+                        header : 'Posted',
+                        width : 75,
+                        renderer : function(v) {  
+                            var state = v * 1 > 0 ?  '-checked' : '';
+                        
+                            return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                        
+                         }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleAdjustmentGroup.bjs b/Pman.Tab.XtupleAdjustmentGroup.bjs
new file mode 100644 (file)
index 0000000..598a282
--- /dev/null
@@ -0,0 +1,196 @@
+{
+    "id": "roo-file-310",
+    "name": "Pman.Tab.XtupleAdjustmentGroup",
+    "parent": "Pman.Tab.XtupleAdjustmentTab",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleAdjustmentGroup.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "invadjgrp",
+            "title": "Inventroy Adjustment Groups",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "rowdblclick": "function (_self, rowIndex, e)\n{\n    var s = _this.grid.ds.getAt(rowIndex);\n    \n    Pman.Dialog.XtupleAdjustmentGroup.show( { invadjgrp_id : s.data.invadjgrp_id } , function() {\n        _this.grid.footer.onClick('first');\n   });\n}",
+                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var c = _this.grid.colModel.config[columnIndex];\n    var di = c.dataIndex;\n    \n    if (di != 'invadjgrp_posted') {\n        return;\n    }\n    \n    var r = _this.grid.ds.getAt(rowIndex);\n    if (r.data.invadjgrp_posted  ) { // nos ur\n        Roo.MessageBox.alert(\"Error\", \"Group is already posted\");\n        return;\n    }\n     if (r.data.invadjgrp_void * 1 )  {\n        Roo.MessageBox.alert(\"Error\", \"Group is already void\");\n        return;\n    }\n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure it's ready to post?\",\n        function(bu) {\n            if (bu != 'yes') {\n                return;\n            }\n            \n            new Pman.Request({\n                url : baseURL + '/Roo/Invadjgrp',\n                method  : 'POST',\n                mask : 'Posting',\n                params : {\n                    invadjgrp_id : r.data.invadjgrp_id,\n                    invadjgrp_posted : 1,\n                    _post : 1\n                },\n                success : function(res) {\n                    _this.grid.footer.onClick('first');\n                },\n                failure : function (res) {\n                    Roo.log(res);\n                    Roo.MessageBox.alert(\"Error\",res.errorMsg);\n                    \n                }\n            });\n    });\n    \n}"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "invadjgrp_comments",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "*prop": "sm",
+                            "singleSelect": true,
+                            "xtype": "RowSelectionModel",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    \n    o.params._with_qty_detail = 1;\n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'invadjgrp_id', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "method": "GET",
+                                    "xtype": "HttpProxy",
+                                    "|url": "baseURL + '/Roo/Invadjgrp.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "root": "data",
+                                    "totalProperty": "total",
+                                    "xtype": "JsonReader",
+                                    "|fields": "[\n    {\n        'name': 'invadjgrp_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invadjgrp_location_id',\n        'type': 'int'\n    }\n]",
+                                    "|xns": "Roo.data"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "displayInfo": true,
+                            "displayMsg": "Displaying Inventory Adjustment Groups{0} - {1} of {2}",
+                            "emptyMsg": "No Inventory Adjustment Groups found",
+                            "pageSize": 25,
+                            "xtype": "PagingToolbar",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    Pman.Dialog.XtupleAdjustmentGroup.show( { invadjgrp_id : 0 } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var s = _this.grid.getSelectionModel().getSelected();\n    if (!s || s.data.invadjgrp_id * 1 < 1 )  {\n        Roo.MessageBox.alert(\"Error\", \"Select a inventory adjustment group\");\n        return;\n    }\n     if (!s || s.data.invadjgrp_void * 1 )  {\n        Roo.MessageBox.alert(\"Error\", \"Group is already void\");\n        return;\n    }\n    \n    if (!s.data.invadjgrp_posted) {\n        Roo.MessageBox.alert('Error', 'This group has not been posted yet!');\n        return;\n    }\n    \n    var voidit = function(force){\n        new Pman.Request({\n            url : baseURL + '/Roo/Invadjgrp',\n            method  : 'POST',\n            mask : 'Voiding',\n            params : {\n                invadjgrp_id : s.data.invadjgrp_id,\n                _void : 1,\n                _force : force\n            },\n            success : function(res) {\n                _this.grid.footer.onClick('first');\n            },\n            failure : function (res) {\n                Roo.log(res);\n                try {\n                    if (res.errors.confirm) {\n                                      \n                        Roo.MessageBox.confirm(\n                            \"Confirm\", \n                            \"There are some adjustments have been voided of this group! Do you want to void this group anyway?\",\n                            function(x) {\n                                if (x != 'yes') {\n                                    return;\n                                }\n                                voidit(1);\n                            }\n                        );\n                        return;\n                    }\n                } catch(e) { }\n                Roo.MessageBox.alert(\"Error\", res.errorMsg);\n                \n            }\n        });\n    }\n    \n    voidit(0)\n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Void",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{ \n    var s = _this.grid.getSelectionModel().getSelected();\n    \n    if (!s || s.data.invadjgrp_id * 1 < 1 )  {\n        Roo.MessageBox.alert(\"Error\", \"Select a inventory adjustment group\");\n        return;\n    }\n    \n    if (s.data.invadjgrp_posted) {\n        Roo.MessageBox.alert('Error', 'You can not delete the posted adjustment, try void it');\n        return;\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/Invadjgrp',\n        method : 'POST',\n        params  : { _delete : s.data.invadjgrp_id },\n        mask : 'Deleteing',\n        success : function(res) {\n            _this.grid.footer.onClick('first');\n        }\n    \n    });\n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Delete",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_id",
+                            "header": "Ref#",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_name",
+                            "header": "Name",
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_transdate",
+                            "header": "Date",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_neg_qty",
+                            "header": "Negative",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_pos_qty",
+                            "header": "Positive",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_location_id_location_name",
+                            "header": "Location",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_comments",
+                            "header": "Comments",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invadjgrp_posted",
+                            "header": "Posted",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {  \n    \n   if  (r.data.invadjgrp_void *1) { \n    return '';\n    }\n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleAdjustmentGroup.js b/Pman.Tab.XtupleAdjustmentGroup.js
new file mode 100644 (file)
index 0000000..5ff9cfe
--- /dev/null
@@ -0,0 +1,355 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleAdjustmentGroup = new Roo.XComponent({
+    part     :  ["Xtuple","AdjustmentGroup"],
+    order    : '001-Pman.Tab.XtupleAdjustmentGroup',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleAdjustmentTab',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'invadjgrp',
+            title : "Inventroy Adjustment Groups",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        var s = _this.grid.ds.getAt(rowIndex);
+                        
+                        Pman.Dialog.XtupleAdjustmentGroup.show( { invadjgrp_id : s.data.invadjgrp_id } , function() {
+                            _this.grid.footer.onClick('first');
+                       });
+                    },
+                    cellclick : function (_self, rowIndex, columnIndex, e)
+                    {
+                        var c = _this.grid.colModel.config[columnIndex];
+                        var di = c.dataIndex;
+                        
+                        if (di != 'invadjgrp_posted') {
+                            return;
+                        }
+                        
+                        var r = _this.grid.ds.getAt(rowIndex);
+                        if (r.data.invadjgrp_posted  ) { // nos ur
+                            Roo.MessageBox.alert("Error", "Group is already posted");
+                            return;
+                        }
+                         if (r.data.invadjgrp_void * 1 )  {
+                            Roo.MessageBox.alert("Error", "Group is already void");
+                            return;
+                        }
+                        Roo.MessageBox.confirm(
+                            "Confirm",
+                            "Are you sure it's ready to post?",
+                            function(bu) {
+                                if (bu != 'yes') {
+                                    return;
+                                }
+                                
+                                new Pman.Request({
+                                    url : baseURL + '/Roo/Invadjgrp',
+                                    method  : 'POST',
+                                    mask : 'Posting',
+                                    params : {
+                                        invadjgrp_id : r.data.invadjgrp_id,
+                                        invadjgrp_posted : 1,
+                                        _post : 1
+                                    },
+                                    success : function(res) {
+                                        _this.grid.footer.onClick('first');
+                                    },
+                                    failure : function (res) {
+                                        Roo.log(res);
+                                        Roo.MessageBox.alert("Error",res.errorMsg);
+                                        
+                                    }
+                                });
+                        });
+                        
+                    }
+                },
+                autoExpandColumn : 'invadjgrp_comments',
+                loadMask : true,
+                sm : {
+                    xtype: 'RowSelectionModel',
+                    xns: Roo.grid,
+                    singleSelect : true
+                },
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            o.params = o.params || {};
+                            
+                            o.params._with_qty_detail = 1;
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'invadjgrp_id', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/Invadjgrp.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        id : 'id',
+                        root : 'data',
+                        totalProperty : 'total',
+                        fields : [
+                            {
+                                'name': 'invadjgrp_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invadjgrp_location_id',
+                                'type': 'int'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    displayInfo : true,
+                    displayMsg : "Displaying Inventory Adjustment Groups{0} - {1} of {2}",
+                    emptyMsg : "No Inventory Adjustment Groups found",
+                    pageSize : 25
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    Pman.Dialog.XtupleAdjustmentGroup.show( { invadjgrp_id : 0 } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelected();
+                                    if (!s || s.data.invadjgrp_id * 1 < 1 )  {
+                                        Roo.MessageBox.alert("Error", "Select a inventory adjustment group");
+                                        return;
+                                    }
+                                     if (!s || s.data.invadjgrp_void * 1 )  {
+                                        Roo.MessageBox.alert("Error", "Group is already void");
+                                        return;
+                                    }
+                                    
+                                    if (!s.data.invadjgrp_posted) {
+                                        Roo.MessageBox.alert('Error', 'This group has not been posted yet!');
+                                        return;
+                                    }
+                                    
+                                    var voidit = function(force){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/Invadjgrp',
+                                            method  : 'POST',
+                                            mask : 'Voiding',
+                                            params : {
+                                                invadjgrp_id : s.data.invadjgrp_id,
+                                                _void : 1,
+                                                _force : force
+                                            },
+                                            success : function(res) {
+                                                _this.grid.footer.onClick('first');
+                                            },
+                                            failure : function (res) {
+                                                Roo.log(res);
+                                                try {
+                                                    if (res.errors.confirm) {
+                                                                      
+                                                        Roo.MessageBox.confirm(
+                                                            "Confirm", 
+                                                            "There are some adjustments have been voided of this group! Do you want to void this group anyway?",
+                                                            function(x) {
+                                                                if (x != 'yes') {
+                                                                    return;
+                                                                }
+                                                                voidit(1);
+                                                            }
+                                                        );
+                                                        return;
+                                                    }
+                                                } catch(e) { }
+                                                Roo.MessageBox.alert("Error", res.errorMsg);
+                                                
+                                            }
+                                        });
+                                    }
+                                    
+                                    voidit(0)
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Void",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                { 
+                                    var s = _this.grid.getSelectionModel().getSelected();
+                                    
+                                    if (!s || s.data.invadjgrp_id * 1 < 1 )  {
+                                        Roo.MessageBox.alert("Error", "Select a inventory adjustment group");
+                                        return;
+                                    }
+                                    
+                                    if (s.data.invadjgrp_posted) {
+                                        Roo.MessageBox.alert('Error', 'You can not delete the posted adjustment, try void it');
+                                        return;
+                                    }
+                                    
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Invadjgrp',
+                                        method : 'POST',
+                                        params  : { _delete : s.data.invadjgrp_id },
+                                        mask : 'Deleteing',
+                                        success : function(res) {
+                                            _this.grid.footer.onClick('first');
+                                        }
+                                    
+                                    });
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Delete",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_id',
+                        header : 'Ref#',
+                        width : 50,
+                        renderer : function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_name',
+                        header : 'Name',
+                        width : 150,
+                        renderer : function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_transdate',
+                        header : 'Date',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_neg_qty',
+                        header : 'Negative',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_pos_qty',
+                        header : 'Positive',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', parseInt(v).toFixed(0)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_location_id_location_name',
+                        header : 'Location',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_comments',
+                        header : 'Comments',
+                        width : 200,
+                        renderer : function(v,x,r) { return String.format(r.data.invadjgrp_void *1 ? '<s>{0}</s>' : '{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invadjgrp_posted',
+                        header : 'Posted',
+                        width : 75,
+                        renderer : function(v,x,r) {  
+                            
+                           if  (r.data.invadjgrp_void *1) { 
+                            return '';
+                            }
+                            var state = v * 1 > 0 ?  '-checked' : '';
+                        
+                            return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                        
+                         }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleAdjustmentTab.bjs b/Pman.Tab.XtupleAdjustmentTab.bjs
new file mode 100644 (file)
index 0000000..dc9e159
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "id": "roo-file-214",
+    "name": "Pman.Tab.XtupleAdjustmentTab",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleAdjustmentTab.bjs",
+    "items": [
+        {
+            "background": true,
+            "title": "Inventory Adjustments",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "center",
+                            "alwaysShowTabs": true,
+                            "tabPosition": "top",
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "990"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleAdjustmentTab.js b/Pman.Tab.XtupleAdjustmentTab.js
new file mode 100644 (file)
index 0000000..f43bdcd
--- /dev/null
@@ -0,0 +1,34 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleAdjustmentTab = new Roo.XComponent({
+    part     :  ["Xtuple","AdjustmentTab"],
+    order    : '990-Pman.Tab.XtupleAdjustmentTab',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            title : "Inventory Adjustments",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    alwaysShowTabs : true,
+                    tabPosition : 'top'
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleCreditMemos.bjs b/Pman.Tab.XtupleCreditMemos.bjs
new file mode 100644 (file)
index 0000000..2126b87
--- /dev/null
@@ -0,0 +1,441 @@
+{
+    "id": "roo-file-313",
+    "name": "Pman.Tab.XtupleCreditMemos",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "Pman.Tab.XtupleCreditMemos",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleCreditMemos.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "cmhead",
+            "title": "Credit Memos",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    var s = this.dataSource.getAt(rowIndex);\n    Pman.Dialog.XtupleCreditMemo.show({\n        cmhead_id : s.data.cmhead_id\n    },function() {\n        _this.grid.footer.onClick('first');\n    \n    });\n/*    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); */\n}\n"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "cmhead_cust_id_cust_name",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    if ( _this.customer &&  _this.customer.getValue() ) {\n       o.params.cmhead_cust_id = _this.customer.getValue();\n    }\n    if (_this.cmnumber && _this.cmnumber.getValue() ) {\n       o.params.cmhead_id =  _this.cmnumber.getValue();\n    }\n    if (_this.status) { \n        o.params['query[status]'] = _this.status.getValue();\n    }\n    \n    o.params._with_aropen = 1;\n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'cmhead_id', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/cmhead.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'cmhead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_custponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_docdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cmhead_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_shipto_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address1',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address2',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_address3',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_city',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_state',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_zipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_misc',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_printed',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_billtoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_billtozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_hold',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'cmhead_misc_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_rsncode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_freighttaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_gldistdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cmhead_billtocountry',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_shipto_country',\n        'type': 'string'\n    },\n    {\n        'name': 'cmhead_rahead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cmhead_prj_id',\n        'type': 'int'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying cmhead{0} - {1} of {2}",
+                            "emptyMsg": "No cmhead found",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.cmnumber = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "cmhead_number",
+                                    "editable": true,
+                                    "emptyText": "Order",
+                                    "fieldLabel": "ordernumber",
+                                    "forceSelection": true,
+                                    "hiddenName": "cmhead_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cmhead_number",
+                                    "pageSize": 20,
+                                    "qtip": "Select invchead",
+                                    "queryParam": "query[cmhead_number]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cmhead_number}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "cmhead_id",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cmhead_number' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/cmhead.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "cmhead_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"cmhead_id\",\"type\":\"int\"},\"cmhead_number\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.customer = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "emptyText": "Select Customer",
+                                    "fieldLabel": "cust_name",
+                                    "forceSelection": true,
+                                    "hiddenName": "cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select custinfo",
+                                    "queryParam": "query[cust_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": false,
+                                    "valueField": "cust_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "|xns": "Roo.data",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "xtype": "Store",
+                                            "remoteSort": true,
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Status",
+                                    "hiddenName": "cm_status",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "cm_status_name",
+                                    "triggerAction": "all",
+                                    "value": "NOTCLOSED",
+                                    "valueField": "ftype",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'NOTCLOSED', \"Not Closed\"],\n    [ 'CLOSED' , \"Closed\"],\n    [ 'UNPOSTED', \"Unposted only\"] ,\n    [ 'UNUSED', \"Posted and not used\"] ,\n    [ 'VOIDED', \"Voided\"] \n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.XtupleCreditMemoNew.show( {} , function() {\n        _this.grid.footer.onClick('first');\n   }); \n\n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "New Credit Memo",
+                                                    "xtype": "Item",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "|xns": "Roo.menu",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   var s = _this.grid.getSelectionModel().getSelections();\n\n    if (!s.length || (s.length > 1))  {\n        Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n        return;\n    }    \n    if(s[0].data.checkhead_total == 0){\n        Roo.MessageBox.alert(\"Error\", \"you cannot create the miscellaneous check for the credit memo coz the total amount remaining is 0! \");\n        return;\n    }\n    if(!s[0].data.cmhead_posted){\n        Roo.MessageBox.alert(\"Error\", \"This credit memo  has not been posted!\");\n        return;\n    }\n    var data = {\n        'checkhead_recip_id' : s[0].data.cmhead_cust_id,\n        'checkhead_recip_type' : 'C',\n        'checkhead_checkdate' : new Date(),\n        'checkhead_amount' : s[0].data.checkhead_total,\n        'remaining_total' : s[0].data.checkhead_total,\n        'checkhead_curr_id' : s[0].data.cmhead_curr_id,\n        'checkhead_curr_id_curr_name' : s[0].data.cmhead_curr_id_curr_name,\n        'checkhead_misc' : true,\n        'aropen_id' : s[0].data.cmhead_aropen_id_aropen_id,\n    \t'cmhead_number' : s[0].data.cmhead_number,\n\t'cust_name' : s[0].data.cmhead_cust_id_cust_name,\n\t'_create_and_post' : 1\n\n    };\n    \n    \n    Pman.Dialog.XtupleMiscellaneousCheck.show( data , function() {\n        _this.grid.footer.onClick('first');\n   }); \n\n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "New Miscellaneous Check",
+                                                    "xtype": "Item",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var s = _this.grid.getSelectionModel().getSelections();\n\n    if (!s.length || (s.length > 1))  {\n        Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n        return;\n    }\n\n    var postit = function()\n    {\n        new Pman.Request(\n        {\n            url : baseURL + '/Roo/Cmhead',\n            mask: 'Voiding',\n            method : 'POST',\n            params : {\n                cmhead_id : s[0].data.cmhead_id,\n                _void : 1\n            },\n            success : function()\n            {\n                _this.grid.footer.onClick('refresh');\n            } \n        });\n    \n    };\n\n\n    Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"Are you sure to void this credit memo?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            postit();\n        }\n    );\n    \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Void Credit Memo",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var s = _this.grid.getSelectionModel().getSelections();\n\n    if (!s.length || (s.length > 1))  {\n        Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n        return;\n    }\n    if (s[0].data.cmhead_posted ) { \n        Roo.MessageBox.alert(\"Error\", \n            \"You can not delete posted credit memo's - you have to create an invoice to reverse them\");\n        return;\n    }\n    \n    \n\n    var postit = function()\n    {\n        new Pman.Request(\n        {\n            url : baseURL + '/Roo/Cmhead',\n            mask: 'Deleting',\n            method : 'POST',\n            params : {\n                _delete  : s[0].data.cmhead_id \n            },\n            success : function()\n            {\n                _this.grid.footer.onClick('refresh');\n            } \n        });\n    \n    };\n\n\n    Roo.MessageBox.confirm(\n        \"Confirm Deletion\",\n        \"You will have to make sure this credit memo has no line items associated before deleting it. \",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            postit();\n        }\n    );\n    \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Delete Credit Memo",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var s = _this.grid.getSelectionModel().getSelections();\n\n    if (!s.length || (s.length > 1))  {\n        Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n        return;\n    }\n\n    var postit = function()\n    {\n        new Pman.Request(\n        {\n            url : baseURL + '/Roo/Cmhead',\n            mask: 'Posting',\n            method : 'POST',\n            params : {\n                cmhead_id : s[0].data.cmhead_id,\n                _post : 1\n            },\n            success : function()\n            {\n                _this.grid.footer.onClick('refresh');\n            } \n        });\n    \n    };\n\n\n    Roo.MessageBox.confirm(\n        \"Confirm Posting\",\n        \"Are you sure that is complete, <B>Voiding a Credit memo invoices creating a sales order and invoice</B>, so make sure this is correct before posting\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            postit();\n        }\n    ); \n    \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "POST",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{\n    var s = _this.grid.getSelectionModel().getSelected();\n      if (!s || !s.data.cmhead_id) {\n        Roo.MessageBox.alert(\"Error\", \"Select a credit memo\");\n        return\n      }\n      \n      var ext = baseURL.split('/').pop().replace(/\\.php/, '');\n      new Pman.Download({\n        url : baseURL + '/Xtuple/Print',\n        params :  {\n            template: 'creditmemo-' + ext,\n            filename : 'creditmemo-' + s.data.cmhead_id,\n            'param[0]':   \"cmhead_id:string='\" + s.data.cmhead_id + \"'\"\n           \n        },\n        method : 'GET'\n     });\n     Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n            \n            \n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Print",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Tools",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.menu",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   Roo.MessageBox.confirm(\n        \"Confirm\",\n        \"It is going to fill in all the blank return stock. Are you sure?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            new Pman.Request(\n            {\n                url : baseURL + '/Roo/Cmhead',\n                mask: 'Processing',\n                method : 'POST',\n                params : {\n                    _fix_stock : 1\n                },\n                success : function()\n                {\n                    Roo.MessageBox.alert('Notice','Fixed');\n                    _this.grid.footer.onClick('refresh');\n                } \n            });\n        }\n    ); \n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Fix Blank Return Stock",
+                                                    "xtype": "Item",
+                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cmhead_number",
+                            "header": "Ref #",
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cmhead_docdate",
+                            "header": "Date",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cmhead_salesrep_id_salesrep_name",
+                            "header": "Sales Rep",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v  ); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"}",
+                            "dataIndex": "cmhead_cust_id_cust_name",
+                            "header": "Customer",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cmhead_curr_id_curr_symbol",
+                            "header": "Currency",
+                            "width": 70,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v)\n{\n    return String.format('{0}', v ? v : '??');\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cmhead_value",
+                            "header": "Value",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v)\n{\n    return Roo.util.Format.usMoney(v);\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cmhead_unpaid",
+                            "header": "Open Value",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r)\n{\n    if (!r.data.cmhead_posted) {\n        return '';\n    }\n    return Roo.util.Format.usMoney(v);\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cmhead_posted",
+                            "header": "Posted",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? 'Yes':''); }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "200"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleCreditMemos.js b/Pman.Tab.XtupleCreditMemos.js
new file mode 100644 (file)
index 0000000..d9156d2
--- /dev/null
@@ -0,0 +1,868 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleCreditMemos = new Roo.XComponent({
+    part     :  ["Xtuple","CreditMemos"],
+    order    : '200-Pman.Tab.XtupleCreditMemos',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "Pman.Tab.XtupleCreditMemos",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'cmhead',
+            title : "Credit Memos",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        //_this.dialog = Pman.Dialog.FILL_IN
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        var s = this.dataSource.getAt(rowIndex);
+                        Pman.Dialog.XtupleCreditMemo.show({
+                            cmhead_id : s.data.cmhead_id
+                        },function() {
+                            _this.grid.footer.onClick('first');
+                        
+                        });
+                    /*    if (!_this.dialog) return;
+                        _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                            _this.grid.footer.onClick('first');
+                        }); */
+                    }
+                },
+                autoExpandColumn : 'cmhead_cust_id_cust_name',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            if ( _this.customer &&  _this.customer.getValue() ) {
+                               o.params.cmhead_cust_id = _this.customer.getValue();
+                            }
+                            if (_this.cmnumber && _this.cmnumber.getValue() ) {
+                               o.params.cmhead_id =  _this.cmnumber.getValue();
+                            }
+                            if (_this.status) { 
+                                o.params['query[status]'] = _this.status.getValue();
+                            }
+                            
+                            o.params._with_aropen = 1;
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'cmhead_id', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/cmhead.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'cmhead_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_number',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_posted',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_invcnumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_custponumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_cust_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_docdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cmhead_shipto_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_shipto_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_address1',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_address2',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_address3',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_city',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_state',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_zipcode',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_salesrep_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_freight',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cmhead_misc',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cmhead_comments',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_printed',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_billtoname',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtoaddress1',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtoaddress2',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtoaddress3',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtocity',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtostate',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_billtozip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_hold',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_commission',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cmhead_misc_accnt_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_misc_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_rsncode_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_curr_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_freighttaxtype_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_gldistdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cmhead_billtocountry',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_shipto_country',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cmhead_rahead_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_taxzone_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cmhead_prj_id',
+                                'type': 'int'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying cmhead{0} - {1} of {2}",
+                    emptyMsg : "No cmhead found"
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.cmnumber = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'cmhead_number',
+                            editable : true,
+                            emptyText : "Order",
+                            fieldLabel : 'ordernumber',
+                            forceSelection : true,
+                            hiddenName : 'cmhead_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'cmhead_number',
+                            pageSize : 20,
+                            qtip : "Select invchead",
+                            queryParam : 'query[cmhead_number]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cmhead_number}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : false,
+                            valueField : 'cmhead_id',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'cmhead_number' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/cmhead.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'cmhead_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"cmhead_id","type":"int"},"cmhead_number"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.customer = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'cust_name',
+                            editable : true,
+                            emptyText : "Select Customer",
+                            fieldLabel : 'cust_name',
+                            forceSelection : true,
+                            hiddenName : 'cust_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'cust_name',
+                            pageSize : 20,
+                            qtip : "Select custinfo",
+                            queryParam : 'query[cust_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : false,
+                            valueField : 'cust_id',
+                            width : 200,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                remoteSort : true,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/custinfo.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'cust_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.status = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : false,
+                            displayField : 'fname',
+                            editable : false,
+                            fieldLabel : 'Status',
+                            hiddenName : 'cm_status',
+                            listWidth : 200,
+                            mode : 'local',
+                            name : 'cm_status_name',
+                            triggerAction : 'all',
+                            value : "NOTCLOSED",
+                            valueField : 'ftype',
+                            width : 150,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                data : [ 
+                                    [ 'NOTCLOSED', "Not Closed"],
+                                    [ 'CLOSED' , "Closed"],
+                                    [ 'UNPOSTED', "Unposted only"] ,
+                                    [ 'UNUSED', "Posted and not used"] ,
+                                    [ 'VOIDED', "Voided"] 
+                                ],
+                                fields : [  'ftype', 'fname']
+                            }
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif',
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               Pman.Dialog.XtupleCreditMemoNew.show( {} , function() {
+                                                    _this.grid.footer.onClick('first');
+                                               }); 
+                                            
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "New Credit Memo",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.menu
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               var s = _this.grid.getSelectionModel().getSelections();
+                                            
+                                                if (!s.length || (s.length > 1))  {
+                                                    Roo.MessageBox.alert("Error", s.length ? "Select only one Row" : "Select a Row");
+                                                    return;
+                                                }    
+                                                if(s[0].data.checkhead_total == 0){
+                                                    Roo.MessageBox.alert("Error", "you cannot create the miscellaneous check for the credit memo coz the total amount remaining is 0! ");
+                                                    return;
+                                                }
+                                                if(!s[0].data.cmhead_posted){
+                                                    Roo.MessageBox.alert("Error", "This credit memo  has not been posted!");
+                                                    return;
+                                                }
+                                                var data = {
+                                                    'checkhead_recip_id' : s[0].data.cmhead_cust_id,
+                                                    'checkhead_recip_type' : 'C',
+                                                    'checkhead_checkdate' : new Date(),
+                                                    'checkhead_amount' : s[0].data.checkhead_total,
+                                                    'remaining_total' : s[0].data.checkhead_total,
+                                                    'checkhead_curr_id' : s[0].data.cmhead_curr_id,
+                                                    'checkhead_curr_id_curr_name' : s[0].data.cmhead_curr_id_curr_name,
+                                                    'checkhead_misc' : true,
+                                                    'aropen_id' : s[0].data.cmhead_aropen_id_aropen_id,
+                                                       'cmhead_number' : s[0].data.cmhead_number,
+                                               'cust_name' : s[0].data.cmhead_cust_id_cust_name,
+                                               '_create_and_post' : 1
+                                            
+                                                };
+                                                
+                                                
+                                                Pman.Dialog.XtupleMiscellaneousCheck.show( data , function() {
+                                                    _this.grid.footer.onClick('first');
+                                               }); 
+                                            
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "New Miscellaneous Check",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    }
+                                ]
+                            }
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelections();
+                                
+                                    if (!s.length || (s.length > 1))  {
+                                        Roo.MessageBox.alert("Error", s.length ? "Select only one Row" : "Select a Row");
+                                        return;
+                                    }
+                                
+                                    var postit = function()
+                                    {
+                                        new Pman.Request(
+                                        {
+                                            url : baseURL + '/Roo/Cmhead',
+                                            mask: 'Voiding',
+                                            method : 'POST',
+                                            params : {
+                                                cmhead_id : s[0].data.cmhead_id,
+                                                _void : 1
+                                            },
+                                            success : function()
+                                            {
+                                                _this.grid.footer.onClick('refresh');
+                                            } 
+                                        });
+                                    
+                                    };
+                                
+                                
+                                    Roo.MessageBox.confirm(
+                                        "Confirm",
+                                        "Are you sure to void this credit memo?",
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            postit();
+                                        }
+                                    );
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Void Credit Memo",
+                            icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelections();
+                                
+                                    if (!s.length || (s.length > 1))  {
+                                        Roo.MessageBox.alert("Error", s.length ? "Select only one Row" : "Select a Row");
+                                        return;
+                                    }
+                                    if (s[0].data.cmhead_posted ) { 
+                                        Roo.MessageBox.alert("Error", 
+                                            "You can not delete posted credit memo's - you have to create an invoice to reverse them");
+                                        return;
+                                    }
+                                    
+                                    
+                                
+                                    var postit = function()
+                                    {
+                                        new Pman.Request(
+                                        {
+                                            url : baseURL + '/Roo/Cmhead',
+                                            mask: 'Deleting',
+                                            method : 'POST',
+                                            params : {
+                                                _delete  : s[0].data.cmhead_id 
+                                            },
+                                            success : function()
+                                            {
+                                                _this.grid.footer.onClick('refresh');
+                                            } 
+                                        });
+                                    
+                                    };
+                                
+                                
+                                    Roo.MessageBox.confirm(
+                                        "Confirm Deletion",
+                                        "You will have to make sure this credit memo has no line items associated before deleting it. ",
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            postit();
+                                        }
+                                    );
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Delete Credit Memo",
+                            icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelections();
+                                
+                                    if (!s.length || (s.length > 1))  {
+                                        Roo.MessageBox.alert("Error", s.length ? "Select only one Row" : "Select a Row");
+                                        return;
+                                    }
+                                
+                                    var postit = function()
+                                    {
+                                        new Pman.Request(
+                                        {
+                                            url : baseURL + '/Roo/Cmhead',
+                                            mask: 'Posting',
+                                            method : 'POST',
+                                            params : {
+                                                cmhead_id : s[0].data.cmhead_id,
+                                                _post : 1
+                                            },
+                                            success : function()
+                                            {
+                                                _this.grid.footer.onClick('refresh');
+                                            } 
+                                        });
+                                    
+                                    };
+                                
+                                
+                                    Roo.MessageBox.confirm(
+                                        "Confirm Posting",
+                                        "Are you sure that is complete, <B>Voiding a Credit memo invoices creating a sales order and invoice</B>, so make sure this is correct before posting",
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            postit();
+                                        }
+                                    ); 
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "POST",
+                            icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelected();
+                                      if (!s || !s.data.cmhead_id) {
+                                        Roo.MessageBox.alert("Error", "Select a credit memo");
+                                        return
+                                      }
+                                      
+                                      var ext = baseURL.split('/').pop().replace(/\.php/, '');
+                                      new Pman.Download({
+                                        url : baseURL + '/Xtuple/Print',
+                                        params :  {
+                                            template: 'creditmemo-' + ext,
+                                            filename : 'creditmemo-' + s.data.cmhead_id,
+                                            'param[0]':   "cmhead_id:string='" + s.data.cmhead_id + "'"
+                                           
+                                        },
+                                        method : 'GET'
+                                     });
+                                     Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            
+                                            
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Print",
+                            icon : rootURL + '/Pman/templates/images/pdf.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            cls : 'x-btn-text-icon',
+                            text : "Tools",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif',
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.menu
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               Roo.MessageBox.confirm(
+                                                    "Confirm",
+                                                    "It is going to fill in all the blank return stock. Are you sure?",
+                                                    function(r) {
+                                                        if (r != 'yes') {
+                                                            return;
+                                                        }
+                                                        new Pman.Request(
+                                                        {
+                                                            url : baseURL + '/Roo/Cmhead',
+                                                            mask: 'Processing',
+                                                            method : 'POST',
+                                                            params : {
+                                                                _fix_stock : 1
+                                                            },
+                                                            success : function()
+                                                            {
+                                                                Roo.MessageBox.alert('Notice','Fixed');
+                                                                _this.grid.footer.onClick('refresh');
+                                                            } 
+                                                        });
+                                                    }
+                                                ); 
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Fix Blank Return Stock",
+                                        icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cmhead_number',
+                        header : 'Ref #',
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cmhead_docdate',
+                        header : 'Date',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cmhead_salesrep_id_salesrep_name',
+                        header : 'Sales Rep',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v  ); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cmhead_cust_id_cust_name',
+                        header : 'Customer',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cmhead_curr_id_curr_symbol',
+                        header : 'Currency',
+                        width : 70,
+                        renderer : function(v)
+                        {
+                            return String.format('{0}', v ? v : '??');
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cmhead_value',
+                        header : 'Value',
+                        width : 100,
+                        renderer : function(v)
+                        {
+                            return Roo.util.Format.usMoney(v);
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cmhead_unpaid',
+                        header : 'Open Value',
+                        width : 100,
+                        renderer : function(v,x,r)
+                        {
+                            if (!r.data.cmhead_posted) {
+                                return '';
+                            }
+                            return Roo.util.Format.usMoney(v);
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cmhead_posted',
+                        header : 'Posted',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? 'Yes':''); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleCustomer.bjs b/Pman.Tab.XtupleCustomer.bjs
new file mode 100644 (file)
index 0000000..1896613
--- /dev/null
@@ -0,0 +1,527 @@
+{
+    "id": "roo-file-351",
+    "name": "Pman.Tab.XtupleCustomer",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleCustomer.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            ".builderCfg": "{\"cols\":[{\"table\":\"custinfo\",\"column\":\"cust_active\",\"columnshort\":\"cust_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Active\"},{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Sales Rep\"},{\"table\":\"custinfo\",\"column\":\"cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Name\"}],\"cols_ex\":[\"cust_name\"],\"table\":\"custinfo\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "custinfo",
+            "title": "Customers",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    _this.dialog = Pman.Dialog.XtupleCustomer;\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('refresh');\n    }); \n}\n"
+                    },
+                    "*prop": "grid",
+                    ".builderCfg": "{\"cols\":[{\"table\":\"custinfo\",\"column\":\"cust_active\",\"columnshort\":\"cust_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Active\"},{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Sales Rep\"},{\"table\":\"custinfo\",\"column\":\"cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Name\"}],\"cols_ex\":[\"cust_name\"],\"table\":\"custinfo\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                    "autoExpandColumn": "cust_name",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    if (!_this.officeCombo) {\n        return false;\n    }\n    \n    o.params = o.params || {};\n    o.params['search[cust_name]'] = _this.searchBox.getValue();\n    if (!_this.activeBtn.pressed) {\n        o.params.cust_active = 1;\n    } \n    var dt = _this.dateSearch.getValue(); \n    if (dt) {\n        o.params['search[orders_since]'] = dt.format('Y-m-d');\n    }\n    dt = _this.dateSearchNo.getValue(); \n    if (dt) {\n        o.params['search[no_orders_since]'] = dt.format('Y-m-d');\n    }\n    \n    o.params['search[with_orders_since]'] = 1; //\n    o.params['search[with_balance]'] = 1;\n    o.params['search[with_address]'] = 1;\n    o.params['_with_char'] = 1;    \n    o.params['_with_group_data'] = 1;\n    o.params['search[_country]'] = _this.country.getValue();\n    o.params._get = 1; // for download\n    \n    o.params['cust_char_internalcompany'] = _this.officeCombo.getValue();\n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'cust_name', direction: 'ASC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "method": "GET",
+                                    "xtype": "HttpProxy",
+                                    "|url": "baseURL + '/Roo/custinfo.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"custinfo\",\"column\":\"cust_active\",\"columnshort\":\"cust_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Active\"},{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"},{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Sales Rep\"},{\"table\":\"custinfo\",\"column\":\"cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Name\"}],\"cols_ex\":[\"cust_name\"],\"table\":\"custinfo\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'cust_active',\n        'type': 'boolean'\n    },\n    {\n        'name': 'cust_custtype_id_custtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cust_salesrep_id_salesrep_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cust_name',\n        'type': 'string'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying custinfo{0} - {1} of {2}",
+                            "emptyMsg": "No custinfo found",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "text": "Upload/Download",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    if (!Pman.hasPerm('Xtuple.CustomerDownload','S')) {\n        Roo.MessageBox.alert(\"Error\", \"Permission Denied\");\n        return;\n    }\n    _this.grid.ds.proxy.conn.method = 'POST';\n    new Pman.Download({\n        grid : _this.grid\n    });\n    \n}"
+                                                    },
+                                                    "text": "Download Customers",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    if (!Pman.hasPerm('Admin.Admin_Tab','S')) {\n        Roo.MessageBox.alert(\"Error\", \"Permission Denied\");\n        return;\n    }\n    \n    var c = _this.country.getValue();\n    if(!c.length){\n        Roo.MessageBox.alert(\"Error\", \"Please select a country\");\n        return;\n    }\n    \n    new Pman.Download({\n        url : baseURL + '/Roo/custinfo',\n        method : 'GET',\n        params : {\n            _my_json : 1,\n            limit : 9999,\n            'search[_country]' : c,\n            'search[with_address]' : 1\n        }\n        \n    });\n}"
+                                                    },
+                                                    "text": "Download Customers As Json",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    if (!Pman.hasPerm('Admin.Admin_Tab','S')) {\n        Roo.MessageBox.alert(\"Error\", \"Permission Denied\");\n        return;\n    }\n   \n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Customers' \n        \n       },\n       function (data) {\n            _this.grid.footer.onClick('first');\n            Roo.MessageBox.alert(\"Notice\", \"DONE\");\n//            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n    \n}"
+                                                    },
+                                                    "text": "Upload Customers",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    if (!Pman.hasPerm('Admin.Admin_Tab','S')) {\n        Roo.MessageBox.alert(\"Error\", \"Permission Denied\");\n        return;\n    }\n   \n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/MyCustomers' \n        \n       },\n       function (data) {\n            _this.grid.footer.onClick('first');\n            Roo.MessageBox.alert(\"Notice\", \"DONE\");\n//            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n    \n}"
+                                                    },
+                                                    "text": "Upload Customers Json File",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    if (!Pman.hasPerm('Admin.Admin_Tab','S')) {\n        Roo.MessageBox.alert(\"Error\", \"Permission Denied\");\n        return;\n    }\n   \n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/AUPostAccounts' \n        \n       },\n       function (data) {\n            _this.grid.footer.onClick('first');\n            Roo.MessageBox.alert(\"Notice\", data);\n\n       }\n   );\n    \n}"
+                                                    },
+                                                    "text": "Upload AU Post Accounts",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "text": "Search : ",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.searchBox = _self;\n}",
+                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\n    \n    \n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.officeCombo  = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "xtype": "ComboBox",
+                                    "allowBlank": true,
+                                    "displayField": "office",
+                                    "editable": false,
+                                    "fieldLabel": "Office",
+                                    "hiddenName": "office",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "office",
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{office}</b> </div>",
+                                    "triggerAction": "all",
+                                    "valueField": "office",
+                                    "width": 75,
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ ''] ,\n    [ 'hk' ],\n    [ 'sg' ],\n    [ 'my' ],\n    [ 'cn' ],\n    [ 'au' ]\n]\n        ",
+                                            "|fields": "['office']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.country = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "alwaysQuery": true,
+                                    "displayField": "addr_country",
+                                    "editable": true,
+                                    "emptyText": "Select Country",
+                                    "fieldLabel": "Country",
+                                    "forceSelection": true,
+                                    "hiddenName": "addr_country",
+                                    "listWidth": 300,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "addr_country",
+                                    "pageSize": 20,
+                                    "qtip": "Select Country",
+                                    "queryParam": "query[addr_country]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_country}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "addr_country",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params._distinct = 'addr_country';\n    o.params._columns ='addr_country';\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'addr_country' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Addr.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "addr_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"addr_id\",\"type\":\"int\"},{\"name\":\"addr_country\",\"type\":\"string\"}]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "toggle": "function (_self, pressed)\n{\n    _this.grid.footer.onClick('first');\n}",
+                                        "render": "function (_self)\n{\n    _this.activeBtn = _self;\n}"
+                                    },
+                                    "enableToggle": true,
+                                    "pressed": false,
+                                    "text": "Show / Hide Inactive",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "text": "Has orders since",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.dateSearch = _self\n}",
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}",
+                                        "specialkey": "function (_self, e)\n{\n   _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "format": "Y-m-d",
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "text": "No orders since",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.dateSearchNo = _self\n}",
+                                        "select": "function (combo, date)\n{\n   _this.grid.footer.onClick('first');\n}",
+                                        "specialkey": "function (_self, e)\n{\n   _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "format": "Y-m-d",
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "xtype": "Fill",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( { id : 0 } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var s = _this.grid.getSelectionModel().getSelections();\n    if (!s.length || (s.length > 1))  {\n        Roo.MessageBox.alert(\"Error\", s.length ? \"Select only one Row\" : \"Select a Row\");\n        return;\n    }\n    if (!_this.dialog) return;\n    _this.dialog.show(s[0].data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n    \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Edit",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"custinfo\",\"column\":\"cust_active\",\"columnshort\":\"cust_active\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Active\"}",
+                            "dataIndex": "cust_active",
+                            "header": "Active",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v? 'Y' : 'N'); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "last_order",
+                            "header": "Last Order",
+                            "width": 80,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    if (!v) { \n        return '-none-';\n    }\n    var vv = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}',  vv.format('d/M/Y') ); \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"}",
+                            "dataIndex": "cust_taxzone_id_taxzone_descrip",
+                            "header": "Tax Status",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"}",
+                            "dataIndex": "cust_terms_id_terms_descrip",
+                            "header": "Terms",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"salesrep\",\"column\":\"cust_salesrep_id_salesrep_name\",\"columnshort\":\"salesrep_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Sales Rep\"}",
+                            "dataIndex": "cust_salesrep_id_salesrep_name",
+                            "header": "Sales Rep",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "ipshead_id_name",
+                            "header": "Curr/Price List",
+                            "sortable": true,
+                            "width": 80,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    if (!v.length) {\n         return String.format('{0}<br/><span style=\"color:red\">No price list</span>', \n        r.data.cust_curr_id_curr_name  );\n     }    \n\n    return  String.format('{0}<br/>{1}', \n        r.data.cust_curr_id_curr_name,\n       v ); \n   }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_number",
+                            "header": "Ref No.",
+                            "sortable": true,
+                            "width": 80,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_name",
+                            "header": "Name",
+                            "sortable": true,
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {\n    if (!r.data.cust_char_internalcompany.length) {\n         return String.format('{0}', v); \n     }\n    return String.format('<span style=\"color:red\">[Internal company : {0}] {1}</span>',\n        r.data.cust_char_internalcompany,  v); \n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_bill_info",
+                            "header": "Billing Address",
+                            "sortable": true,
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    if(!v.length){\n        var add = [];\r\n        Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {\r\n            if (!r.data['cntct_addr_' + k].length) {\r\n                return;\r\n            }\r\n            add.push(String.format(\"{0}\", r.data['cntct_addr_' + k]));\r\n        \r\n        });\n        return add.join('<BR/>');\n    }\n    \n    var v = v.split(\"\\r\\n\").join(\"<br/>\");\n    return v; \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_ship_info",
+                            "header": "Shipping Address",
+                            "sortable": true,
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    if(!v.length){\n        var add = [];\r\n        Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {\r\n            if (!r.data['cntct_addr_' + k].length) {\r\n                return;\r\n            }\r\n            add.push(String.format(\"{0}\", r.data['cntct_addr_' + k]));\r\n        \r\n        });\n        return add.join('<BR/>');\n    }\n    \n    var v = v.split(\"\\r\\n\").join(\"<br/>\");\n    return v; \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_cntct_id_cntct_first_name",
+                            "header": "Contact",
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    return String.format(\n        'Name: {0}<br/>' + \n        'Phone: {1}<br/>' + \n        'Email: <a href=\"mailto:{2}\">{2}</a>',\n    \n        r.data.cust_cntct_id_cntct_first_name,\n        r.data.cust_cntct_id_cntct_phone,\n        r.data.cust_cntct_id_cntct_email\n    );\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_char_au_post_accno",
+                            "header": "AU Post#",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    return String.format('{0}', v);\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_cntct_id_cntct_phone",
+                            "header": "Contact Number",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    return String.format('{0}',v);\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_cntct_id_cntct_email",
+                            "header": "Email",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) \n{ \n    return String.format('<a href=\"mailto:{0}\">{0}</a>', v);\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cntct_addr_city",
+                            "header": "City",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cntct_addr_state",
+                            "header": "State",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cntct_addr_country",
+                            "header": "Country",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"custtype\",\"column\":\"cust_custtype_id_custtype_descrip\",\"columnshort\":\"custtype_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Customer type\"}",
+                            "dataIndex": "cust_curr_id_curr_name",
+                            "header": "Currency",
+                            "sortable": true,
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "balance",
+                            "header": "Balance",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n     \n    return String.format('{0}{1}', r.data.cust_curr_id_curr_symbol, Roo.util.Format.number(v,2)); \n}",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "700"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleCustomer.js b/Pman.Tab.XtupleCustomer.js
new file mode 100644 (file)
index 0000000..91b4c65
--- /dev/null
@@ -0,0 +1,805 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleCustomer = new Roo.XComponent({
+    part     :  ["Xtuple","Customer"],
+    order    : '700-Pman.Tab.XtupleCustomer',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'custinfo',
+            title : "Customers",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        _this.dialog = Pman.Dialog.XtupleCustomer;
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        if (!_this.dialog) return;
+                        _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                            _this.grid.footer.onClick('refresh');
+                        }); 
+                    }
+                },
+                autoExpandColumn : 'cust_name',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            if (!_this.officeCombo) {
+                                return false;
+                            }
+                            
+                            o.params = o.params || {};
+                            o.params['search[cust_name]'] = _this.searchBox.getValue();
+                            if (!_this.activeBtn.pressed) {
+                                o.params.cust_active = 1;
+                            } 
+                            var dt = _this.dateSearch.getValue(); 
+                            if (dt) {
+                                o.params['search[orders_since]'] = dt.format('Y-m-d');
+                            }
+                            dt = _this.dateSearchNo.getValue(); 
+                            if (dt) {
+                                o.params['search[no_orders_since]'] = dt.format('Y-m-d');
+                            }
+                            
+                            o.params['search[with_orders_since]'] = 1; //
+                            o.params['search[with_balance]'] = 1;
+                            o.params['search[with_address]'] = 1;
+                            o.params['_with_char'] = 1;    
+                            o.params['_with_group_data'] = 1;
+                            o.params['search[_country]'] = _this.country.getValue();
+                            o.params._get = 1; // for download
+                            
+                            o.params['cust_char_internalcompany'] = _this.officeCombo.getValue();
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'cust_name', direction: 'ASC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/custinfo.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'cust_active',
+                                'type': 'boolean'
+                            },
+                            {
+                                'name': 'cust_custtype_id_custtype_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cust_salesrep_id_salesrep_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cust_name',
+                                'type': 'string'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying custinfo{0} - {1} of {2}",
+                    emptyMsg : "No custinfo found",
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            text : "Upload/Download",
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                if (!Pman.hasPerm('Xtuple.CustomerDownload','S')) {
+                                                    Roo.MessageBox.alert("Error", "Permission Denied");
+                                                    return;
+                                                }
+                                                _this.grid.ds.proxy.conn.method = 'POST';
+                                                new Pman.Download({
+                                                    grid : _this.grid
+                                                });
+                                                
+                                            }
+                                        },
+                                        text : "Download Customers"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                if (!Pman.hasPerm('Admin.Admin_Tab','S')) {
+                                                    Roo.MessageBox.alert("Error", "Permission Denied");
+                                                    return;
+                                                }
+                                                
+                                                var c = _this.country.getValue();
+                                                if(!c.length){
+                                                    Roo.MessageBox.alert("Error", "Please select a country");
+                                                    return;
+                                                }
+                                                
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/custinfo',
+                                                    method : 'GET',
+                                                    params : {
+                                                        _my_json : 1,
+                                                        limit : 9999,
+                                                        'search[_country]' : c,
+                                                        'search[with_address]' : 1
+                                                    }
+                                                    
+                                                });
+                                            }
+                                        },
+                                        text : "Download Customers As Json"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                if (!Pman.hasPerm('Admin.Admin_Tab','S')) {
+                                                    Roo.MessageBox.alert("Error", "Permission Denied");
+                                                    return;
+                                                }
+                                               
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/Customers' 
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        _this.grid.footer.onClick('first');
+                                                        Roo.MessageBox.alert("Notice", "DONE");
+                                            //            Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                            
+                                                   }
+                                               );
+                                                
+                                            }
+                                        },
+                                        text : "Upload Customers"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                if (!Pman.hasPerm('Admin.Admin_Tab','S')) {
+                                                    Roo.MessageBox.alert("Error", "Permission Denied");
+                                                    return;
+                                                }
+                                               
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/MyCustomers' 
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        _this.grid.footer.onClick('first');
+                                                        Roo.MessageBox.alert("Notice", "DONE");
+                                            //            Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                            
+                                                   }
+                                               );
+                                                
+                                            }
+                                        },
+                                        text : "Upload Customers Json File"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                if (!Pman.hasPerm('Admin.Admin_Tab','S')) {
+                                                    Roo.MessageBox.alert("Error", "Permission Denied");
+                                                    return;
+                                                }
+                                               
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/AUPostAccounts' 
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        _this.grid.footer.onClick('first');
+                                                        Roo.MessageBox.alert("Notice", data);
+                                            
+                                                   }
+                                               );
+                                                
+                                            }
+                                        },
+                                        text : "Upload AU Post Accounts"
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "Search : "
+                        },
+                        {
+                            xtype: 'TextField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.searchBox = _self;
+                                },
+                                specialkey : function (_self, e)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/search.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    _this.searchBox.setValue('');
+                                    
+                                    
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.officeCombo  = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'office',
+                            editable : false,
+                            fieldLabel : 'Office',
+                            hiddenName : 'office',
+                            listWidth : 200,
+                            mode : 'local',
+                            name : 'office',
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{office}</b> </div>',
+                            triggerAction : 'all',
+                            valueField : 'office',
+                            width : 75,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                data : [ 
+                                    [ ''] ,
+                                    [ 'hk' ],
+                                    [ 'sg' ],
+                                    [ 'my' ],
+                                    [ 'cn' ],
+                                    [ 'au' ]
+                                ],
+                                fields : ['office']
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.country = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            alwaysQuery : true,
+                            displayField : 'addr_country',
+                            editable : true,
+                            emptyText : "Select Country",
+                            fieldLabel : 'Country',
+                            forceSelection : true,
+                            hiddenName : 'addr_country',
+                            listWidth : 300,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'addr_country',
+                            pageSize : 20,
+                            qtip : "Select Country",
+                            queryParam : 'query[addr_country]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_country}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'addr_country',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params._distinct = 'addr_country';
+                                        o.params._columns ='addr_country';
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'addr_country' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Addr.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'addr_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"addr_id","type":"int"},{"name":"addr_country","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                toggle : function (_self, pressed)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                    _this.activeBtn = _self;
+                                }
+                            },
+                            enableToggle : true,
+                            pressed : false,
+                            text : "Show / Hide Inactive"
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "Has orders since"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.dateSearch = _self
+                                },
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                },
+                                specialkey : function (_self, e)
+                                {
+                                   _this.grid.footer.onClick('first');
+                                }
+                            },
+                            format : 'Y-m-d'
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "No orders since"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.dateSearchNo = _self
+                                },
+                                select : function (combo, date)
+                                {
+                                   _this.grid.footer.onClick('first');
+                                },
+                                specialkey : function (_self, e)
+                                {
+                                   _this.grid.footer.onClick('first');
+                                }
+                            },
+                            format : 'Y-m-d'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( { id : 0 } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var s = _this.grid.getSelectionModel().getSelections();
+                                    if (!s.length || (s.length > 1))  {
+                                        Roo.MessageBox.alert("Error", s.length ? "Select only one Row" : "Select a Row");
+                                        return;
+                                    }
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show(s[0].data, function() {
+                                        _this.grid.footer.onClick('first');
+                                    }); 
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Edit",
+                            icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_active',
+                        header : 'Active',
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v? 'Y' : 'N'); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'last_order',
+                        header : 'Last Order',
+                        width : 80,
+                        renderer : function(v) { 
+                            if (!v) { 
+                                return '-none-';
+                            }
+                            var vv = Date.parseDate(v, 'Y-m-d');
+                            return String.format('{0}',  vv.format('d/M/Y') ); 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_taxzone_id_taxzone_descrip',
+                        header : 'Tax Status',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_terms_id_terms_descrip',
+                        header : 'Terms',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_salesrep_id_salesrep_name',
+                        header : 'Sales Rep',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'ipshead_id_name',
+                        header : 'Curr/Price List',
+                        sortable : true,
+                        width : 80,
+                        renderer : function(v,x,r) { 
+                            if (!v.length) {
+                                 return String.format('{0}<br/><span style="color:red">No price list</span>', 
+                                r.data.cust_curr_id_curr_name  );
+                             }    
+                        
+                            return  String.format('{0}<br/>{1}', 
+                                r.data.cust_curr_id_curr_name,
+                               v ); 
+                           }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_number',
+                        header : 'Ref No.',
+                        sortable : true,
+                        width : 80,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_name',
+                        header : 'Name',
+                        sortable : true,
+                        width : 200,
+                        renderer : function(v,x,r) {
+                            if (!r.data.cust_char_internalcompany.length) {
+                                 return String.format('{0}', v); 
+                             }
+                            return String.format('<span style="color:red">[Internal company : {0}] {1}</span>',
+                                r.data.cust_char_internalcompany,  v); 
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_bill_info',
+                        header : 'Billing Address',
+                        sortable : true,
+                        width : 200,
+                        renderer : function(v,x,r) 
+                        { 
+                            if(!v.length){
+                                var add = [];
+                                Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {
+                                    if (!r.data['cntct_addr_' + k].length) {
+                                        return;
+                                    }
+                                    add.push(String.format("{0}", r.data['cntct_addr_' + k]));
+                                
+                                });
+                                return add.join('<BR/>');
+                            }
+                            
+                            var v = v.split("\r\n").join("<br/>");
+                            return v; 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_ship_info',
+                        header : 'Shipping Address',
+                        sortable : true,
+                        width : 200,
+                        renderer : function(v,x,r) 
+                        { 
+                            if(!v.length){
+                                var add = [];
+                                Roo.each([ 'line1', 'line2', 'line3', 'city', 'state', 'country'], function (k) {
+                                    if (!r.data['cntct_addr_' + k].length) {
+                                        return;
+                                    }
+                                    add.push(String.format("{0}", r.data['cntct_addr_' + k]));
+                                
+                                });
+                                return add.join('<BR/>');
+                            }
+                            
+                            var v = v.split("\r\n").join("<br/>");
+                            return v; 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_cntct_id_cntct_first_name',
+                        header : 'Contact',
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) 
+                        { 
+                            return String.format(
+                                'Name: {0}<br/>' + 
+                                'Phone: {1}<br/>' + 
+                                'Email: <a href="mailto:{2}">{2}</a>',
+                            
+                                r.data.cust_cntct_id_cntct_first_name,
+                                r.data.cust_cntct_id_cntct_phone,
+                                r.data.cust_cntct_id_cntct_email
+                            );
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_char_au_post_accno',
+                        header : 'AU Post#',
+                        hidden : true,
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) 
+                        { 
+                            return String.format('{0}', v);
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_cntct_id_cntct_phone',
+                        header : 'Contact Number',
+                        hidden : true,
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) 
+                        { 
+                            return String.format('{0}',v);
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_cntct_id_cntct_email',
+                        header : 'Email',
+                        hidden : true,
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) 
+                        { 
+                            return String.format('<a href="mailto:{0}">{0}</a>', v);
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cntct_addr_city',
+                        header : 'City',
+                        hidden : true,
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cntct_addr_state',
+                        header : 'State',
+                        hidden : true,
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cntct_addr_country',
+                        header : 'Country',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_curr_id_curr_name',
+                        header : 'Currency',
+                        sortable : true,
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'balance',
+                        header : 'Balance',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                        
+                             
+                            return String.format('{0}{1}', r.data.cust_curr_id_curr_symbol, Roo.util.Format.number(v,2)); 
+                        }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleDashboard.bjs b/Pman.Tab.XtupleDashboard.bjs
new file mode 100644 (file)
index 0000000..2084b09
--- /dev/null
@@ -0,0 +1,502 @@
+{
+    "id": "roo-file-304",
+    "name": "Pman.Tab.XtupleDashboard",
+    "parent": "Pman",
+    "title": "Pman.Tab.XtupleDashboard",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleDashboard.bjs",
+    "items": [
+        {
+            "listeners": {
+                "activate": "function (_self)\n{\n    \n    try {\n       // Pman.Xtuple.DashboardRender.load();    \n    } catch (e) {\n        Roo.log(e);\n    }\n    \n}"
+            },
+            "region": "center",
+            "title": "Management Dashboard",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "west",
+                            "hidden": false,
+                            "split": true,
+                            "width": 200,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "center",
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "render": "function (_self)\n{\n    _this.dashpanel = _self;\n    \n    \n    (function() { \n            this.layout.getRegion('center').showPanel(0);\n    }).defer(100,this);\n}"
+                            },
+                            "region": "center",
+                            "xtype": "NestedLayoutPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "BorderLayout",
+                                    "*prop": "layout",
+                                    "items": [
+                                        {
+                                            "*prop": "center",
+                                            "hideTabs": true,
+                                            "xtype": "LayoutRegion",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "render": "function (_self)\n{\n    _this.viewPanel = _self;\n    \n  \n    //_this.paper = Raphael(_self.el.dom);\n    \n\n \n    \n    \n    \n}",
+                                                "resize": "function (_self, width, height)\n{\n    \n   Roo.log(\"RESIZE\");\n   /* _this.svg.attr(\"width\", width)\n        .attr(\"height\", height);\n        */\n   //      _this.paper.setSize(width, 400);\n    try {\nPman.Clipping.DashboardRender.resize(width,height);\n    } catch (e) {\n        Roo.log(e);\n    }\n\n   \n    \n}",
+                                                "activate": "function (_self)\n{\n    if (!_this.loadonce) {\n        _this.loadonce = true;\n    \n        (function () { Pman.Xtuple.DashboardRender.load(); }).defer(1000); \n    }\n}"
+                                            },
+                                            "autoScroll": true,
+                                            "fitContainer": true,
+                                            "fitToFrame": true,
+                                            "region": "center",
+                                            "xtype": "ContentPanel",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "text": "Show : ",
+                                                            "xtype": "TextItem",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.countryCombo= _self;\n}"
+                                                            },
+                                                            "allowBlank": true,
+                                                            "displayField": "addr_country",
+                                                            "editable": false,
+                                                            "emptyText": " Country",
+                                                            "forceSelection": true,
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "addr_country",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select addr",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_country}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": true,
+                                                            "width": 100,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params._distinct = 'addr_country';\n    o.params._columns = 'addr_country';    \n    o.params['!addr_country'] = '';\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'addr_country' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "xtype": "HttpProxy",
+                                                                            "method": "GET",
+                                                                            "|xns": "Roo.data",
+                                                                            "|url": "baseURL + '/Roo/addr.php'"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "xtype": "JsonReader",
+                                                                            "|xns": "Roo.data",
+                                                                            "id": "id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"addr_line1\",\"type\":\"string\"}]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n  _this.viewType = _self;\n   _this.dateRange = function() {\n                return {\n                   date_from : _this.mfrom.getValue(),\n                    date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.YEAR, 1).format('Y-m-d')\n         \n                };\n           \n           };\n}",
+                                                                "select": "function (combo, record, index)\n{\n    Roo.log('select');\n   // Pman.Clipping.DashboardRender.load();\n    var n = new Date();\n    var ys = n.format('Y' )+ '-05-01';\n    n = Date.parseDate(ys, 'Y-n-d');\n    \n    var ftype = record ? record.data.ftype : this.getValue();\n    \n    switch(ftype) {\n        case 'Y':\n            //Roo.log(Date.parseDate(ys, 'Y-n-d'));\n           _this.mfrom.setValue(Date.parseDate(ys, 'Y-n-d'));\n           _this.mfrom.show();\n           _this.mto.hide(); \n           _this.daypick.hide();\n           \n           _this.dateRange = function() {\n                return {\n                   date_from : _this.mfrom.getValue(),\n                    date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.YEAR, 1).format('Y-m-d')\n         \n                };\n           \n           };\n           \n           \n            break;\n        case 'H':        \n        // ?? latest half\n            var m = (new Date()).format('n')*1  > 6 ? 6 : 0;\n            Roo.log(m);\n            Roo.log( n.add(Date.MONTH,m));\n           _this.mfrom.setValue(n.add(Date.MONTH,m));           \n           _this.mfrom.show();\n           _this.mto.hide(); \n           _this.daypick.hide();\n           _this.dateRange = function() {\n                return {\n                    date_from : _this.mfrom.getValue(),\n                    date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 6).format('Y-m-d')\n                };\n           };\n          break;\n        case 'Q':                \n        \n            var m = Math.floor(((new Date()).format('n') *1 -1) / 4) * 4;\n\n           _this.mfrom.setValue(n.add(Date.MONTH, m));           \n           _this.mfrom.show();\n           _this.mto.hide(); \n           _this.daypick.hide();\n           _this.dateRange = function() {\n                return {\n                    date_from : _this.mfrom.getValue(),\n                    date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 3).format('Y-m-d')\n                };\n            };   \n            break;\n\n        case 'M':        \n            var m = (new Date()).format('n') *1  - 1 ;\n           _this.mfrom.setValue(n.add(Date.MONTH, m ));\n           _this.mfrom.show();\n           _this.mto.hide(); \n           _this.daypick.hide();\n            _this.dateRange = function() {\n                return {\n                    date_from : _this.mfrom.getValue(),\n                    date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 1).format('Y-m-d')\n                };\n            };   \n            break;        \n        \n\n        \n        case 'R':\n            // this month..\n            var m = (new Date()).format('n') * 1;            \n           _this.mfrom.setValue(n.add(Date.MONTH, m-1 )); \n           _this.mto.setValue(n.add(Date.MONTH,m )); \n        \n        \n        \n             _this.mfrom.show();\n            _this.mto.show(); \n            _this.daypick.hide();\n             _this.dateRange = function() {\n                return {\n                    date_from : _this.mfrom.getValue(),\n                    date_to : _this.mto.getValue()\n                };\n            };   \n            \n            \n            break;\n        /*\n         case 'W': // today\n            var d = (new Date()).format('w') * -1;\n            _this.daypick.setValue( (new Date()).add(Date.DAY, d )); \n             _this.mfrom.hide();\n            _this.mto.hide(); \n            _this.daypick.show();\n            break;\n        \n        \n        case 'D': // today\n            _this.daypick.setValue(new Date()); \n             _this.mfrom.hide();\n            _this.mto.hide(); \n            _this.daypick.show();\n            break;\n            */\n        default:\n            alerT(\"oops invalid ftype?\");\n            return;\n    }\n    \n    \n    \n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "displayField": "fname",
+                                                            "editable": false,
+                                                            "fieldLabel": "Status",
+                                                            "hiddenName": "cm_status",
+                                                            "listWidth": 200,
+                                                            "mode": "local",
+                                                            "name": "cm_status_name",
+                                                            "triggerAction": "all",
+                                                            "value": "R",
+                                                            "valueField": "ftype",
+                                                            "width": 150,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "xtype": "SimpleStore",
+                                                                    "|data": "[ \n    [ 'Y', \"Show Year From\"],\n    [ 'H' , \"6 Months From\"],\n    [ 'Q', \"3 Months From\"] ,\n    [ 'M', \"Single Month\"],\n   // [ 'W', \"Single Week Starting\"],\n    [ 'R', \"Between these Dates\"] //,\n  //  [ 'D', \"Single Day\"]\n    \n]\n",
+                                                                    "|fields": "[  'ftype', 'fname']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.mfrom=  _self;\n}"
+                                                            },
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|value": "(function() {\n    var n = new Date();\n    // previous apr.\n    var y = n.format('Y');\n    if (n.format('m') < 5) { \n        y--;\n    }\n    \n    return Date.parseDate(y  + '-05-01', 'Y-m-d');\n})()",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.mto=  _self;\n    //this.hide();\n}"
+                                                            },
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|value": "(function() {\n    var n = (new Date()).add(Date.YEAR, 1);\n    \n    var n = new Date();\n    // previous apr.\n    var y = n.format('Y');\n    if (n.format('m') >= 5) { \n        y++;\n    }\n    \n    return Date.parseDate(y  + '-05-01', 'Y-m-d');\n    \n    \n\n})()",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.daypick = _self;\n    this.hide();\n}"
+                                                            },
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|value": "(function() {\n//    var n = new Date();\n    return new Date();\n})()",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n    Pman.Xtuple.DashboardRender.load();\n}"
+                                                            },
+                                                            "text": "Run Report",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "text": "Other Reports",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Menu",
+                                                                    "*prop": "menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/SalesByCustomer',\n        params : _this.dateRange()\n    \n    });\n}\n"
+                                                                            },
+                                                                            "text": "Sales By Customer",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/SalesByCountry',\n        params :  _this.dateRange()\n    \n    });\n}\n"
+                                                                            },
+                                                                            "text": "Sales By Country",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/SalesByProduct',\n        params :  _this.dateRange()\n    \n    });\n}\n"
+                                                                            },
+                                                                            "text": "Sales By Product",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Separator"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/PurchasesByVendor',\n        params :  _this.dateRange()\n    \n    });\n}\n"
+                                                                            },
+                                                                            "text": "Purchases By Vendor",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/PurchasesByProduct',\n        params :  _this.dateRange()\n    \n    });\n}\n"
+                                                                            },
+                                                                            "text": "Purchases By Product",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Separator"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/StockAtLocation',\n         params :  _this.dateRange()\n    \n    });\n    Roo.MessageBox.alert(\"Downloading\", \n        \"The file will start downloading shortly - it may take around 1-2 minutes to calculate\");\n    \n}\n"
+                                                                            },
+                                                                            "text": "Historical Stock Levels (EO HKFY)",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        },
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Separator"
+                                                                        },
+                                                                        {
+                                                                            "listeners": {
+                                                                                "click": "function (_self, e)\n{\n    new Pman.Download({\n        url :baseURL + '/Xtuple/Reports/SGTax',\n         params :  _this.dateRange()\n    \n    });\n    Roo.MessageBox.alert(\"Downloading\", \n        \"The file will start downloading shortly - it may take around 1-2 minutes to calculate\");\n    \n}\n"
+                                                                            },
+                                                                            "text": "SG Tax report",
+                                                                            "xtype": "Item",
+                                                                            "|xns": "Roo.menu"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Spacer"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "text": "Theme : ",
+                                                            "xtype": "TextItem",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "select": "function (combo, record, index)\n{\n    Pman.Xtuple.DashboardRender.load();\n}",
+                                                                "render": "function (_self)\n{\n    _this.themeCombo = this;\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "displayField": "name",
+                                                            "editable": false,
+                                                            "hiddenName": "colortheme",
+                                                            "listWidth": 300,
+                                                            "name": "colorTheme_title",
+                                                            "qtip": "Select a Color Theme",
+                                                            "selectOnFocus": true,
+                                                            "triggerAction": "all",
+                                                            "typeAhead": false,
+                                                            "valueField": "themeData",
+                                                            "xtype": "ComboBox",
+                                                            "|value": "(function() {\n     return Pman.Xtuple ? Pman.Xtuple.DashboardRender.colorthemes()[12][1] : ''; \n})() ",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "xtype": "SimpleStore",
+                                                                    "|data": "(function() {\n    return (typeof Pman.Xtuple != 'undefined') ? Pman.Xtuple.DashboardRender.colorthemes() : [];\n    \n})()",
+                                                                    "|fields": "['name','themeData']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "render": "function (_self)\n{\n    _this.reportpanel = _self;\n}"
+                                            },
+                                            "autoScroll": true,
+                                            "fitToFrame": true,
+                                            "region": "center",
+                                            "xtype": "ContentPanel",
+                                            "|showReport": "function(node, isxls) {\n    if (node) {\n        _this.selectedNode = node;\n    }\n    var rc = _this.reportCompany.getValue();\n    var params =  {\n        flhead_name : _this.selectedNode.attributes.text,\n        ts : Math.random(),\n        period : _this.reportDateFrom.getValue(),\n        interval:   _this.reportInterval.getValue(),\n        company : (_this.reportCompany.hidden) ? '' : rc == 'consolidated' ? '' : rc,\n        singleCountry :  rc == 'consolidated' ? 0 : 1\n    };\n    \n    if (isxls) {\n        params._xls = 1;\n        new Pman.Download({\n            url : baseURL + '/Xtuple/Reports/ConsolidatedAccounts',\n            method: 'GET',\n            timeout: 120000,\n            params :  params\n        });\n        Roo.MessageBox.alert(\"Notice\", \"Report is downloading now for the combined report this will take about 50s\");\n        return;\n    }\n    var el = this.region.el;\n\n    var done = false;\n    var v= 0;\n    var f = function(){\n            if (done) {\n                return;\n            }\n            Roo.MessageBox.updateProgress(v/50, 'Loading..  Around ' + (50-v) + ' seconds to go');\n            v++;\n            f.defer(1000)\n       };\n     Roo.MessageBox.show({\n           title: 'Please wait...',\n           msg: 'Loading...',\n           width:240,\n           progress:true,\n           closable:true\n       });\n    \n\n    \n    ///el.mask(\"Loading - Should take around 45 seconds <br/> if it takes longer than 2 minutes, then something is broken<br/> If nothing displays try doing shift-reload or ctrl-reload\");\n    this.load({\n        url : baseURL + '/Xtuple/Reports/ConsolidatedAccounts',\n        method: 'GET',\n        params :  params,\n        timeout: 120,\n        callback: function() {\n            done = true;\n            Roo.MessageBox.hide();\n        }\n        \n    });\n    \n    f();\n    \n}\n",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo",
+                                                    "xtype": "Toolbar",
+                                                    "*prop": "toolbar",
+                                                    "items": [
+                                                        {
+                                                            "text": "Report Range :",
+                                                            "xtype": "TextItem",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n    _this.reportDateFrom = _self;\n}",
+                                                                "select": "function (combo, date)\n{\n  //_this.grid.footer.onClick('first');\n}"
+                                                            },
+                                                            "format": "d/M/Y",
+                                                            "useIso": 1,
+                                                            "width": 120,
+                                                            "xtype": "DateField",
+                                                            "|value": "(function() { \n    return Date.parseDate( \n        '' + (new Date()).format('Y-m') + '-01'\n        , 'Y-m-d'   ); })()",
+                                                            "|xns": "Roo.form"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n  _this.reportInterval = _self;\n}",
+                                                                "select": "function (combo, record, index)\n{\n   // Roo.log('select');\n   // _this.grid.footer.onClick('first');\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "displayField": "fname",
+                                                            "editable": false,
+                                                            "fieldLabel": "Status",
+                                                            "hiddenName": "cm_status",
+                                                            "listWidth": 400,
+                                                            "mode": "local",
+                                                            "name": "cm_status_name",
+                                                            "triggerAction": "all",
+                                                            "value": "Y",
+                                                            "valueField": "ftype",
+                                                            "width": 200,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "xtype": "SimpleStore",
+                                                                    "|data": "[ \n    [ 'Y', \"Since Start of Financial Year\"],\n    [ 'YY' , \"Since Start of Financial Year with same range Previous Year\"],            \n    [ 'M' , \"Single Month\"],\n    [ 'MM' , \"Single Month with Previous Month\"],    \n    [ 'MY' , \"Single Month with Previous Year\"],\n    [ 'MF' , \"This Months of Financia Year\"],\n    [ 'ML' , \"Last 12 Months\"]\n]\n",
+                                                                    "|fields": "[  'ftype', 'fname']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "render": "function (_self)\n{\n  _this.reportCompany = _self;\n}"
+                                                            },
+                                                            "allowBlank": false,
+                                                            "displayField": "fname",
+                                                            "editable": false,
+                                                            "fieldLabel": "Status",
+                                                            "hiddenName": "report_company",
+                                                            "listWidth": 300,
+                                                            "mode": "local",
+                                                            "name": "report_company_name",
+                                                            "triggerAction": "all",
+                                                            "value": "hk",
+                                                            "valueField": "ftype",
+                                                            "width": 100,
+                                                            "xtype": "ComboBox",
+                                                            "|hidden": "(function() {\n\n    return baseURL.match(/hk\\.php$/) ? false : true;\n})()",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "store",
+                                                                    "xtype": "SimpleStore",
+                                                                    "|data": "[ \n    [ 'hk', \"Hong Kong\"],\n    [ 'sg' , \"Singapore\"],            \n    [ 'my' , \"Malaysia\"],\n    [ 'cn' , \"China\"],    \n    [ 'au' , \"Australia\"],\n    [ 'consolidated' , \"Consolidated\"]\n]\n",
+                                                                    "|fields": "[  'ftype', 'fname']",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n      _this.reportpanel.showReport(); \n}"
+                                                            },
+                                                            "text": "Refresh Report",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo.Toolbar",
+                                                            "xtype": "Fill"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "click": "function (_self, e)\n{\n      _this.reportpanel.showReport(false,'xls'); \n}"
+                                                            },
+                                                            "text": "Download XLS",
+                                                            "xtype": "Button",
+                                                            "|xns": "Roo.Toolbar"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "render": "function (_self)\n{\n    _this.tree = _self;\n}"
+                            },
+                            "fitToFrame": true,
+                            "region": "west",
+                            "xtype": "TreePanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "Toolbar",
+                                    "*prop": "toolbar"
+                                },
+                                {
+                                    "*prop": "tree",
+                                    "rootVisible": false,
+                                    "xtype": "TreePanel",
+                                    "|xns": "Roo.tree",
+                                    "items": [
+                                        {
+                                            "*prop": "root",
+                                            "id": "root",
+                                            "xtype": "TreeNode",
+                                            "|xns": "Roo.tree"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "selectionchange": "function (_self, node)\n{\n    var at = node.attributes.id;\n    if (at > 999) {\n         _this.dashpanel.layout.getRegion('center').showPanel(0);\n          Pman.Xtuple.DashboardRender.load();\n          return;\n         \n    }\n    _this.dashpanel.layout.getRegion('center').showPanel(1);\n    _this.reportpanel.showReport(node); \n   \n    \n}"
+                                            },
+                                            "*prop": "selModel",
+                                            "xtype": "DefaultSelectionModel",
+                                            "|xns": "Roo.tree"
+                                        },
+                                        {
+                                            "*prop": "loader",
+                                            "requestMethod": "GET",
+                                            "xtype": "TreeLoader",
+                                            "|baseParams": "{ _tree : 1, _dragon_only : 1 }",
+                                            "|dataUrl": "baseURL + '/Roo/Flhead'",
+                                            "|xns": "Roo.tree"
+                                        },
+                                        {
+                                            "|xns": "Roo.tree",
+                                            "xtype": "AsyncTreeNode",
+                                            "*prop": "root"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleDashboard.js b/Pman.Tab.XtupleDashboard.js
new file mode 100644 (file)
index 0000000..ee32c7a
--- /dev/null
@@ -0,0 +1,893 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleDashboard = new Roo.XComponent({
+    part     :  ["Xtuple","Dashboard"],
+    order    : '001-Pman.Tab.XtupleDashboard',
+    region   : 'center',
+    parent   : 'Pman',
+    name     : "Pman.Tab.XtupleDashboard",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            listeners : {
+                activate : function (_self)
+                {
+                    
+                    try {
+                       // Pman.Xtuple.DashboardRender.load();    
+                    } catch (e) {
+                        Roo.log(e);
+                    }
+                    
+                }
+            },
+            region : 'center',
+            title : "Management Dashboard",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'NestedLayoutPanel',
+                        xns: Roo,
+                        listeners : {
+                            render : function (_self)
+                            {
+                                _this.dashpanel = _self;
+                                
+                                
+                                (function() { 
+                                        this.layout.getRegion('center').showPanel(0);
+                                }).defer(100,this);
+                            }
+                        },
+                        region : 'center',
+                        layout : {
+                            xtype: 'BorderLayout',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'ContentPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        render : function (_self)
+                                        {
+                                            _this.viewPanel = _self;
+                                            
+                                          
+                                            //_this.paper = Raphael(_self.el.dom);
+                                            
+                                        
+                                         
+                                            
+                                            
+                                            
+                                        },
+                                        resize : function (_self, width, height)
+                                        {
+                                            
+                                           Roo.log("RESIZE");
+                                           /* _this.svg.attr("width", width)
+                                                .attr("height", height);
+                                                */
+                                           //      _this.paper.setSize(width, 400);
+                                            try {
+                                        Pman.Clipping.DashboardRender.resize(width,height);
+                                            } catch (e) {
+                                                Roo.log(e);
+                                            }
+                                        
+                                           
+                                            
+                                        },
+                                        activate : function (_self)
+                                        {
+                                            if (!_this.loadonce) {
+                                                _this.loadonce = true;
+                                            
+                                                (function () { Pman.Xtuple.DashboardRender.load(); }).defer(1000); 
+                                            }
+                                        }
+                                    },
+                                    autoScroll : true,
+                                    fitContainer : true,
+                                    fitToFrame : true,
+                                    region : 'center',
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'TextItem',
+                                                xns: Roo.Toolbar,
+                                                text : "Show : "
+                                            },
+                                            {
+                                                xtype: 'ComboBox',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.countryCombo= _self;
+                                                    }
+                                                },
+                                                allowBlank : true,
+                                                displayField : 'addr_country',
+                                                editable : false,
+                                                emptyText : " Country",
+                                                forceSelection : true,
+                                                listWidth : 400,
+                                                loadingText : "Searching...",
+                                                minChars : 2,
+                                                name : 'addr_country',
+                                                pageSize : 20,
+                                                qtip : "Select addr",
+                                                selectOnFocus : true,
+                                                tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_country}</b> </div>',
+                                                triggerAction : 'all',
+                                                typeAhead : true,
+                                                width : 100,
+                                                store : {
+                                                    xtype: 'Store',
+                                                    xns: Roo.data,
+                                                    listeners : {
+                                                        beforeload : function (_self, o){
+                                                            o.params = o.params || {};
+                                                            // set more here
+                                                            o.params._distinct = 'addr_country';
+                                                            o.params._columns = 'addr_country';    
+                                                            o.params['!addr_country'] = '';
+                                                        }
+                                                    },
+                                                    remoteSort : true,
+                                                    sortInfo : { direction : 'ASC', field: 'addr_country' },
+                                                    proxy : {
+                                                        xtype: 'HttpProxy',
+                                                        xns: Roo.data,
+                                                        method : 'GET',
+                                                        url : baseURL + '/Roo/addr.php'
+                                                    },
+                                                    reader : {
+                                                        xtype: 'JsonReader',
+                                                        xns: Roo.data,
+                                                        id : 'id',
+                                                        root : 'data',
+                                                        totalProperty : 'total',
+                                                        fields : [{"name":"id","type":"int"},{"name":"addr_line1","type":"string"}]
+                                                    }
+                                                }
+                                            },
+                                            {
+                                                xtype: 'ComboBox',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                      _this.viewType = _self;
+                                                       _this.dateRange = function() {
+                                                                    return {
+                                                                       date_from : _this.mfrom.getValue(),
+                                                                        date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.YEAR, 1).format('Y-m-d')
+                                                             
+                                                                    };
+                                                               
+                                                               };
+                                                    },
+                                                    select : function (combo, record, index)
+                                                    {
+                                                        Roo.log('select');
+                                                       // Pman.Clipping.DashboardRender.load();
+                                                        var n = new Date();
+                                                        var ys = n.format('Y' )+ '-05-01';
+                                                        n = Date.parseDate(ys, 'Y-n-d');
+                                                        
+                                                        var ftype = record ? record.data.ftype : this.getValue();
+                                                        
+                                                        switch(ftype) {
+                                                            case 'Y':
+                                                                //Roo.log(Date.parseDate(ys, 'Y-n-d'));
+                                                               _this.mfrom.setValue(Date.parseDate(ys, 'Y-n-d'));
+                                                               _this.mfrom.show();
+                                                               _this.mto.hide(); 
+                                                               _this.daypick.hide();
+                                                               
+                                                               _this.dateRange = function() {
+                                                                    return {
+                                                                       date_from : _this.mfrom.getValue(),
+                                                                        date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.YEAR, 1).format('Y-m-d')
+                                                             
+                                                                    };
+                                                               
+                                                               };
+                                                               
+                                                               
+                                                                break;
+                                                            case 'H':        
+                                                            // ?? latest half
+                                                                var m = (new Date()).format('n')*1  > 6 ? 6 : 0;
+                                                                Roo.log(m);
+                                                                Roo.log( n.add(Date.MONTH,m));
+                                                               _this.mfrom.setValue(n.add(Date.MONTH,m));           
+                                                               _this.mfrom.show();
+                                                               _this.mto.hide(); 
+                                                               _this.daypick.hide();
+                                                               _this.dateRange = function() {
+                                                                    return {
+                                                                        date_from : _this.mfrom.getValue(),
+                                                                        date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 6).format('Y-m-d')
+                                                                    };
+                                                               };
+                                                              break;
+                                                            case 'Q':                
+                                                            
+                                                                var m = Math.floor(((new Date()).format('n') *1 -1) / 4) * 4;
+                                                    
+                                                               _this.mfrom.setValue(n.add(Date.MONTH, m));           
+                                                               _this.mfrom.show();
+                                                               _this.mto.hide(); 
+                                                               _this.daypick.hide();
+                                                               _this.dateRange = function() {
+                                                                    return {
+                                                                        date_from : _this.mfrom.getValue(),
+                                                                        date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 3).format('Y-m-d')
+                                                                    };
+                                                                };   
+                                                                break;
+                                                    
+                                                            case 'M':        
+                                                                var m = (new Date()).format('n') *1  - 1 ;
+                                                               _this.mfrom.setValue(n.add(Date.MONTH, m ));
+                                                               _this.mfrom.show();
+                                                               _this.mto.hide(); 
+                                                               _this.daypick.hide();
+                                                                _this.dateRange = function() {
+                                                                    return {
+                                                                        date_from : _this.mfrom.getValue(),
+                                                                        date_to :Date.parseDate(_this.mfrom.getValue(), 'Y-n-d').add(Date.MONTH, 1).format('Y-m-d')
+                                                                    };
+                                                                };   
+                                                                break;        
+                                                            
+                                                    
+                                                            
+                                                            case 'R':
+                                                                // this month..
+                                                                var m = (new Date()).format('n') * 1;            
+                                                               _this.mfrom.setValue(n.add(Date.MONTH, m-1 )); 
+                                                               _this.mto.setValue(n.add(Date.MONTH,m )); 
+                                                            
+                                                            
+                                                            
+                                                                 _this.mfrom.show();
+                                                                _this.mto.show(); 
+                                                                _this.daypick.hide();
+                                                                 _this.dateRange = function() {
+                                                                    return {
+                                                                        date_from : _this.mfrom.getValue(),
+                                                                        date_to : _this.mto.getValue()
+                                                                    };
+                                                                };   
+                                                                
+                                                                
+                                                                break;
+                                                            /*
+                                                             case 'W': // today
+                                                                var d = (new Date()).format('w') * -1;
+                                                                _this.daypick.setValue( (new Date()).add(Date.DAY, d )); 
+                                                                 _this.mfrom.hide();
+                                                                _this.mto.hide(); 
+                                                                _this.daypick.show();
+                                                                break;
+                                                            
+                                                            
+                                                            case 'D': // today
+                                                                _this.daypick.setValue(new Date()); 
+                                                                 _this.mfrom.hide();
+                                                                _this.mto.hide(); 
+                                                                _this.daypick.show();
+                                                                break;
+                                                                */
+                                                            default:
+                                                                alerT("oops invalid ftype?");
+                                                                return;
+                                                        }
+                                                        
+                                                        
+                                                        
+                                                    }
+                                                },
+                                                allowBlank : false,
+                                                displayField : 'fname',
+                                                editable : false,
+                                                fieldLabel : 'Status',
+                                                hiddenName : 'cm_status',
+                                                listWidth : 200,
+                                                mode : 'local',
+                                                name : 'cm_status_name',
+                                                triggerAction : 'all',
+                                                value : "R",
+                                                valueField : 'ftype',
+                                                width : 150,
+                                                store : {
+                                                    xtype: 'SimpleStore',
+                                                    xns: Roo.data,
+                                                    data : [ 
+                                                        [ 'Y', "Show Year From"],
+                                                        [ 'H' , "6 Months From"],
+                                                        [ 'Q', "3 Months From"] ,
+                                                        [ 'M', "Single Month"],
+                                                       // [ 'W', "Single Week Starting"],
+                                                        [ 'R', "Between these Dates"] //,
+                                                      //  [ 'D', "Single Day"]
+                                                        
+                                                    ],
+                                                    fields : [  'ftype', 'fname']
+                                                }
+                                            },
+                                            {
+                                                xtype: 'DateField',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.mfrom=  _self;
+                                                    }
+                                                },
+                                                format : 'd/M/Y',
+                                                useIso : true,
+                                                value : (function() {
+                                                    var n = new Date();
+                                                    // previous apr.
+                                                    var y = n.format('Y');
+                                                    if (n.format('m') < 5) { 
+                                                        y--;
+                                                    }
+                                                    
+                                                    return Date.parseDate(y  + '-05-01', 'Y-m-d');
+                                                })()
+                                            },
+                                            {
+                                                xtype: 'DateField',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.mto=  _self;
+                                                        //this.hide();
+                                                    }
+                                                },
+                                                format : 'd/M/Y',
+                                                useIso : true,
+                                                value : (function() {
+                                                    var n = (new Date()).add(Date.YEAR, 1);
+                                                    
+                                                    var n = new Date();
+                                                    // previous apr.
+                                                    var y = n.format('Y');
+                                                    if (n.format('m') >= 5) { 
+                                                        y++;
+                                                    }
+                                                    
+                                                    return Date.parseDate(y  + '-05-01', 'Y-m-d');
+                                                    
+                                                    
+                                                
+                                                })()
+                                            },
+                                            {
+                                                xtype: 'DateField',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.daypick = _self;
+                                                        this.hide();
+                                                    }
+                                                },
+                                                format : 'd/M/Y',
+                                                useIso : true,
+                                                value : (function() {
+                                                //    var n = new Date();
+                                                    return new Date();
+                                                })()
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                        Pman.Xtuple.DashboardRender.load();
+                                                    }
+                                                },
+                                                text : "Run Report"
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                text : "Other Reports",
+                                                menu : {
+                                                    xtype: 'Menu',
+                                                    xns: Roo.menu,
+                                                    items : [
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/SalesByCustomer',
+                                                                        params : _this.dateRange()
+                                                                    
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Sales By Customer"
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/SalesByCountry',
+                                                                        params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Sales By Country"
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/SalesByProduct',
+                                                                        params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Sales By Product"
+                                                        },
+                                                        {
+                                                            xtype: 'Separator',
+                                                            xns: Roo.menu
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/PurchasesByVendor',
+                                                                        params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Purchases By Vendor"
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/PurchasesByProduct',
+                                                                        params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                }
+                                                            },
+                                                            text : "Purchases By Product"
+                                                        },
+                                                        {
+                                                            xtype: 'Separator',
+                                                            xns: Roo.menu
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/StockAtLocation',
+                                                                         params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                    Roo.MessageBox.alert("Downloading", 
+                                                                        "The file will start downloading shortly - it may take around 1-2 minutes to calculate");
+                                                                    
+                                                                }
+                                                            },
+                                                            text : "Historical Stock Levels (EO HKFY)"
+                                                        },
+                                                        {
+                                                            xtype: 'Separator',
+                                                            xns: Roo.menu
+                                                        },
+                                                        {
+                                                            xtype: 'Item',
+                                                            xns: Roo.menu,
+                                                            listeners : {
+                                                                click : function (_self, e)
+                                                                {
+                                                                    new Pman.Download({
+                                                                        url :baseURL + '/Xtuple/Reports/SGTax',
+                                                                         params :  _this.dateRange()
+                                                                    
+                                                                    });
+                                                                    Roo.MessageBox.alert("Downloading", 
+                                                                        "The file will start downloading shortly - it may take around 1-2 minutes to calculate");
+                                                                    
+                                                                }
+                                                            },
+                                                            text : "SG Tax report"
+                                                        }
+                                                    ]
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Spacer',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'TextItem',
+                                                xns: Roo.Toolbar,
+                                                text : "Theme : "
+                                            },
+                                            {
+                                                xtype: 'ComboBox',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    select : function (combo, record, index)
+                                                    {
+                                                        Pman.Xtuple.DashboardRender.load();
+                                                    },
+                                                    render : function (_self)
+                                                    {
+                                                        _this.themeCombo = this;
+                                                    }
+                                                },
+                                                allowBlank : false,
+                                                displayField : 'name',
+                                                editable : false,
+                                                hiddenName : 'colortheme',
+                                                listWidth : 300,
+                                                name : 'colorTheme_title',
+                                                qtip : "Select a Color Theme",
+                                                selectOnFocus : true,
+                                                triggerAction : 'all',
+                                                typeAhead : false,
+                                                valueField : 'themeData',
+                                                value : (function() {
+                                                     return Pman.Xtuple ? Pman.Xtuple.DashboardRender.colorthemes()[12][1] : ''; 
+                                                })(),
+                                                store : {
+                                                    xtype: 'SimpleStore',
+                                                    xns: Roo.data,
+                                                    data : (function() {
+                                                        return (typeof Pman.Xtuple != 'undefined') ? Pman.Xtuple.DashboardRender.colorthemes() : [];
+                                                        
+                                                    })(),
+                                                    fields : ['name','themeData']
+                                                }
+                                            }
+                                        ]
+                                    }
+                                },
+                                {
+                                    xtype: 'ContentPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        render : function (_self)
+                                        {
+                                            _this.reportpanel = _self;
+                                        }
+                                    },
+                                    autoScroll : true,
+                                    fitToFrame : true,
+                                    region : 'center',
+                                    showReport : function(node, isxls) {
+                                        if (node) {
+                                            _this.selectedNode = node;
+                                        }
+                                        var rc = _this.reportCompany.getValue();
+                                        var params =  {
+                                            flhead_name : _this.selectedNode.attributes.text,
+                                            ts : Math.random(),
+                                            period : _this.reportDateFrom.getValue(),
+                                            interval:   _this.reportInterval.getValue(),
+                                            company : (_this.reportCompany.hidden) ? '' : rc == 'consolidated' ? '' : rc,
+                                            singleCountry :  rc == 'consolidated' ? 0 : 1
+                                        };
+                                        
+                                        if (isxls) {
+                                            params._xls = 1;
+                                            new Pman.Download({
+                                                url : baseURL + '/Xtuple/Reports/ConsolidatedAccounts',
+                                                method: 'GET',
+                                                timeout: 120000,
+                                                params :  params
+                                            });
+                                            Roo.MessageBox.alert("Notice", "Report is downloading now for the combined report this will take about 50s");
+                                            return;
+                                        }
+                                        var el = this.region.el;
+                                    
+                                        var done = false;
+                                        var v= 0;
+                                        var f = function(){
+                                                if (done) {
+                                                    return;
+                                                }
+                                                Roo.MessageBox.updateProgress(v/50, 'Loading..  Around ' + (50-v) + ' seconds to go');
+                                                v++;
+                                                f.defer(1000)
+                                           };
+                                         Roo.MessageBox.show({
+                                               title: 'Please wait...',
+                                               msg: 'Loading...',
+                                               width:240,
+                                               progress:true,
+                                               closable:true
+                                           });
+                                        
+                                    
+                                        
+                                        ///el.mask("Loading - Should take around 45 seconds <br/> if it takes longer than 2 minutes, then something is broken<br/> If nothing displays try doing shift-reload or ctrl-reload");
+                                        this.load({
+                                            url : baseURL + '/Xtuple/Reports/ConsolidatedAccounts',
+                                            method: 'GET',
+                                            params :  params,
+                                            timeout: 120,
+                                            callback: function() {
+                                                done = true;
+                                                Roo.MessageBox.hide();
+                                            }
+                                            
+                                        });
+                                        
+                                        f();
+                                        
+                                    },
+                                    toolbar : {
+                                        xtype: 'Toolbar',
+                                        xns: Roo,
+                                        items : [
+                                            {
+                                                xtype: 'TextItem',
+                                                xns: Roo.Toolbar,
+                                                text : "Report Range :"
+                                            },
+                                            {
+                                                xtype: 'DateField',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                        _this.reportDateFrom = _self;
+                                                    },
+                                                    select : function (combo, date)
+                                                    {
+                                                      //_this.grid.footer.onClick('first');
+                                                    }
+                                                },
+                                                format : 'd/M/Y',
+                                                useIso : 1,
+                                                width : 120,
+                                                value : (function() { 
+                                                    return Date.parseDate( 
+                                                        '' + (new Date()).format('Y-m') + '-01'
+                                                        , 'Y-m-d'   ); })()
+                                            },
+                                            {
+                                                xtype: 'ComboBox',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                      _this.reportInterval = _self;
+                                                    },
+                                                    select : function (combo, record, index)
+                                                    {
+                                                       // Roo.log('select');
+                                                       // _this.grid.footer.onClick('first');
+                                                    }
+                                                },
+                                                allowBlank : false,
+                                                displayField : 'fname',
+                                                editable : false,
+                                                fieldLabel : 'Status',
+                                                hiddenName : 'cm_status',
+                                                listWidth : 400,
+                                                mode : 'local',
+                                                name : 'cm_status_name',
+                                                triggerAction : 'all',
+                                                value : "Y",
+                                                valueField : 'ftype',
+                                                width : 200,
+                                                store : {
+                                                    xtype: 'SimpleStore',
+                                                    xns: Roo.data,
+                                                    data : [ 
+                                                        [ 'Y', "Since Start of Financial Year"],
+                                                        [ 'YY' , "Since Start of Financial Year with same range Previous Year"],            
+                                                        [ 'M' , "Single Month"],
+                                                        [ 'MM' , "Single Month with Previous Month"],    
+                                                        [ 'MY' , "Single Month with Previous Year"],
+                                                        [ 'MF' , "This Months of Financia Year"],
+                                                        [ 'ML' , "Last 12 Months"]
+                                                    ],
+                                                    fields : [  'ftype', 'fname']
+                                                }
+                                            },
+                                            {
+                                                xtype: 'ComboBox',
+                                                xns: Roo.form,
+                                                listeners : {
+                                                    render : function (_self)
+                                                    {
+                                                      _this.reportCompany = _self;
+                                                    }
+                                                },
+                                                allowBlank : false,
+                                                displayField : 'fname',
+                                                editable : false,
+                                                fieldLabel : 'Status',
+                                                hiddenName : 'report_company',
+                                                listWidth : 300,
+                                                mode : 'local',
+                                                name : 'report_company_name',
+                                                triggerAction : 'all',
+                                                value : "hk",
+                                                valueField : 'ftype',
+                                                width : 100,
+                                                hidden : (function() {
+                                                
+                                                    return baseURL.match(/hk\.php$/) ? false : true;
+                                                })(),
+                                                store : {
+                                                    xtype: 'SimpleStore',
+                                                    xns: Roo.data,
+                                                    data : [ 
+                                                        [ 'hk', "Hong Kong"],
+                                                        [ 'sg' , "Singapore"],            
+                                                        [ 'my' , "Malaysia"],
+                                                        [ 'cn' , "China"],    
+                                                        [ 'au' , "Australia"],
+                                                        [ 'consolidated' , "Consolidated"]
+                                                    ],
+                                                    fields : [  'ftype', 'fname']
+                                                }
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                          _this.reportpanel.showReport(); 
+                                                    }
+                                                },
+                                                text : "Refresh Report"
+                                            },
+                                            {
+                                                xtype: 'Fill',
+                                                xns: Roo.Toolbar
+                                            },
+                                            {
+                                                xtype: 'Button',
+                                                xns: Roo.Toolbar,
+                                                listeners : {
+                                                    click : function (_self, e)
+                                                    {
+                                                          _this.reportpanel.showReport(false,'xls'); 
+                                                    }
+                                                },
+                                                text : "Download XLS"
+                                            }
+                                        ]
+                                    }
+                                }
+                            ],
+                            center : {
+                                xtype: 'LayoutRegion',
+                                xns: Roo,
+                                hideTabs : true
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'TreePanel',
+                        xns: Roo,
+                        listeners : {
+                            render : function (_self)
+                            {
+                                _this.tree = _self;
+                            }
+                        },
+                        fitToFrame : true,
+                        region : 'west',
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo
+                        },
+                        tree : {
+                            xtype: 'TreePanel',
+                            xns: Roo.tree,
+                            rootVisible : false,
+                            root : {
+                                xtype: 'AsyncTreeNode',
+                                xns: Roo.tree
+                            },
+                            selModel : {
+                                xtype: 'DefaultSelectionModel',
+                                xns: Roo.tree,
+                                listeners : {
+                                    selectionchange : function (_self, node)
+                                    {
+                                        var at = node.attributes.id;
+                                        if (at > 999) {
+                                             _this.dashpanel.layout.getRegion('center').showPanel(0);
+                                              Pman.Xtuple.DashboardRender.load();
+                                              return;
+                                             
+                                        }
+                                        _this.dashpanel.layout.getRegion('center').showPanel(1);
+                                        _this.reportpanel.showReport(node); 
+                                       
+                                        
+                                    }
+                                }
+                            },
+                            loader : {
+                                xtype: 'TreeLoader',
+                                xns: Roo.tree,
+                                requestMethod : 'GET',
+                                baseParams : { _tree : 1, _dragon_only : 1 },
+                                dataUrl : baseURL + '/Roo/Flhead'
+                            },
+                            root : {
+                                xtype: 'AsyncTreeNode',
+                                xns: Roo.tree
+                            }
+                        }
+                    }
+                ],
+                west : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    hidden : false,
+                    split : true,
+                    width : 200
+                },
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleExpenses.bjs b/Pman.Tab.XtupleExpenses.bjs
new file mode 100644 (file)
index 0000000..25deaa8
--- /dev/null
@@ -0,0 +1,201 @@
+{
+    "id": "roo-file-320",
+    "name": "Pman.Tab.XtupleExpenses",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "Pman.Tab.XtupleExpenses",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleExpenses.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "expense",
+            "title": "Expenses",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    _this.dialog = Pman.Dialog.XtupleExpenses;\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "expense_memo",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, options)\n{\n    options.params._applyPerms = 1;\n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'expense_id', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/expense.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'expense_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expense_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expense_emp_id',\n        'type': 'int'\n    },\n    {\n        'name': 'expense_number',\n        'type': 'string'\n    },\n    {\n        'name': 'expense_trandate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'expense_created',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'expense_modified',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'expense_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'expense_memo',\n        'type': 'string'\n    },\n    {\n        'name': 'expense_status',\n        'type': 'string'\n    },\n    {\n        'name': 'expense_advance',\n        'type': 'float'\n    },\n    {\n        'name': 'expense_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'expense_tax',\n        'type': 'float'\n    },\n    {\n        'name': 'expense_total',\n        'type': 'float'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying expense{0} - {1} of {2}",
+                            "emptyMsg": "No expense found",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( { \n        expense_id : 0,\n        expense_emp_id_emp_name : Pman.Login.authUser.name\n     } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    var rec =  _this.grid.selModel.getSelected();\n    if (!rec) {\n        Roo.MessageBox.alert(\"Error\", \"Select a line to delete\");\n        return;\n    }\n    if (['Draft', ''].indexOf(rec.data.expense_status) < 0) {\n        Roo.MessageBox.alert(\"Error\", \"You can only delete draft entries\");\n        return;\n    }\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to delete that?\", function(r) {\n        if (r!='yes') {\n            return;\n        }\n        \n    \n        new Pman.Request({\n            mask : 'Deleting',\n            url : baseURL + '/Roo/expense',\n            method : 'POST',\n            params : {\n                _delete : rec.data.expense_id\n            },\n            success : function()\n            {\n                _this.grid.ds.remove(rec);            \n            }\n        });\n   });\n   \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Delete",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_emp_id_emp_name",
+                            "header": "Employee",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_number",
+                            "header": "no#",
+                            "width": 70,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_trandate",
+                            "header": "Post Date",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_duedate",
+                            "header": "Due Date",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_memo",
+                            "header": "Desc",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "expense_status",
+                            "header": "Status",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "expense_advance",
+                            "header": "Advance",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "expense_amount",
+                            "header": "Amount",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "expense_tax",
+                            "header": "Tax",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "expense_total",
+                            "header": "Total",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', (1*v).toFixed(2)); }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "800"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleExpenses.js b/Pman.Tab.XtupleExpenses.js
new file mode 100644 (file)
index 0000000..cc1982b
--- /dev/null
@@ -0,0 +1,311 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleExpenses = new Roo.XComponent({
+    part     :  ["Xtuple","Expenses"],
+    order    : '800-Pman.Tab.XtupleExpenses',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "Pman.Tab.XtupleExpenses",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'expense',
+            title : "Expenses",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        _this.dialog = Pman.Dialog.XtupleExpenses;
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        if (!_this.dialog) return;
+                        _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                            _this.grid.footer.onClick('first');
+                        }); 
+                    }
+                },
+                autoExpandColumn : 'expense_memo',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, options)
+                        {
+                            options.params._applyPerms = 1;
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'expense_id', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/expense.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'expense_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'expense_accnt_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'expense_emp_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'expense_number',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'expense_trandate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'expense_created',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'expense_modified',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'expense_duedate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'expense_memo',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'expense_status',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'expense_advance',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'expense_amount',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'expense_tax',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'expense_total',
+                                'type': 'float'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying expense{0} - {1} of {2}",
+                    emptyMsg : "No expense found"
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( { 
+                                        expense_id : 0,
+                                        expense_emp_id_emp_name : Pman.Login.authUser.name
+                                     } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    var rec =  _this.grid.selModel.getSelected();
+                                    if (!rec) {
+                                        Roo.MessageBox.alert("Error", "Select a line to delete");
+                                        return;
+                                    }
+                                    if (['Draft', ''].indexOf(rec.data.expense_status) < 0) {
+                                        Roo.MessageBox.alert("Error", "You can only delete draft entries");
+                                        return;
+                                    }
+                                    
+                                    Roo.MessageBox.confirm("Confirm", "Are you sure you want to delete that?", function(r) {
+                                        if (r!='yes') {
+                                            return;
+                                        }
+                                        
+                                    
+                                        new Pman.Request({
+                                            mask : 'Deleting',
+                                            url : baseURL + '/Roo/expense',
+                                            method : 'POST',
+                                            params : {
+                                                _delete : rec.data.expense_id
+                                            },
+                                            success : function()
+                                            {
+                                                _this.grid.ds.remove(rec);            
+                                            }
+                                        });
+                                   });
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Delete",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_emp_id_emp_name',
+                        header : 'Employee',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_number',
+                        header : 'no#',
+                        width : 70,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_trandate',
+                        header : 'Post Date',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_duedate',
+                        header : 'Due Date',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_memo',
+                        header : 'Desc',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'expense_status',
+                        header : 'Status',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'expense_advance',
+                        header : 'Advance',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'expense_amount',
+                        header : 'Amount',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'expense_tax',
+                        header : 'Tax',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'expense_total',
+                        header : 'Total',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', (1*v).toFixed(2)); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleGeneralLedger.bjs b/Pman.Tab.XtupleGeneralLedger.bjs
new file mode 100644 (file)
index 0000000..dce2335
--- /dev/null
@@ -0,0 +1,727 @@
+{
+    "id": "roo-file-43",
+    "name": "Pman.Tab.XtupleGeneralLedger",
+    "parent": "Pman.Tab.XtupleAccountsTab",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleGeneralLedger.bjs",
+    "items": [
+        {
+            "background": true,
+            "fitContainer": true,
+            "fitToFrame": true,
+            "region": "center",
+            "title": "General Ledger",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "center",
+                            "tabPosition": "top",
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "west",
+                            "split": true,
+                            "tabPosition": "top",
+                            "width": 600,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.wpanel = this;\n    if (_this.wgrid) {\n        _this.wgrid.ds.load({});\n    }\n}"
+                            },
+                            "background": false,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "west",
+                            "tableName": "accnt",
+                            "title": "Account",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.wgrid = this; \n    _this.active = 1;\n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.wpanel.active) {\n       this.ds.load({});\n    }\n}",
+                                        "rowclick": "function (_self, rowIndex, e)\n{\n    var s = _this.wgrid.ds.getAt(rowIndex);\n    \n    if(s.data.accnt_id * 1 < 1){\n        return;\n    }\n    \n    _this.grid.footer.onClick('first');\n    \n    \n}",
+                                        "rowdblclick": "function (_self, rowIndex, e)\n{\n    var ret = _this.wgrid.ds.getAt(rowIndex).data;\n    if(ret.accnt_id * 1 < 1){\n        Roo.MessageBox.alert(\"Error\", \"Error occur on getting the account id!\");\n        return;\n    }\n    Pman.Dialog.XtupleGLAccountNameEdit.show( {accnt_id : ret.accnt_id}, function() {\n        _this.wgrid.ds.load({});\n    }); \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "accnt_descrip",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "specialkey": "function (_self, e)\n{\n  _this.wgrid.ds.load({});\n}",
+                                                        "render": "function (_self)\n{\n    _this.searchBox = _self;\n}"
+                                                    },
+                                                    "width": 100,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.wgrid.ds.load({});\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\r\n    _this.wgrid.ds.load({});\r\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\r\n{\r\n    _this.dateSel = _self;\r\n   _self.setValue(  new Date() );\r\n}",
+                                                        "select": "function (combo, date)\n{\n    _this.wgrid.ds.load({});\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "format": "d/M/Y",
+                                                    "width": 100,
+                                                    "xtype": "DateField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.orderBox = _self;\n}"
+                                                    },
+                                                    "width": 80,
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "text": "Download / Upload",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    _this.active = (_this.active) ? 0 : 1;\n    this.setText(_this.active ? \"Show Inactive\" : \"Hide Inactive\");\n    _this.wgrid.ds.load({});\n}"
+                                                                    },
+                                                                    "text": "Show Inactive",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n    new Pman.download({\n        url : baseURL + '/Roo/accnt.php',\n        method : 'GET',\n        params : {\n            'start' : 0,\n            'limit' : 9999,\n            _with_xt_balances : 1,\n            'csvTitles[0]' : 'Name', 'csvCols[0]' : 'accnt_name',\n            'csvTitles[1]' : 'Description', 'csvCols[1]' : 'accnt_descrip',\n            'csvTitles[2]' : 'Alternative Code', 'csvCols[2]' : 'accnt_code_alt',\n            'csvTitles[3]' : 'Alternative Description', 'csvCols[3]' : 'accnt_code_descrip',\n            'csvTitles[4]' : 'ADJUST', 'csvCols[4]' : 'balance_base'\n        }\n        \n    });\n}"
+                                                                    },
+                                                                    "text": "Download Balances",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.XtupleUploadBalances.show( {} , function(res) {\n        Pman.Dialog.Image.show({\n            _url : baseURL + '/Xtuple/Import/JournalEntry?' + Roo.urlEncode(res)\n        }, function(data) {\n             _this.wgrid.ds.load({});\n        });\n   }); \n}"
+                                                                    },
+                                                                    "text": "Upload JE adjustment",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n  new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 60000,\n        newWindow : true,\n        params : {\n            _group : 'apopen',\n            _name : 'bydate',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });;\n    Roo.MessageBox.alert(\"Notice\", \"This may take some time to calculate\");\n}"
+                                                                    },
+                                                                    "text": "Download AP - Day by Day Comparison",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n  new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 90000,\n        params : {\n            _group : 'apopen',\n            _name : 'bydatesummary',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });;\n    Roo.MessageBox.alert(\"Notice\", \"This may take some time to calculate\");\n}"
+                                                                    },
+                                                                    "text": "Download AP open vs GL - summary of bad days",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n  new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 90000,\n        params : {\n             'startDate:text' : _this.dateSel.getValue().format('Y-m-d'),\n            'endDate:text' :  _this.dateSel.getValue().add(Date.DAY,1).format('Y-m-d'),\n        \n            _group : 'apopen',\n            _name : 'all',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });;\n    Roo.MessageBox.alert(\"Notice\", \"This may take some time to calculate\");\n}"
+                                                                    },
+                                                                    "text": "Download AP - Transactions on a single day",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n  new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 90000,\n        params : {\n             'relDate:text' : _this.dateSel.getValue().format('Y-m-d'),\n            'useDocDate:text' :  'FALSE',\n        \n            _group : 'apAging',\n            _name : 'bydate',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });;\n    Roo.MessageBox.alert(\"Notice\", \"This may take some time to calculate\");\n}\n "
+                                                                    },
+                                                                    "text": "Download AP Aging at this date",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n  new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 90000,\n        params : {\n             \n            _group : 'apopen',\n            _name : 'history',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });\n    Roo.MessageBox.alert(\"Notice\", \"This may take some time to calculate\");\n}\n "
+                                                                    },
+                                                                    "text": "Download AP Aging History",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'aropen',\n            _name : 'all',\n            'startDate:text' : _this.dateSel.getValue().format('Y-m-d'),\n            'endDate:text' :  _this.dateSel.getValue().add(Date.DAY,1).format('Y-m-d'),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999        \n            \n        }\n    });;\n}"
+                                                                    },
+                                                                    "text": "Download AR - Transactions on a day",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'aropen',\n            _name : 'bydate',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });;\n}"
+                                                                    },
+                                                                    "text": "Download AR - Day by Day Comparison",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "text": "Gltrans vs Stock (COHEAD)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'bydate',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Gltrans vs Stock By Date",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var dt = _this.dateSel.getValue();\n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'gltrans',\n            '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Gltrans",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var dt = _this.dateSel.getValue();\n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'stock',\n            '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Stock",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "text": "Gltrans vs Stock (PO)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        timeout: 600000,\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'byorder',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Gltrans vs Stock By PO",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var ord = _this.orderBox.getValue();\n    \n    if(!ord.length){\n        Roo.MessageBox.alert('Error','Please enter a PO number');\n        return;\n    }\n    \n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'byordergltrans',\n            'docnumber:text' : ord,\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999       \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Gltrans",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var ord = _this.orderBox.getValue();\n    \n    if(!ord.length){\n        Roo.MessageBox.alert('Error','Please enter a PO number');\n        return;\n    }\n    \n    \n     new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans_stock',\n            _name : 'byorderstock',\n            'docnumber:text' : ord,\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999      \n        }\n    });\n}"
+                                                                                    },
+                                                                                    "text": "Download Stock",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "text": "Kingdee",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL+'/Xtuple/Kingdee/Currency',\n        method : 'GET',\n        timeout: 600000\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "Currency",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL+'/Xtuple/Kingdee/Rate',\n        method : 'GET',\n        timeout: 600000\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "Exchange Rate",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    \n     new Pman.Download({\n        url : baseURL+'/Xtuple/Kingdee/Account',\n        method : 'GET',\n        timeout: 600000\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "Accounts",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        url : baseURL+'/Xtuple/Kingdee/VoucherGroup',\n        method : 'GET',\n        timeout: 600000\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "Voucher Category",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    //var dt = _this.dateSel.getValue();\n    new Pman.Download({\n        url : baseURL+'/Xtuple/Kingdee/Voucher',\n        method : 'GET',\n        timeout: 600000\n        //params : {\n        //    _as_of : (typeof(dt) == 'string') ? dt : dt.format('Y-m-d')\n        //}\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly - If you wanna import again, please delete all the exist!\");\n}"
+                                                                                    },
+                                                                                    "text": "Transactions",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    options.params = options.params || {};\n    \n    options.params.limit = 9999;\n    \n    options.params._general_ledger = 1;\n    \n    options.params['search[name]'] = _this.searchBox.getValue();\n    \n    if (_this.active) {\r\n        options.params.accnt_active = 1;\r\n    }\n    \n    options.params._with_balances = 1;\n    \r    var dt = _this.dateSel.getValue();\r\n    options.params._as_of = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');\n    \n\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'accnt_name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "loadexception": "function (This, o, arg, e)\n{\n\n}"
+                                                    },
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/accnt.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "accnt_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'accnt_name',\n        'type': 'string'\n    },\n    {\n        'name': 'accnt_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'accnt_type',\n        'type': 'string'\n    },\n    {\n        'name': 'accnt_subaccnttype_code',\n        'type': 'string'\n    },\n    {\n        'name': 'accnt_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'accnt_curr_id_curr_id',\n        'type': 'int'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "accnt_name",
+                                            "header": "Name",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "accnt_code_alt",
+                                            "header": "Alternative Code",
+                                            "hidden": true,
+                                            "sortable": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "accnt_descrip_alt",
+                                            "header": "Alternative Description",
+                                            "hidden": true,
+                                            "sortable": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "accnt_type",
+                                            "header": "Type",
+                                            "sortable": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n     return String.format('{0}-{1}', v,r.data.accnt_subaccnttype_code); \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "accnt_descrip",
+                                            "header": "Description",
+                                            "sortable": true,
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{ \n    if(r.data.accnt_descrip_alt){\n        return String.format('{0} ({1})', v, r.data.accnt_descrip_alt);     \n    }\n    \n    return String.format('{0}', v); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "accnt_curr_id_curr_name",
+                                            "header": "Currency",
+                                            "sortable": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    var base = baseURL.match(/sg\\.php$/) ? 'SGD' : 'HKD';\n    if (v != base) {\n        return String.format('<span style=\"color:green\">{0}</span>', v);     \n    }\n\n    return String.format('{0}', v); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "balance",
+                                            "header": "Balance",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \r\n   return String.format('<span style=\"color:blue;text-decoration:underline;\">{0}</span>',\r\n            Roo.util.Format.usMoney(v) ); \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n /*   if (_this.grid) {\n        _this.grid.ds.load({});\n    } */\n}"
+                            },
+                            "background": false,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "gltrans",
+                            "title": "Transactions",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n   /* if (_this.panel.active) {\n       this.ds.load({});\n    } */\n}",
+                                        "afteredit": "function (e)\n{   \n    var r = _this.grid.ds.getAt(e.row);\n    \n    if(e.value == e.originalValue || !r){\n        return;\n    }\n\n    new Pman.Request({\n        url : baseURL + '/Roo/Gltrans.php',\n        method :'POST',\n        params : {\n            gltrans_id : r.data.gltrans_id,\n            gltrans_notes : e.value,\n            _update_notes : 1\n            \n        },\n        success : function() {\n           \n            _this.grid.footer.onClick('refresh');\n            \n        }\n    });\n    \n}",
+                                        "rowclass": "function (gridview, rowcfg)\n{\n  rowcfg.rowClass = 'dragon-gl-fixedheight';\n}",
+                                        "celldblclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var cm = this.colModel.config[columnIndex].dataIndex;\n    var r = this.ds.getAt(rowIndex);\n    if (cm != 'gltrans_date') {\n        return;\n    }\n    new Pman.Download({\n        url : baseURL+ '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans',\n            _name : 'sequence',\n            'gltrans_sequence:number' : r.data.gltrans_sequence,\n            limit : 9999,\n        }\n    });\n    \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "gltrans_notes",
+                                    "clicksToEdit": 2,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "specialkey": "function (_self, e)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                                        "render": "function (_self)\n{\n    _this.gltransBox = _self;\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.gltransBox.setValue('');\r\n    _this.grid.footer.onClick('first');\r\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Download",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!s){\n        Roo.MessageBox.alert(\"Error\", \"Please select a account\"); \n        return false;\n    }\n    \n    var dt = _this.dateSel.getValue();\n    \n    if(!dt){\n        Roo.MessageBox.alert(\"Error\", \"Please select a date on the right\"); \n        return false;\n    }  \n    \n    var g = _this.gltransBox.getValue();\n    \n    var params = {\n        '_group' : 'account',\n        '_name' : 'summary',\n        'limit' : 99999,\n        'accnt_id:number' : s.data.accnt_id,\n        'endDate:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n    \n    if(g.length){\n        params['search:text'] = g;\n    }\n    \n    new Pman.Download({\n      url : baseURL + '/Roo/Metasql',\n      params :   params,\n      method : 'GET'\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"All Transactions Report for \" + s.data.accnt_descrip + \" will download shortly\");\n}"
+                                                                    },
+                                                                    "text": "Download All Transactions",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!s){\n        Roo.MessageBox.alert(\"Error\", \"Please select a account\"); \n        return false;\n    }\n    \n    var dt = _this.dateSel.getValue();\n    \n    if(!dt){\n        Roo.MessageBox.alert(\"Error\", \"Please select a date on the right\"); \n        return false;\n    }  \n    \n    new Pman.Download({\n        url : baseURL + '/Roo/Gltrans.php',\n        method :'GET',\n        params : {\n            gltrans_accnt_id : s.data.accnt_id,\n            _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            _download : 1\n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Financial Year Report for \" + s.data.accnt_descrip + \" will download shortly\");\n}"
+                                                                    },
+                                                                    "text": "Download All Transactions (Selected Financial Year)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{   \n    var dt = _this.dateSel.getValue();\n    \n    if(!dt){\n        Roo.MessageBox.alert(\"Error\", \"Please select a date on the right\"); \n        return false;\n    }   \n       \n    new Pman.Download({\n        url : baseURL + '/Roo/Gltrans.php',\n        method :'GET',\n        timeout : 900000,\n        params : {\n            _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            _download : 1\n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Financial Year Report for all accounts will download shortly! it might take several minutes\");\n}"
+                                                                    },
+                                                                    "text": "Download All Transactions  / All Accounts (Selected Financial Year)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    options.params = options.params || {};\n    \n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!s){\n        return;\n    }\n    \n    var dt = _this.dateSel.getValue();\n    var g = _this.gltransBox.getValue();\n    \n    var params = {\n        _group : 'account',\n        _name : 'summary',\n        'accnt_id:number' : s.data.accnt_id,\n        'endDate:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d')\n    };\n    \n    if(g.length){\n        params['search:text'] = g;\n    }\n    \n    Roo.apply(options.params,params);\n    \n    var cm = _this.grid.getColumnModel();\n    var hide = (g.length) ? true : false;\n    \n    cm.setHidden(cm.getIndexByDataIndex('gltrans_balance'), hide);\n    \n    \n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "timeout": 600000,
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Metasql.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "gltrans_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'gltrans_id',\n        'type': 'int'\n    },\n    {\n        'name': 'gltrans_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'gltrans_source',\n        'type': 'string'\n    },\n    {\n        'name': 'gltrans_amount',\n        'type': 'int'\n    },\n    {\n        'name': 'gltrans_notes',\n        'type': 'string'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "pageSize": 100,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "text": "Double Click To Edit",
+                                                    "xtype": "TextItem",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "gltrans_date",
+                                            "header": "Date",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0}<br/><i style=\"color:#ccc;\">{1}</i>',\n         v ? v : '', r.data.gltrans_sequence\n     ); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "gltrans_source",
+                                            "header": "Source / Who",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0} - {1}<br/>{2}', v,r.data.gltrans_doctype, r.data.gltrans_username);\n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "gltrans_docnumber",
+                                            "header": "Doc Number",
+                                            "hidden": true,
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "gltrans_notes",
+                                            "header": "Notes",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{ \n    return String.format(\n            '<span qtip=\"{2}\"><b>{0}</b>' + \"\\n\" + '{1}', \n            r.data.gltrans_docnumber, v, \n            v.split('\\n').join('<br/>') \n        ).split('\\n').join('<br/>');\n    \n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "TextArea",
+                                                            "*prop": "field"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "gltrans_base_curr",
+                                            "header": "Currency",
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    return String.format('{0}', v); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "gltrans_credit_amount",
+                                            "header": "Credit",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0}', v ? Roo.util.Format.number(v*1,2)  : ''  );\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "gltrans_debit_amount",
+                                            "header": "Debit",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0}', v ? Roo.util.Format.number(v*1,2)  : ''  );\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "gltrans_balance",
+                                            "header": "Amount",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    var c =v >= 0.0 ? 'black' :  'red';\n\r\n   return String.format('<span style=\"color:' + c + ';\">{0}</span>',\r\n            Roo.util.Format.number(v,2) ); \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "005"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleGeneralLedger.js b/Pman.Tab.XtupleGeneralLedger.js
new file mode 100644 (file)
index 0000000..dc2b69c
--- /dev/null
@@ -0,0 +1,1342 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleGeneralLedger = new Roo.XComponent({
+    part     :  ["Xtuple","GeneralLedger"],
+    order    : '005-Pman.Tab.XtupleGeneralLedger',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleAccountsTab',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            fitContainer : true,
+            fitToFrame : true,
+            region : 'center',
+            title : "General Ledger",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.wpanel = this;
+                                if (_this.wgrid) {
+                                    _this.wgrid.ds.load({});
+                                }
+                            }
+                        },
+                        background : false,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'west',
+                        tableName : 'accnt',
+                        title : "Account",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.wgrid = this; 
+                                    _this.active = 1;
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.wpanel.active) {
+                                       this.ds.load({});
+                                    }
+                                },
+                                rowclick : function (_self, rowIndex, e)
+                                {
+                                    var s = _this.wgrid.ds.getAt(rowIndex);
+                                    
+                                    if(s.data.accnt_id * 1 < 1){
+                                        return;
+                                    }
+                                    
+                                    _this.grid.footer.onClick('first');
+                                    
+                                    
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    var ret = _this.wgrid.ds.getAt(rowIndex).data;
+                                    if(ret.accnt_id * 1 < 1){
+                                        Roo.MessageBox.alert("Error", "Error occur on getting the account id!");
+                                        return;
+                                    }
+                                    Pman.Dialog.XtupleGLAccountNameEdit.show( {accnt_id : ret.accnt_id}, function() {
+                                        _this.wgrid.ds.load({});
+                                    }); 
+                                }
+                            },
+                            autoExpandColumn : 'accnt_descrip',
+                            loadMask : true,
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            specialkey : function (_self, e)
+                                            {
+                                              _this.wgrid.ds.load({});
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.searchBox = _self;
+                                            }
+                                        },
+                                        width : 100
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.wgrid.ds.load({});
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.searchBox.setValue('');\r
+                                                _this.wgrid.ds.load({});\r
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)\r
+                                            {\r
+                                                _this.dateSel = _self;\r
+                                               _self.setValue(  new Date() );\r
+                                            },
+                                            select : function (combo, date)
+                                            {
+                                                _this.wgrid.ds.load({});
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        format : 'd/M/Y',
+                                        width : 100
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.orderBox = _self;
+                                            }
+                                        },
+                                        width : 80
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        text : "Download / Upload",
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            _this.active = (_this.active) ? 0 : 1;
+                                                            this.setText(_this.active ? "Show Inactive" : "Hide Inactive");
+                                                            _this.wgrid.ds.load({});
+                                                        }
+                                                    },
+                                                    text : "Show Inactive"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                            new Pman.download({
+                                                                url : baseURL + '/Roo/accnt.php',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    'start' : 0,
+                                                                    'limit' : 9999,
+                                                                    _with_xt_balances : 1,
+                                                                    'csvTitles[0]' : 'Name', 'csvCols[0]' : 'accnt_name',
+                                                                    'csvTitles[1]' : 'Description', 'csvCols[1]' : 'accnt_descrip',
+                                                                    'csvTitles[2]' : 'Alternative Code', 'csvCols[2]' : 'accnt_code_alt',
+                                                                    'csvTitles[3]' : 'Alternative Description', 'csvCols[3]' : 'accnt_code_descrip',
+                                                                    'csvTitles[4]' : 'ADJUST', 'csvCols[4]' : 'balance_base'
+                                                                }
+                                                                
+                                                            });
+                                                        }
+                                                    },
+                                                    text : "Download Balances"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                           Pman.Dialog.XtupleUploadBalances.show( {} , function(res) {
+                                                                Pman.Dialog.Image.show({
+                                                                    _url : baseURL + '/Xtuple/Import/JournalEntry?' + Roo.urlEncode(res)
+                                                                }, function(data) {
+                                                                     _this.wgrid.ds.load({});
+                                                                });
+                                                           }); 
+                                                        }
+                                                    },
+                                                    text : "Upload JE adjustment"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                          new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                timeout: 60000,
+                                                                newWindow : true,
+                                                                params : {
+                                                                    _group : 'apopen',
+                                                                    _name : 'bydate',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });;
+                                                            Roo.MessageBox.alert("Notice", "This may take some time to calculate");
+                                                        }
+                                                    },
+                                                    text : "Download AP - Day by Day Comparison"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                          new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                timeout: 90000,
+                                                                params : {
+                                                                    _group : 'apopen',
+                                                                    _name : 'bydatesummary',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });;
+                                                            Roo.MessageBox.alert("Notice", "This may take some time to calculate");
+                                                        }
+                                                    },
+                                                    text : "Download AP open vs GL - summary of bad days"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                          new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                timeout: 90000,
+                                                                params : {
+                                                                     'startDate:text' : _this.dateSel.getValue().format('Y-m-d'),
+                                                                    'endDate:text' :  _this.dateSel.getValue().add(Date.DAY,1).format('Y-m-d'),
+                                                                
+                                                                    _group : 'apopen',
+                                                                    _name : 'all',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });;
+                                                            Roo.MessageBox.alert("Notice", "This may take some time to calculate");
+                                                        }
+                                                    },
+                                                    text : "Download AP - Transactions on a single day"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                          new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                timeout: 90000,
+                                                                params : {
+                                                                     'relDate:text' : _this.dateSel.getValue().format('Y-m-d'),
+                                                                    'useDocDate:text' :  'FALSE',
+                                                                
+                                                                    _group : 'apAging',
+                                                                    _name : 'bydate',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });;
+                                                            Roo.MessageBox.alert("Notice", "This may take some time to calculate");
+                                                        }
+                                                    },
+                                                    text : "Download AP Aging at this date"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                          new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                timeout: 90000,
+                                                                params : {
+                                                                     
+                                                                    _group : 'apopen',
+                                                                    _name : 'history',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });
+                                                            Roo.MessageBox.alert("Notice", "This may take some time to calculate");
+                                                        }
+                                                    },
+                                                    text : "Download AP Aging History"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                             new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    _group : 'aropen',
+                                                                    _name : 'all',
+                                                                    'startDate:text' : _this.dateSel.getValue().format('Y-m-d'),
+                                                                    'endDate:text' :  _this.dateSel.getValue().add(Date.DAY,1).format('Y-m-d'),
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999        
+                                                                    
+                                                                }
+                                                            });;
+                                                        }
+                                                    },
+                                                    text : "Download AR - Transactions on a day"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                             new Pman.Download({
+                                                                url : baseURL + '/Roo/Metasql',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    _group : 'aropen',
+                                                                    _name : 'bydate',
+                                                                    csvCols : '*',
+                                                                    csvTitles : '*', 
+                                                                    limit : 9999         
+                                                                    
+                                                                }
+                                                            });;
+                                                        }
+                                                    },
+                                                    text : "Download AR - Day by Day Comparison"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "Gltrans vs Stock (COHEAD)",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'bydate',
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999       
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Gltrans vs Stock By Date"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var dt = _this.dateSel.getValue();
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'gltrans',
+                                                                                '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999       
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Gltrans"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var dt = _this.dateSel.getValue();
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'stock',
+                                                                                '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999       
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Stock"
+                                                            }
+                                                        ]
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "Gltrans vs Stock (PO)",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            timeout: 600000,
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'byorder',
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999       
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Gltrans vs Stock By PO"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var ord = _this.orderBox.getValue();
+                                                                        
+                                                                        if(!ord.length){
+                                                                            Roo.MessageBox.alert('Error','Please enter a PO number');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'byordergltrans',
+                                                                                'docnumber:text' : ord,
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999       
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Gltrans"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var ord = _this.orderBox.getValue();
+                                                                        
+                                                                        if(!ord.length){
+                                                                            Roo.MessageBox.alert('Error','Please enter a PO number');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL + '/Roo/Metasql',
+                                                                            method : 'GET',
+                                                                            params : {
+                                                                                _group : 'gltrans_stock',
+                                                                                _name : 'byorderstock',
+                                                                                'docnumber:text' : ord,
+                                                                                csvCols : '*',
+                                                                                csvTitles : '*', 
+                                                                                limit : 9999      
+                                                                            }
+                                                                        });
+                                                                    }
+                                                                },
+                                                                text : "Download Stock"
+                                                            }
+                                                        ]
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "Kingdee",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL+'/Xtuple/Kingdee/Currency',
+                                                                            method : 'GET',
+                                                                            timeout: 600000
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "Currency"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL+'/Xtuple/Kingdee/Rate',
+                                                                            method : 'GET',
+                                                                            timeout: 600000
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "Exchange Rate"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        
+                                                                         new Pman.Download({
+                                                                            url : baseURL+'/Xtuple/Kingdee/Account',
+                                                                            method : 'GET',
+                                                                            timeout: 600000
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "Accounts"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        new Pman.Download({
+                                                                            url : baseURL+'/Xtuple/Kingdee/VoucherGroup',
+                                                                            method : 'GET',
+                                                                            timeout: 600000
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "Voucher Category"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        //var dt = _this.dateSel.getValue();
+                                                                        new Pman.Download({
+                                                                            url : baseURL+'/Xtuple/Kingdee/Voucher',
+                                                                            method : 'GET',
+                                                                            timeout: 600000
+                                                                            //params : {
+                                                                            //    _as_of : (typeof(dt) == 'string') ? dt : dt.format('Y-m-d')
+                                                                            //}
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly - If you wanna import again, please delete all the exist!");
+                                                                    }
+                                                                },
+                                                                text : "Transactions"
+                                                            }
+                                                        ]
+                                                    }
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        options.params = options.params || {};
+                                        
+                                        options.params.limit = 9999;
+                                        
+                                        options.params._general_ledger = 1;
+                                        
+                                        options.params['search[name]'] = _this.searchBox.getValue();
+                                        
+                                        if (_this.active) {\r
+                                            options.params.accnt_active = 1;\r
+                                        }
+                                        
+                                        options.params._with_balances = 1;
+                                        \r    var dt = _this.dateSel.getValue();\r
+                                        options.params._as_of = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');
+                                        
+                                    
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'accnt_name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    listeners : {
+                                        loadexception : function (This, o, arg, e)
+                                        {
+                                        
+                                        }
+                                    },
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/accnt.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'accnt_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'accnt_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'accnt_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'accnt_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'accnt_type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'accnt_subaccnttype_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'accnt_curr_id_curr_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'accnt_curr_id_curr_id',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'accnt_name',
+                                    header : 'Name',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'accnt_code_alt',
+                                    header : 'Alternative Code',
+                                    hidden : true,
+                                    sortable : true,
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'accnt_descrip_alt',
+                                    header : 'Alternative Description',
+                                    hidden : true,
+                                    sortable : true,
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'accnt_type',
+                                    header : 'Type',
+                                    sortable : true,
+                                    width : 50,
+                                    renderer : function(v,x,r) {
+                                         return String.format('{0}-{1}', v,r.data.accnt_subaccnttype_code); 
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'accnt_descrip',
+                                    header : 'Description',
+                                    sortable : true,
+                                    width : 200,
+                                    renderer : function(v,x,r) 
+                                    { 
+                                        if(r.data.accnt_descrip_alt){
+                                            return String.format('{0} ({1})', v, r.data.accnt_descrip_alt);     
+                                        }
+                                        
+                                        return String.format('{0}', v); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'accnt_curr_id_curr_name',
+                                    header : 'Currency',
+                                    sortable : true,
+                                    width : 50,
+                                    renderer : function(v) { 
+                                        var base = baseURL.match(/sg\.php$/) ? 'SGD' : 'HKD';
+                                        if (v != base) {
+                                            return String.format('<span style="color:green">{0}</span>', v);     
+                                        }
+                                    
+                                        return String.format('{0}', v); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'balance',
+                                    header : 'Balance',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { \r
+                                       return String.format('<span style="color:blue;text-decoration:underline;">{0}</span>',\r
+                                                Roo.util.Format.usMoney(v) ); 
+                                    }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                             /*   if (_this.grid) {
+                                    _this.grid.ds.load({});
+                                } */
+                            }
+                        },
+                        background : false,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'gltrans',
+                        title : "Transactions",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                   /* if (_this.panel.active) {
+                                       this.ds.load({});
+                                    } */
+                                },
+                                afteredit : function (e)
+                                {   
+                                    var r = _this.grid.ds.getAt(e.row);
+                                    
+                                    if(e.value == e.originalValue || !r){
+                                        return;
+                                    }
+                                
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Gltrans.php',
+                                        method :'POST',
+                                        params : {
+                                            gltrans_id : r.data.gltrans_id,
+                                            gltrans_notes : e.value,
+                                            _update_notes : 1
+                                            
+                                        },
+                                        success : function() {
+                                           
+                                            _this.grid.footer.onClick('refresh');
+                                            
+                                        }
+                                    });
+                                    
+                                },
+                                rowclass : function (gridview, rowcfg)
+                                {
+                                  rowcfg.rowClass = 'dragon-gl-fixedheight';
+                                },
+                                celldblclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                    var cm = this.colModel.config[columnIndex].dataIndex;
+                                    var r = this.ds.getAt(rowIndex);
+                                    if (cm != 'gltrans_date') {
+                                        return;
+                                    }
+                                    new Pman.Download({
+                                        url : baseURL+ '/Roo/Metasql',
+                                        method : 'GET',
+                                        params : {
+                                            _group : 'gltrans',
+                                            _name : 'sequence',
+                                            'gltrans_sequence:number' : r.data.gltrans_sequence,
+                                            limit : 9999,
+                                        }
+                                    });
+                                    
+                                }
+                            },
+                            autoExpandColumn : 'gltrans_notes',
+                            clicksToEdit : 2,
+                            loadMask : true,
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            specialkey : function (_self, e)
+                                            {
+                                              _this.grid.footer.onClick('first');
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.gltransBox = _self;
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.gltransBox.setValue('');\r
+                                                _this.grid.footer.onClick('first');\r
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        cls : 'x-btn-text-icon',
+                                        text : "Download",
+                                        icon : rootURL + '/Pman/templates/images/spreadsheet.gif',
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var s = _this.wgrid.getSelectionModel().getSelected();
+                                                            
+                                                            if(!s){
+                                                                Roo.MessageBox.alert("Error", "Please select a account"); 
+                                                                return false;
+                                                            }
+                                                            
+                                                            var dt = _this.dateSel.getValue();
+                                                            
+                                                            if(!dt){
+                                                                Roo.MessageBox.alert("Error", "Please select a date on the right"); 
+                                                                return false;
+                                                            }  
+                                                            
+                                                            var g = _this.gltransBox.getValue();
+                                                            
+                                                            var params = {
+                                                                '_group' : 'account',
+                                                                '_name' : 'summary',
+                                                                'limit' : 99999,
+                                                                'accnt_id:number' : s.data.accnt_id,
+                                                                'endDate:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                'csvTitles' : '*',
+                                                                'csvCols' : '*'
+                                                            };
+                                                            
+                                                            if(g.length){
+                                                                params['search:text'] = g;
+                                                            }
+                                                            
+                                                            new Pman.Download({
+                                                              url : baseURL + '/Roo/Metasql',
+                                                              params :   params,
+                                                              method : 'GET'
+                                                            });
+                                                            
+                                                            Roo.MessageBox.alert("Notice", "All Transactions Report for " + s.data.accnt_descrip + " will download shortly");
+                                                        }
+                                                    },
+                                                    text : "Download All Transactions"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var s = _this.wgrid.getSelectionModel().getSelected();
+                                                            
+                                                            if(!s){
+                                                                Roo.MessageBox.alert("Error", "Please select a account"); 
+                                                                return false;
+                                                            }
+                                                            
+                                                            var dt = _this.dateSel.getValue();
+                                                            
+                                                            if(!dt){
+                                                                Roo.MessageBox.alert("Error", "Please select a date on the right"); 
+                                                                return false;
+                                                            }  
+                                                            
+                                                            new Pman.Download({
+                                                                url : baseURL + '/Roo/Gltrans.php',
+                                                                method :'GET',
+                                                                params : {
+                                                                    gltrans_accnt_id : s.data.accnt_id,
+                                                                    _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                    _download : 1
+                                                                }
+                                                            });
+                                                            
+                                                            Roo.MessageBox.alert("Notice", "Financial Year Report for " + s.data.accnt_descrip + " will download shortly");
+                                                        }
+                                                    },
+                                                    text : "Download All Transactions (Selected Financial Year)"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {   
+                                                            var dt = _this.dateSel.getValue();
+                                                            
+                                                            if(!dt){
+                                                                Roo.MessageBox.alert("Error", "Please select a date on the right"); 
+                                                                return false;
+                                                            }   
+                                                               
+                                                            new Pman.Download({
+                                                                url : baseURL + '/Roo/Gltrans.php',
+                                                                method :'GET',
+                                                                timeout : 900000,
+                                                                params : {
+                                                                    _as_of : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                                    _download : 1
+                                                                }
+                                                            });
+                                                            
+                                                            Roo.MessageBox.alert("Notice", "Financial Year Report for all accounts will download shortly! it might take several minutes");
+                                                        }
+                                                    },
+                                                    text : "Download All Transactions  / All Accounts (Selected Financial Year)"
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        options.params = options.params || {};
+                                        
+                                        var s = _this.wgrid.getSelectionModel().getSelected();
+                                        
+                                        if(!s){
+                                            return;
+                                        }
+                                        
+                                        var dt = _this.dateSel.getValue();
+                                        var g = _this.gltransBox.getValue();
+                                        
+                                        var params = {
+                                            _group : 'account',
+                                            _name : 'summary',
+                                            'accnt_id:number' : s.data.accnt_id,
+                                            'endDate:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d')
+                                        };
+                                        
+                                        if(g.length){
+                                            params['search:text'] = g;
+                                        }
+                                        
+                                        Roo.apply(options.params,params);
+                                        
+                                        var cm = _this.grid.getColumnModel();
+                                        var hide = (g.length) ? true : false;
+                                        
+                                        cm.setHidden(cm.getIndexByDataIndex('gltrans_balance'), hide);
+                                        
+                                        
+                                    }
+                                },
+                                remoteSort : true,
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    timeout : 600000,
+                                    url : baseURL + '/Roo/Metasql.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'gltrans_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'gltrans_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'gltrans_accnt_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'gltrans_source',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'gltrans_amount',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'gltrans_notes',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 100,
+                                items : [
+                                    {
+                                        xtype: 'TextItem',
+                                        xns: Roo.Toolbar,
+                                        text : "Double Click To Edit"
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'gltrans_date',
+                                    header : 'Date',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0}<br/><i style="color:#ccc;">{1}</i>',
+                                             v ? v : '', r.data.gltrans_sequence
+                                         ); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'gltrans_source',
+                                    header : 'Source / Who',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0} - {1}<br/>{2}', v,r.data.gltrans_doctype, r.data.gltrans_username);
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'gltrans_docnumber',
+                                    header : 'Doc Number',
+                                    hidden : true,
+                                    sortable : true,
+                                    width : 100
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'gltrans_notes',
+                                    header : 'Notes',
+                                    width : 200,
+                                    renderer : function(v,x,r) 
+                                    { 
+                                        return String.format(
+                                                '<span qtip="{2}"><b>{0}</b>' + "\n" + '{1}', 
+                                                r.data.gltrans_docnumber, v, 
+                                                v.split('\n').join('<br/>') 
+                                            ).split('\n').join('<br/>');
+                                        
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextArea',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'gltrans_base_curr',
+                                    header : 'Currency',
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) { 
+                                        return String.format('{0}', v); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'gltrans_credit_amount',
+                                    header : 'Credit',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0}', v ? Roo.util.Format.number(v*1,2)  : ''  );
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'gltrans_debit_amount',
+                                    header : 'Debit',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0}', v ? Roo.util.Format.number(v*1,2)  : ''  );
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'gltrans_balance',
+                                    header : 'Amount',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { 
+                                        var c =v >= 0.0 ? 'black' :  'red';
+                                    \r
+                                       return String.format('<span style="color:' + c + ';">{0}</span>',\r
+                                                Roo.util.Format.number(v,2) ); 
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    tabPosition : 'top'
+                },
+                west : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    tabPosition : 'top',
+                    width : 600
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleItem.bjs b/Pman.Tab.XtupleItem.bjs
new file mode 100644 (file)
index 0000000..2bf9f92
--- /dev/null
@@ -0,0 +1,737 @@
+{
+    "id": "roo-file-44",
+    "name": "Pman.Tab.XtupleItem",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "Pman.Tab.XtupleItem",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleItem.bjs",
+    "items": [
+        {
+            "background": true,
+            "region": "center",
+            "title": "Products",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "east",
+                            "split": true,
+                            "width": 200,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "item",
+                            "title": "Products",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "cellclick": "function (_self, row, col, e)\n{\n     var di = _this.grid.colModel.getDataIndex(col);\n     \n     var rec = _this.grid.ds.getAt(row);\n     \n     if(di == 'item_image_filename'){\n        if(!rec.data.item_image_id){\n            return;\n        }\n        var u = baseURL;\n        if(rec.data.item_image_from_hk){\n            u = u.split('/');\n            u.pop();\n            u = u.join('/') + '/hk.php';\n        }\n        Pman.download( {\n           url: u + '/Images/Download/' + rec.data.item_image_id  + '/' + rec.data.item_image_filename\n       });\n       return;\n     }\n     \n     if (di == 'item_active') {\n     \n        var nv = rec.data.item_active ? 0 : 1;\n        new Pman.Request({\n            mask : 'Saving',\n            url : baseURL + '/Roo/Item',\n            params : {\n                item_id : rec.data.item_id,\n                item_active : nv\n            },\n            success : function() {\n                rec.set('item_active', nv);\n            }\n        });\n        return;\n        \n     \n     }\n     \n     if(di == 'itemsrc_active'){\n        if(!rec.data.itemsrc_active){\n            Roo.MessageBox.alert('Error','Please edit it on Xtuple tool');\n            return;\n        }\n        if(rec.data.itemsrc_active){\n            Roo.MessageBox.confirm(\"Confirm\", \"Are you sure this product is no longer purchased\",\n                function (res) {\n                    if(res!='yes') {\n                        return;\n                    }\n                    rec.commit();\n            });\n        }\n    }\n     \n     _this.locgrid.footer.onClick('first');\n     \n     \n     \n     \n}",
+                                        "afteredit": "function (e)\n{\n    \n    \n    Roo.log(e);\n    new Pman.Request({\n        url : baseURL +'/Roo/Charass',\n        params : {\n             charass_char_id_char_name : e.field.replace(/^item_char_/,'').toUpperCase(),\n             charass_value : e.value,\n             charass_target_type : 'I',\n             charass_default : 1,\n             charass_target_id : e.record.data.item_id\n         },\n         method : 'POST'\n     });\n    \n    \n    e.record.commit();\n    \n    \n    \n}",
+                                        "celldblclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var s = _this.grid.ds.getAt(rowIndex);\n    \n    Pman.Dialog.XtupleItem.show( { item_id : s.data.item_id } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "item_descrip1",
+                                    "clicksToEdit": 1,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n  o.params._with_prodcat = 1;\n  o.params._with_char = 1;\n  o.params._with_itemsrc_active = 1;\n  o.params._with_last_purchase_price = 1;\n  o.params._with_image = 1;\n  var s = _this.search.getValue();\n  if (s.length) {\n    o.params['query[number_or_name]'] = s;\n  }\n  if (!_this.active.pressed) {\n    o.params.item_active = 1;\n  }\n  if (_this.brandSel.getValue().length) {\n    o.params._with_brand = _this.brandSel.getValue()\n  }\n  \n  o.params._with_stock_balance = 1;\n}",
+                                                "update": "function (_self, record, operation)\n{\n    if(operation != 'commit'){\n        return;\n    }\n    \n    var nv  = record.data.itemsrc_active ? 0 : 1;\n    new Pman.Request({\n        mask : 'Saving',\n        url : baseURL + '/Roo/Itemsrc',\n        params : {\n            _update_by_item : 1,\n            item_id : record.data.item_id,\n            itemsrc_active : nv\n        },\n        success : function(res) {\n            record.set('itemsrc_active', nv);\n        }\n    });\n}",
+                                                "load": "function (_self, records, options)\n{\n\n    var cm = _this.grid.getColumnModel();\n    if(records.length){\n        cm.setColumnHeader(cm.getIndexByDataIndex('item_stock_balance'),records[0].data.default_location_name);\n    }\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'item_number', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|url": "baseURL + '/Roo/item.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'item_descrip1',\n        'type': 'string'\n    },\n    {\n        'name': 'item_descrip2',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_picklist',\n        'type': 'int'\n    },\n    {\n        'name': 'item_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'item_sold',\n        'type': 'int'\n    },\n    {\n        'name': 'item_fractional',\n        'type': 'int'\n    },\n    {\n        'name': 'item_active',\n        'type': 'int'\n    },\n    {\n        'name': 'item_type',\n        'type': 'string'\n    },\n    {\n        'name': 'item_prodweight',\n        'type': 'float'\n    },\n    {\n        'name': 'item_packweight',\n        'type': 'float'\n    },\n    {\n        'name': 'item_prodcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_exclusive',\n        'type': 'int'\n    },\n    {\n        'name': 'item_listprice',\n        'type': 'float'\n    },\n    {\n        'name': 'item_config',\n        'type': 'int'\n    },\n    {\n        'name': 'item_extdescrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_upccode',\n        'type': 'string'\n    },\n    {\n        'name': 'item_maxcost',\n        'type': 'float'\n    },\n    {\n        'name': 'item_inv_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_warrdays',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_tax_recoverable',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_price_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'item_price_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_price_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_name',\n        'type': 'string'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_inv_uom_id_uom_item_weight',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_code',\n        'type': 'string'\n    },\n    {\n        'name': 'item_freightclass_id_freightclass_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'item_classcode_id_classcode_code',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_mfg',\n        'type': 'int'\n    },\n    {\n        'name': 'item_classcode_id_classcode_creator',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_created',\n        'type': 'date'\n    },\n    {\n        'name': 'item_classcode_id_classcode_modifier',\n        'type': 'string'\n    },\n    {\n        'name': 'item_classcode_id_classcode_modified',\n        'type': 'date'\n    },\n    {\n        'name': 'item_classcode_id_classcode_type',\n        'type': 'string'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.brandSel = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": true,
+                                                    "alwaysQuery": true,
+                                                    "displayField": "charass_value",
+                                                    "editable": true,
+                                                    "emptyText": "Select Brand",
+                                                    "forceSelection": true,
+                                                    "listWidth": 300,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "pageSize": 20,
+                                                    "qtip": "Select Brand",
+                                                    "queryParam": "query[charass_value]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charass_value}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n    // look for all of the charass 's with the same type= eg. brand.\n    \n    o.params.charass_char_id_char_name = 'BRAND';\n    o.params.charass_target_type ='I';\n    o.params._distinct = 'charass_value';\n        o.params._columns = 'charass_value';\n\n}"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ field : 'charass_value' , direction : 'ASC' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/Charass.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.data",
+                                                                    "xtype": "JsonReader",
+                                                                    "totalProperty": "total",
+                                                                    "root": "data",
+                                                                    "*prop": "reader",
+                                                                    "id": "id",
+                                                                    "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_name',\n        'type': 'string'\n    },\n    {\n        'name': 'event_when',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'on_id',\n        'type': 'int'\n    },\n    {\n        'name': 'on_table',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id',\n        'type': 'int'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_email',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_role',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_active',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_dt',\n        'type': 'date'\n    }\n]"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.search = _self;\n}",
+                                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "emptyText": "Search Product",
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n    _this.search.setValue('');\n    \n\n    \n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "toggle": "function (_self, pressed)\n{\n\n    this.setText(pressed ? \"Hide Inactive\" : \"Show Inactive\");\n    (function() { _this.grid.footer.onClick('first'); }).defer(100);\n}",
+                                                        "render": "function (_self)\n{\n    _this.active = _self;\n}"
+                                                    },
+                                                    "enableToggle": true,
+                                                    "text": "Show Inactive",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n\n   Pman.Dialog.XtupleItem.show( { item_id : 0 } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Add",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n    var s = _this.grid.selModel.getSelectedCell();\n    if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a product\");\n        return;\n    } \n    var rec = _this.grid.ds.getAt(s[0]);\n    \n    var params = [];\n    \n    Roo.MessageBox.prompt(\n        \"Rename SKU\", \n        \"Warning changing SKU names affects historical data, and should only be done if you are sure that this is ok\",\n        function(r,v) {\n            if (r != 'ok') {\n                return;\n                \n            }\n            params = {\n                _rename_sku : v,\n                item_id : rec.data.item_id,\n                _check : 1\n            }\n\n            change(params);\n            \n            return;\n                \n            \n\n        }\n    );\n    \n    var change = function(params){\n        new Pman.Request({\n            url : baseURL + '/Roo/Item',\n            mask : \"Renaming\",\n            method : 'POST',\n            params : params,\n            success : function(res) {\n                Roo.log(res);\n                _this.grid.footer.onClick('refresh');\n                if(typeof(res.data) == 'string'){\n                    Roo.MessageBox.alert(\"Notice\", 'SKU has been renamed');\n                    return\n                }\n                var offices = [];\n                Roo.each(res.data, function(o){\n                    offices.push(Pman.Xtuple.offices[o]);\n                })\n                Roo.MessageBox.alert(\"Notice\", 'SKU has been renamed in ' + offices.join(\", \"));\n                \n            },\n            failure : function(res) {\n                Roo.log(res);\n                try {\n                    if (res.errors.confirm.length) {\n                        var offices = [];\n                        Roo.each(res.errors.confirm, function(o){\n                            offices.push(Pman.Xtuple.offices[o]);\n                        })\n                        Roo.MessageBox.confirm(\n                            \"Confirm\", \n                            \" Do you want to change the name in \" + offices.join(\", \") + \"?\",\n                            function(x) {\n                                if (x != 'yes') {\n                                    Roo.MessageBox.alert(\"Notice\", 'SKU was not changed');\n                                    return;\n                                }\n                                delete params['_check'];\n                                params._can_change_sku = 1;\n                                change(params);\n                            }\n                        );\n                        return;\n                    }\n                } catch(e) { }\n                Roo.MessageBox.alert(\"Error\", res.errorMsg);\n                \n            }\n        });\n    }\n   \n}\n"
+                                                    },
+                                                    "text": "Rename SKU",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "text": "Report start :",
+                                                    "xtype": "TextItem",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.dateFrom = _self;\n}"
+                                                    },
+                                                    "format": "d/M/Y",
+                                                    "useIso": true,
+                                                    "xtype": "DateField",
+                                                    "|value": "(function() { return (new Date()).format('Y') + '-01-01'; })()",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.datespan  = _self;\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "cm_status",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "cm_status_name",
+                                                    "triggerAction": "all",
+                                                    "value": 12,
+                                                    "valueField": "ftype",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ \n    [ '1', \"Single Month Sales\"],\n    [ '3', \"Quarter Sales\"],\n    [ '6', \"Half year Sales\"] ,\n    [ '12', \"Full Year Sales\"] \n]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    if (!_this.brandSel.getValue().length) {\n        Roo.MessageBox.alert(\"Error\", \"Select a brand to download\");\n        return;\n    }\n\n    new Pman.Download({\n        url : baseURL + '/Xtuple/Reports/SalesByCountryItemYear',\n        params: { \n            date_from : _this.dateFrom.getValue(),\n            brand : _this.brandSel.getValue(),\n            span : _this.datespan.getValue()\n        }\n    });\n        \n\n}"
+                                                    },
+                                                    "text": "Download Sales Report",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying item{0} - {1} of {2}",
+                                            "emptyMsg": "No item found",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "text": "Tools - Upload/Download",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n   new Pman.Download({\n        method: 'GET',\n        url : baseURL + '/Roo/item',\n        params : {\n            _costgrid : 1\n        }\n   });\n}"
+                                                                    },
+                                                                    "text": "Download Standard costs",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n//   Roo.MessageBox.alert(\"Disabled\", \"Can you please send Alan the test file for this - there is a problem and we need to fix it before you use this again\");\n //  return;\n   \n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Products',\n            timeout : 60000\n        \n       },\n       function (data) {\n            var msg = [];\n           \n            if (data.updated) {\n                msg.push(\"Updated \" + data.updated + \" Products(s)\");\n            }            \n            if (data.inserted) {\n                msg.push(\"Added \" + data.inserted + \" Products(s)\");\n            }\n            if (data.skipped) {\n                msg.push(\"Skipped \" + data.skipped);\n            }\n            \n            if (!msg.length) {\n                msg.push(\"No data changed\");\n            }\n            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n}"
+                                                                    },
+                                                                    "text": "Upload new products and costs",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n    var sel = _this.grid.selModel.getSelectedCell();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row\");\n        return;\n    }\n    \n    var rec = _this.grid.ds.getAt(sel[0]);\n    if(rec.data.item_id * 1 < 1){\n        return;\n    }\n    \n    Pman.Dialog.Image.show({\n            id : rec.data.item_image_id ? rec.data.item_image_id : 0,\n            onid : rec.data.item_id,\n            ontable : 'item'\n        }, function(data) {\n            if (data) {\n                _this.grid.footer.onClick('first');\n                \n        }\n        \n    });\n}"
+                                                                    },
+                                                                    "text": "Upload an image",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n  Roo.MessageBox.progress (\"Syncing Stock\", \"Sending\");\n  \n  var offset = 0;\n  \n   function runSync() {\n       \n       new Pman.Request( {\n            url : baseURL+'/Roo/Item',\n            method : 'GET',\n            timeout: 60000,\n            params : {\n                _syncFromHK : 1,\n                offset : offset\n            },\n            success : function(res) {\n                Roo.log(res);\n                if (!res.data.total) {\n                    Roo.MessageBox.hide();\n                    return;\n                }\n                offset += res.data.limit;\n                Roo.MessageBox.updateProgress ( offset  / res.data.total, \"Done \" + offset + '/' + res.data.total);\n                runSync();\n            }\n            \n        \n       });\n   }\n   runSync();\n}"
+                                                                    },
+                                                                    "text": "Sync Product Data from HK",
+                                                                    "xtype": "Item",
+                                                                    "|hidden": "(function() {\n\n    return baseURL.match(/hk\\.php$/) ? true : false;\n})()",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n  Roo.MessageBox.progress (\"Syncing Stock\", \"Sending\");\n  \n  var offset = 0;\n  \n   \n       \n   new Pman.Request( {\n        url : baseURL+'/Roo/Item',\n        method : 'GET',\n        params : {\n            _syncFromHK : 1,\n            _new_only : 1\n        },\n        success : function(res) {\n            Roo.log(res);\n            \n                Roo.MessageBox.hide();\n             _this.grid.footer.onClick('refresh');\n            \n             \n        }\n        \n    \n   });\n    \n}"
+                                                                    },
+                                                                    "text": "Sync Product from HK (New Products Only)",
+                                                                    "xtype": "Item",
+                                                                    "|hidden": "(function() {\n\n    return baseURL.match(/hk\\.php$/) ? true : false;\n})()",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n  Roo.MessageBox.progress (\"Syncing Stock\", \"Sending\");\n  \n  var offset = 0;\n  \n   \n       \n   new Pman.Request( {\n        url : baseURL+'/Roo/Item',\n        method : 'GET',\n        params : {\n            _syncFromHK : 1,\n            item_number : _this.search.getValue()\n        },\n        success : function(res) {\n            Roo.log(res);\n            \n                Roo.MessageBox.hide();\n             _this.grid.footer.onClick('refresh');\n            \n             \n        }\n        \n    \n   });\n    \n}"
+                                                                    },
+                                                                    "text": "Sync Product from HK (Based on Search)",
+                                                                    "xtype": "Item",
+                                                                    "|hidden": "(function() {\n\n    return baseURL.match(/hk\\.php$/) ? true : false;\n})()",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_image_filename",
+                                            "header": "Image ( Click to download )",
+                                            "width": 150,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r)\r\n{\n   if(!v){\n    return '';\n   }\n   if(r.data.item_image_from_hk){\n        var url = baseURL.split('/');\n        url.pop();\n        url = url.join('/');\n        return '<img src=\"' + url + '/hk.php/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '\" width=\"150\" height=\"' + Math.ceil(150 / r.data.item_image_size) + '\" />';     \n   }\r\n   return '<img src=\"' + baseURL + '/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '\" width=\"150\" height=\"' + Math.ceil(150 / r.data.item_image_size) + '\" />';\r\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_char_brand",
+                                            "header": "Brand",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowBlank": true,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "charass_value",
+                                                            "editable": true,
+                                                            "forceSelection": false,
+                                                            "listWidth": 300,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select Brand",
+                                                            "queryParam": "query[charass_value]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charass_value}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "width": 150,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n    // look for all of the charass 's with the same type= eg. brand.\n    \n    o.params.charass_char_id_char_name = 'BRAND';\n    o.params.charass_target_type ='I';\n    o.params._distinct = 'charass_value';\n        o.params._columns = 'charass_value';\n\n}"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ field : 'charass_value' , direction : 'ASC' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/Charass.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "|xns": "Roo.data",
+                                                                            "xtype": "JsonReader",
+                                                                            "totalProperty": "total",
+                                                                            "root": "data",
+                                                                            "*prop": "reader",
+                                                                            "id": "id",
+                                                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_name',\n        'type': 'string'\n    },\n    {\n        'name': 'event_when',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'on_id',\n        'type': 'int'\n    },\n    {\n        'name': 'on_table',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id',\n        'type': 'int'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_email',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_role',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_active',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_dt',\n        'type': 'date'\n    }\n]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_char_productgroup",
+                                            "header": "Product Group",
+                                            "sortable": true,
+                                            "width": 60,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowBlank": true,
+                                                            "alwaysQuery": true,
+                                                            "displayField": "charass_value",
+                                                            "editable": true,
+                                                            "forceSelection": false,
+                                                            "listWidth": 300,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "pageSize": 20,
+                                                            "qtip": "Select Brand",
+                                                            "queryParam": "query[charass_value]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charass_value}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "width": 150,
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n    // look for all of the charass 's with the same type= eg. brand.\n    \n    o.params.charass_char_id_char_name = 'PRODUCTGROUP';\n    o.params.charass_target_type ='I';\n    o.params._distinct = 'charass_value';\n        o.params._columns = 'charass_value';    \n}"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ field : 'charass_value' , direction : 'ASC' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/Charass.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "|xns": "Roo.data",
+                                                                            "xtype": "JsonReader",
+                                                                            "totalProperty": "total",
+                                                                            "root": "data",
+                                                                            "*prop": "reader",
+                                                                            "id": "id",
+                                                                            "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_name',\n        'type': 'string'\n    },\n    {\n        'name': 'event_when',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'on_id',\n        'type': 'int'\n    },\n    {\n        'name': 'on_table',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id',\n        'type': 'int'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_email',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_role',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_active',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_dt',\n        'type': 'date'\n    }\n]"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_number",
+                                            "header": "Number",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('<B>{0}</B>', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_char_pickface_location",
+                                            "header": "Pickface",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "TextField",
+                                                            "*prop": "field"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_char_pallet_location",
+                                            "header": "Pallet",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.form",
+                                                            "xtype": "TextField",
+                                                            "*prop": "field"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_descrip1",
+                                            "header": "Description",
+                                            "sortable": true,
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "itemsrc_active",
+                                            "header": "Purchased",
+                                            "width": 55,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_sold",
+                                            "header": "is Sold?",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_active",
+                                            "header": "is Active?",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "last_purchase_price",
+                                            "header": "Last purchase price",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n\n     return String.format('{0}{1}', r.data.last_purchase_price_curr_name, Roo.util.Format.number(v,2)) ; \n     \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_prodcat_id_prodcat_code",
+                                            "header": "Item prodcat",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0}/{1}', r.data.item_type, v); \n    }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "item_actcost",
+                                            "header": "Cost",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n\n     return String.format('{0}{1}', r.data.item_curr_name, Roo.util.Format.number(v,2)) ; \n     \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "item_base_cost",
+                                            "header": "Cost (base)",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n\n     return String.format('{0}{1}', r.data.item_base_curr, Roo.util.Format.number(v,2)) ; \n     \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "item_stock_balance",
+                                            "header": "Balance",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? parseInt( v) : ''); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.locpanel = this;\n \n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "east",
+                            "tableName": "itemloc",
+                            "title": "itemloc",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.locgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    \n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "location_name",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    var sel = _this.grid.selModel.getSelectedCell();\n    if (!sel) {\n        this.removeAll();\n        return false;\n    }\n    var rec = _this.grid.ds.getAt(sel[0]);\n    o.params._stock_for_item_id = rec.data.item_id;\n    //o.params['!itemloc_qty'] = 0;\n    \n    \n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'location_name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'itemloc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'itemloc_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'itemloc_consolflag',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_ls_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying itemloc{0} - {1} of {2}",
+                                            "emptyMsg": "No itemloc found",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "location_name",
+                                            "header": "Location",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "itemloc_realqty",
+                                            "header": "Itemloc qty",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v*1 ? (v*1).toFixed(0) : ''); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "200"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleItem.js b/Pman.Tab.XtupleItem.js
new file mode 100644 (file)
index 0000000..01f3a71
--- /dev/null
@@ -0,0 +1,1752 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleItem = new Roo.XComponent({
+    part     :  ["Xtuple","Item"],
+    order    : '200-Pman.Tab.XtupleItem',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "Pman.Tab.XtupleItem",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            region : 'center',
+            title : "Products",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'item',
+                        title : "Products",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                cellclick : function (_self, row, col, e)
+                                {
+                                     var di = _this.grid.colModel.getDataIndex(col);
+                                     
+                                     var rec = _this.grid.ds.getAt(row);
+                                     
+                                     if(di == 'item_image_filename'){
+                                        if(!rec.data.item_image_id){
+                                            return;
+                                        }
+                                        var u = baseURL;
+                                        if(rec.data.item_image_from_hk){
+                                            u = u.split('/');
+                                            u.pop();
+                                            u = u.join('/') + '/hk.php';
+                                        }
+                                        Pman.download( {
+                                           url: u + '/Images/Download/' + rec.data.item_image_id  + '/' + rec.data.item_image_filename
+                                       });
+                                       return;
+                                     }
+                                     
+                                     if (di == 'item_active') {
+                                     
+                                        var nv = rec.data.item_active ? 0 : 1;
+                                        new Pman.Request({
+                                            mask : 'Saving',
+                                            url : baseURL + '/Roo/Item',
+                                            params : {
+                                                item_id : rec.data.item_id,
+                                                item_active : nv
+                                            },
+                                            success : function() {
+                                                rec.set('item_active', nv);
+                                            }
+                                        });
+                                        return;
+                                        
+                                     
+                                     }
+                                     
+                                     if(di == 'itemsrc_active'){
+                                        if(!rec.data.itemsrc_active){
+                                            Roo.MessageBox.alert('Error','Please edit it on Xtuple tool');
+                                            return;
+                                        }
+                                        if(rec.data.itemsrc_active){
+                                            Roo.MessageBox.confirm("Confirm", "Are you sure this product is no longer purchased",
+                                                function (res) {
+                                                    if(res!='yes') {
+                                                        return;
+                                                    }
+                                                    rec.commit();
+                                            });
+                                        }
+                                    }
+                                     
+                                     _this.locgrid.footer.onClick('first');
+                                     
+                                     
+                                     
+                                     
+                                },
+                                afteredit : function (e)
+                                {
+                                    
+                                    
+                                    Roo.log(e);
+                                    new Pman.Request({
+                                        url : baseURL +'/Roo/Charass',
+                                        params : {
+                                             charass_char_id_char_name : e.field.replace(/^item_char_/,'').toUpperCase(),
+                                             charass_value : e.value,
+                                             charass_target_type : 'I',
+                                             charass_default : 1,
+                                             charass_target_id : e.record.data.item_id
+                                         },
+                                         method : 'POST'
+                                     });
+                                    
+                                    
+                                    e.record.commit();
+                                    
+                                    
+                                    
+                                },
+                                celldblclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                    var s = _this.grid.ds.getAt(rowIndex);
+                                    
+                                    Pman.Dialog.XtupleItem.show( { item_id : s.data.item_id } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            },
+                            autoExpandColumn : 'item_descrip1',
+                            clicksToEdit : 1,
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                      o.params._with_prodcat = 1;
+                                      o.params._with_char = 1;
+                                      o.params._with_itemsrc_active = 1;
+                                      o.params._with_last_purchase_price = 1;
+                                      o.params._with_image = 1;
+                                      var s = _this.search.getValue();
+                                      if (s.length) {
+                                        o.params['query[number_or_name]'] = s;
+                                      }
+                                      if (!_this.active.pressed) {
+                                        o.params.item_active = 1;
+                                      }
+                                      if (_this.brandSel.getValue().length) {
+                                        o.params._with_brand = _this.brandSel.getValue()
+                                      }
+                                      
+                                      o.params._with_stock_balance = 1;
+                                    },
+                                    update : function (_self, record, operation)
+                                    {
+                                        if(operation != 'commit'){
+                                            return;
+                                        }
+                                        
+                                        var nv  = record.data.itemsrc_active ? 0 : 1;
+                                        new Pman.Request({
+                                            mask : 'Saving',
+                                            url : baseURL + '/Roo/Itemsrc',
+                                            params : {
+                                                _update_by_item : 1,
+                                                item_id : record.data.item_id,
+                                                itemsrc_active : nv
+                                            },
+                                            success : function(res) {
+                                                record.set('itemsrc_active', nv);
+                                            }
+                                        });
+                                    },
+                                    load : function (_self, records, options)
+                                    {
+                                    
+                                        var cm = _this.grid.getColumnModel();
+                                        if(records.length){
+                                            cm.setColumnHeader(cm.getIndexByDataIndex('item_stock_balance'),records[0].data.default_location_name);
+                                        }
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'item_number', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/item.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'item_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_descrip1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_descrip2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_picklist',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_comments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_sold',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_fractional',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_prodweight',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'item_packweight',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'item_prodcat_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_exclusive',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_listprice',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'item_config',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_extdescrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_upccode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_maxcost',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'item_inv_uom_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_price_uom_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_warrdays',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_freightclass_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_tax_recoverable',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_price_uom_id_uom_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_price_uom_id_uom_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_price_uom_id_uom_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_price_uom_id_uom_item_weight',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_inv_uom_id_uom_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_inv_uom_id_uom_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_inv_uom_id_uom_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_inv_uom_id_uom_item_weight',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_freightclass_id_freightclass_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_freightclass_id_freightclass_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_freightclass_id_freightclass_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_mfg',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_creator',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_created',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_modifier',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_modified',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'item_classcode_id_classcode_type',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.brandSel = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        alwaysQuery : true,
+                                        displayField : 'charass_value',
+                                        editable : true,
+                                        emptyText : "Select Brand",
+                                        forceSelection : true,
+                                        listWidth : 300,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        pageSize : 20,
+                                        qtip : "Select Brand",
+                                        queryParam : 'query[charass_value]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
+                                        triggerAction : 'all',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o)
+                                                {
+                                                    o.params = o.params || {};
+                                                    // staff can see all logs, other companies can only see their own.
+                                                    // look for all of the charass 's with the same type= eg. brand.
+                                                    
+                                                    o.params.charass_char_id_char_name = 'BRAND';
+                                                    o.params.charass_target_type ='I';
+                                                    o.params._distinct = 'charass_value';
+                                                        o.params._columns = 'charass_value';
+                                                
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { field : 'charass_value' , direction : 'ASC' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/Charass.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                totalProperty : 'total',
+                                                root : 'data',
+                                                id : 'id',
+                                                fields : [
+                                                    {
+                                                        'name': 'id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'event_when',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'action',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'ipaddr',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'on_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'on_table',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'remarks',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_office_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_phone',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_fax',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_email',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_company_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_role',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_active',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_remarks',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_passwd',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_owner_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_lang',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_no_reset_sent',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_action_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_project_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_deleted_by',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'person_id_deleted_dt',
+                                                        'type': 'date'
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.search = _self;
+                                            },
+                                            specialkey : function (_self, e)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        emptyText : "Search Product"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.search.setValue('');
+                                                
+                                            
+                                                
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            toggle : function (_self, pressed)
+                                            {
+                                            
+                                                this.setText(pressed ? "Hide Inactive" : "Show Inactive");
+                                                (function() { _this.grid.footer.onClick('first'); }).defer(100);
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.active = _self;
+                                            }
+                                        },
+                                        enableToggle : true,
+                                        text : "Show Inactive"
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                            
+                                               Pman.Dialog.XtupleItem.show( { item_id : 0 } , function() {
+                                                    _this.grid.footer.onClick('first');
+                                               }); 
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Add",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                                var s = _this.grid.selModel.getSelectedCell();
+                                                if (!s) {
+                                                    Roo.MessageBox.alert("Error", "Select a product");
+                                                    return;
+                                                } 
+                                                var rec = _this.grid.ds.getAt(s[0]);
+                                                
+                                                var params = [];
+                                                
+                                                Roo.MessageBox.prompt(
+                                                    "Rename SKU", 
+                                                    "Warning changing SKU names affects historical data, and should only be done if you are sure that this is ok",
+                                                    function(r,v) {
+                                                        if (r != 'ok') {
+                                                            return;
+                                                            
+                                                        }
+                                                        params = {
+                                                            _rename_sku : v,
+                                                            item_id : rec.data.item_id,
+                                                            _check : 1
+                                                        }
+                                            
+                                                        change(params);
+                                                        
+                                                        return;
+                                                            
+                                                        
+                                            
+                                                    }
+                                                );
+                                                
+                                                var change = function(params){
+                                                    new Pman.Request({
+                                                        url : baseURL + '/Roo/Item',
+                                                        mask : "Renaming",
+                                                        method : 'POST',
+                                                        params : params,
+                                                        success : function(res) {
+                                                            Roo.log(res);
+                                                            _this.grid.footer.onClick('refresh');
+                                                            if(typeof(res.data) == 'string'){
+                                                                Roo.MessageBox.alert("Notice", 'SKU has been renamed');
+                                                                return
+                                                            }
+                                                            var offices = [];
+                                                            Roo.each(res.data, function(o){
+                                                                offices.push(Pman.Xtuple.offices[o]);
+                                                            })
+                                                            Roo.MessageBox.alert("Notice", 'SKU has been renamed in ' + offices.join(", "));
+                                                            
+                                                        },
+                                                        failure : function(res) {
+                                                            Roo.log(res);
+                                                            try {
+                                                                if (res.errors.confirm.length) {
+                                                                    var offices = [];
+                                                                    Roo.each(res.errors.confirm, function(o){
+                                                                        offices.push(Pman.Xtuple.offices[o]);
+                                                                    })
+                                                                    Roo.MessageBox.confirm(
+                                                                        "Confirm", 
+                                                                        " Do you want to change the name in " + offices.join(", ") + "?",
+                                                                        function(x) {
+                                                                            if (x != 'yes') {
+                                                                                Roo.MessageBox.alert("Notice", 'SKU was not changed');
+                                                                                return;
+                                                                            }
+                                                                            delete params['_check'];
+                                                                            params._can_change_sku = 1;
+                                                                            change(params);
+                                                                        }
+                                                                    );
+                                                                    return;
+                                                                }
+                                                            } catch(e) { }
+                                                            Roo.MessageBox.alert("Error", res.errorMsg);
+                                                            
+                                                        }
+                                                    });
+                                                }
+                                               
+                                            }
+                                        },
+                                        text : "Rename SKU"
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'TextItem',
+                                        xns: Roo.Toolbar,
+                                        text : "Report start :"
+                                    },
+                                    {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.dateFrom = _self;
+                                            }
+                                        },
+                                        format : 'd/M/Y',
+                                        useIso : true,
+                                        value : (function() { return (new Date()).format('Y') + '-01-01'; })()
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.datespan  = _self;
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'cm_status',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'cm_status_name',
+                                        triggerAction : 'all',
+                                        value : 12,
+                                        valueField : 'ftype',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ 
+                                                [ '1', "Single Month Sales"],
+                                                [ '3', "Quarter Sales"],
+                                                [ '6', "Half year Sales"] ,
+                                                [ '12', "Full Year Sales"] 
+                                            ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                if (!_this.brandSel.getValue().length) {
+                                                    Roo.MessageBox.alert("Error", "Select a brand to download");
+                                                    return;
+                                                }
+                                            
+                                                new Pman.Download({
+                                                    url : baseURL + '/Xtuple/Reports/SalesByCountryItemYear',
+                                                    params: { 
+                                                        date_from : _this.dateFrom.getValue(),
+                                                        brand : _this.brandSel.getValue(),
+                                                        span : _this.datespan.getValue()
+                                                    }
+                                                });
+                                                    
+                                            
+                                            }
+                                        },
+                                        text : "Download Sales Report"
+                                    }
+                                ]
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying item{0} - {1} of {2}",
+                                emptyMsg : "No item found",
+                                items : [
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        text : "Tools - Upload/Download",
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                           new Pman.Download({
+                                                                method: 'GET',
+                                                                url : baseURL + '/Roo/item',
+                                                                params : {
+                                                                    _costgrid : 1
+                                                                }
+                                                           });
+                                                        }
+                                                    },
+                                                    text : "Download Standard costs"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                        //   Roo.MessageBox.alert("Disabled", "Can you please send Alan the test file for this - there is a problem and we need to fix it before you use this again");
+                                                         //  return;
+                                                           
+                                                           Pman.Dialog.Image.show(
+                                                               {
+                                                                    _url : baseURL+'/Xtuple/Import/Products',
+                                                                    timeout : 60000
+                                                                
+                                                               },
+                                                               function (data) {
+                                                                    var msg = [];
+                                                                   
+                                                                    if (data.updated) {
+                                                                        msg.push("Updated " + data.updated + " Products(s)");
+                                                                    }            
+                                                                    if (data.inserted) {
+                                                                        msg.push("Added " + data.inserted + " Products(s)");
+                                                                    }
+                                                                    if (data.skipped) {
+                                                                        msg.push("Skipped " + data.skipped);
+                                                                    }
+                                                                    
+                                                                    if (!msg.length) {
+                                                                        msg.push("No data changed");
+                                                                    }
+                                                                    Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                                        
+                                                               }
+                                                           );
+                                                        }
+                                                    },
+                                                    text : "Upload new products and costs"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                            var sel = _this.grid.selModel.getSelectedCell();
+                                                            if (!sel) {
+                                                                Roo.MessageBox.alert("Error", "Select a row");
+                                                                return;
+                                                            }
+                                                            
+                                                            var rec = _this.grid.ds.getAt(sel[0]);
+                                                            if(rec.data.item_id * 1 < 1){
+                                                                return;
+                                                            }
+                                                            
+                                                            Pman.Dialog.Image.show({
+                                                                    id : rec.data.item_image_id ? rec.data.item_image_id : 0,
+                                                                    onid : rec.data.item_id,
+                                                                    ontable : 'item'
+                                                                }, function(data) {
+                                                                    if (data) {
+                                                                        _this.grid.footer.onClick('first');
+                                                                        
+                                                                }
+                                                                
+                                                            });
+                                                        }
+                                                    },
+                                                    text : "Upload an image"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                          Roo.MessageBox.progress ("Syncing Stock", "Sending");
+                                                          
+                                                          var offset = 0;
+                                                          
+                                                           function runSync() {
+                                                               
+                                                               new Pman.Request( {
+                                                                    url : baseURL+'/Roo/Item',
+                                                                    method : 'GET',
+                                                                    timeout: 60000,
+                                                                    params : {
+                                                                        _syncFromHK : 1,
+                                                                        offset : offset
+                                                                    },
+                                                                    success : function(res) {
+                                                                        Roo.log(res);
+                                                                        if (!res.data.total) {
+                                                                            Roo.MessageBox.hide();
+                                                                            return;
+                                                                        }
+                                                                        offset += res.data.limit;
+                                                                        Roo.MessageBox.updateProgress ( offset  / res.data.total, "Done " + offset + '/' + res.data.total);
+                                                                        runSync();
+                                                                    }
+                                                                    
+                                                                
+                                                               });
+                                                           }
+                                                           runSync();
+                                                        }
+                                                    },
+                                                    text : "Sync Product Data from HK",
+                                                    hidden : (function() {
+                                                    
+                                                        return baseURL.match(/hk\.php$/) ? true : false;
+                                                    })()
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                          Roo.MessageBox.progress ("Syncing Stock", "Sending");
+                                                          
+                                                          var offset = 0;
+                                                          
+                                                           
+                                                               
+                                                           new Pman.Request( {
+                                                                url : baseURL+'/Roo/Item',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    _syncFromHK : 1,
+                                                                    _new_only : 1
+                                                                },
+                                                                success : function(res) {
+                                                                    Roo.log(res);
+                                                                    
+                                                                        Roo.MessageBox.hide();
+                                                                     _this.grid.footer.onClick('refresh');
+                                                                    
+                                                                     
+                                                                }
+                                                                
+                                                            
+                                                           });
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Sync Product from HK (New Products Only)",
+                                                    hidden : (function() {
+                                                    
+                                                        return baseURL.match(/hk\.php$/) ? true : false;
+                                                    })()
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                          Roo.MessageBox.progress ("Syncing Stock", "Sending");
+                                                          
+                                                          var offset = 0;
+                                                          
+                                                           
+                                                               
+                                                           new Pman.Request( {
+                                                                url : baseURL+'/Roo/Item',
+                                                                method : 'GET',
+                                                                params : {
+                                                                    _syncFromHK : 1,
+                                                                    item_number : _this.search.getValue()
+                                                                },
+                                                                success : function(res) {
+                                                                    Roo.log(res);
+                                                                    
+                                                                        Roo.MessageBox.hide();
+                                                                     _this.grid.footer.onClick('refresh');
+                                                                    
+                                                                     
+                                                                }
+                                                                
+                                                            
+                                                           });
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Sync Product from HK (Based on Search)",
+                                                    hidden : (function() {
+                                                    
+                                                        return baseURL.match(/hk\.php$/) ? true : false;
+                                                    })()
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_image_filename',
+                                    header : 'Image ( Click to download )',
+                                    width : 150,
+                                    renderer : function(v,x,r)
+                                    {
+                                       if(!v){
+                                        return '';
+                                       }
+                                       if(r.data.item_image_from_hk){
+                                            var url = baseURL.split('/');
+                                            url.pop();
+                                            url = url.join('/');
+                                            return '<img src="' + url + '/hk.php/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '" width="150" height="' + Math.ceil(150 / r.data.item_image_size) + '" />';     
+                                       }
+                                       return '<img src="' + baseURL + '/Images/Thumb/150x150/' + r.data.item_image_id + '/' + v + '" width="150" height="' + Math.ceil(150 / r.data.item_image_size) + '" />';
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_char_brand',
+                                    header : 'Brand',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : true,
+                                            alwaysQuery : true,
+                                            displayField : 'charass_value',
+                                            editable : true,
+                                            forceSelection : false,
+                                            listWidth : 300,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            pageSize : 20,
+                                            qtip : "Select Brand",
+                                            queryParam : 'query[charass_value]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
+                                            triggerAction : 'all',
+                                            width : 150,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o)
+                                                    {
+                                                        o.params = o.params || {};
+                                                        // staff can see all logs, other companies can only see their own.
+                                                        // look for all of the charass 's with the same type= eg. brand.
+                                                        
+                                                        o.params.charass_char_id_char_name = 'BRAND';
+                                                        o.params.charass_target_type ='I';
+                                                        o.params._distinct = 'charass_value';
+                                                            o.params._columns = 'charass_value';
+                                                    
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { field : 'charass_value' , direction : 'ASC' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/Charass.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    totalProperty : 'total',
+                                                    root : 'data',
+                                                    id : 'id',
+                                                    fields : [
+                                                        {
+                                                            'name': 'id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_name',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'event_when',
+                                                            'type': 'date',
+                                                            'dateFormat': 'Y-m-d'
+                                                        },
+                                                        {
+                                                            'name': 'action',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'ipaddr',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'on_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'on_table',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'remarks',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_office_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_name',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_phone',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_fax',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_email',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_company_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_role',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_active',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_remarks',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_passwd',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_owner_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_lang',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_no_reset_sent',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_action_type',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_project_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_deleted_by',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_deleted_dt',
+                                                            'type': 'date'
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_char_productgroup',
+                                    header : 'Product Group',
+                                    sortable : true,
+                                    width : 60,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            allowBlank : true,
+                                            alwaysQuery : true,
+                                            displayField : 'charass_value',
+                                            editable : true,
+                                            forceSelection : false,
+                                            listWidth : 300,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            pageSize : 20,
+                                            qtip : "Select Brand",
+                                            queryParam : 'query[charass_value]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
+                                            triggerAction : 'all',
+                                            width : 150,
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o)
+                                                    {
+                                                        o.params = o.params || {};
+                                                        // staff can see all logs, other companies can only see their own.
+                                                        // look for all of the charass 's with the same type= eg. brand.
+                                                        
+                                                        o.params.charass_char_id_char_name = 'PRODUCTGROUP';
+                                                        o.params.charass_target_type ='I';
+                                                        o.params._distinct = 'charass_value';
+                                                            o.params._columns = 'charass_value';    
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { field : 'charass_value' , direction : 'ASC' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/Charass.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    totalProperty : 'total',
+                                                    root : 'data',
+                                                    id : 'id',
+                                                    fields : [
+                                                        {
+                                                            'name': 'id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_name',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'event_when',
+                                                            'type': 'date',
+                                                            'dateFormat': 'Y-m-d'
+                                                        },
+                                                        {
+                                                            'name': 'action',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'ipaddr',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'on_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'on_table',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'remarks',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_office_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_name',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_phone',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_fax',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_email',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_company_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_role',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_active',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_remarks',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_passwd',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_owner_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_lang',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_no_reset_sent',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_action_type',
+                                                            'type': 'string'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_project_id',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_deleted_by',
+                                                            'type': 'int'
+                                                        },
+                                                        {
+                                                            'name': 'person_id_deleted_dt',
+                                                            'type': 'date'
+                                                        }
+                                                    ]
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_number',
+                                    header : 'Number',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('<B>{0}</B>', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_char_pickface_location',
+                                    header : 'Pickface',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_char_pallet_location',
+                                    header : 'Pallet',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_descrip1',
+                                    header : 'Description',
+                                    sortable : true,
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'itemsrc_active',
+                                    header : 'Purchased',
+                                    width : 55,
+                                    renderer : function(v) {  
+                                        var state = v * 1 > 0 ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_sold',
+                                    header : 'is Sold?',
+                                    width : 50,
+                                    renderer : function(v) {  
+                                        var state = v * 1 > 0 ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_active',
+                                    header : 'is Active?',
+                                    width : 50,
+                                    renderer : function(v) {  
+                                        var state = v * 1 > 0 ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'last_purchase_price',
+                                    header : 'Last purchase price',
+                                    width : 120,
+                                    renderer : function(v,x,r) {
+                                    
+                                         return String.format('{0}{1}', r.data.last_purchase_price_curr_name, Roo.util.Format.number(v,2)) ; 
+                                         
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_prodcat_id_prodcat_code',
+                                    header : 'Item prodcat',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0}/{1}', r.data.item_type, v); 
+                                        }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'item_actcost',
+                                    header : 'Cost',
+                                    width : 75,
+                                    renderer : function(v,x,r) {
+                                    
+                                         return String.format('{0}{1}', r.data.item_curr_name, Roo.util.Format.number(v,2)) ; 
+                                         
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'item_base_cost',
+                                    header : 'Cost (base)',
+                                    width : 75,
+                                    renderer : function(v,x,r) {
+                                    
+                                         return String.format('{0}{1}', r.data.item_base_curr, Roo.util.Format.number(v,2)) ; 
+                                         
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'item_stock_balance',
+                                    header : 'Balance',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v ? parseInt( v) : ''); }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.locpanel = this;
+                             
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'east',
+                        tableName : 'itemloc',
+                        title : "itemloc",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.locgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                        _this.grid.footer.onClick('first');
+                                    }); 
+                                }
+                            },
+                            autoExpandColumn : 'location_name',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        var sel = _this.grid.selModel.getSelectedCell();
+                                        if (!sel) {
+                                            this.removeAll();
+                                            return false;
+                                        }
+                                        var rec = _this.grid.ds.getAt(sel[0]);
+                                        o.params._stock_for_item_id = rec.data.item_id;
+                                        //o.params['!itemloc_qty'] = 0;
+                                        
+                                        
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'location_name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/location.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'itemloc_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_itemsite_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_location_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_qty',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'itemloc_expiration',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'itemloc_consolflag',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_ls_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_warrpurc',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying itemloc{0} - {1} of {2}",
+                                emptyMsg : "No itemloc found"
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'location_name',
+                                    header : 'Location',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'itemloc_realqty',
+                                    header : 'Itemloc qty',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v*1 ? (v*1).toFixed(0) : ''); }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                east : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    width : 200
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleLanded.bjs b/Pman.Tab.XtupleLanded.bjs
new file mode 100644 (file)
index 0000000..ff973ae
--- /dev/null
@@ -0,0 +1,416 @@
+{
+    "id": "roo-file-39",
+    "name": "Pman.Tab.XtupleLanded",
+    "parent": "Pman.Tab.XtuplePurchases",
+    "title": "Pman.Tab.XtupleLanded",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleLanded.bjs",
+    "items": [
+        {
+            "background": true,
+            "region": "center",
+            "title": "Landed Costs",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "east",
+                            "split": true,
+                            "width": 500,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "vohead",
+                            "title": "vohead",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "vohead_reference",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    options.params._landed = 1;\n    if (!_this.vsearch) {\n        return false;\n    }\n    options.params._landed_status = _this.status.getValue();    \n \n\n    options.params._search = _this.vsearch.getValue();\n}",
+                                                "load": "function (_self, records, options)\n{\n_this.rgrid.footer.onClick('refresh');\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'vohead_gldistdate', direction: 'DESC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|url": "baseURL + '/Roo/vohead.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'vohead_pohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'vohead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'vohead_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'vohead_docdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'vohead_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_distdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'vohead_reference',\n        'type': 'string'\n    },\n    {\n        'name': 'vohead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_adjtaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_freighttaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_gldistdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'vohead_misc',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vohead_notes',\n        'type': 'string'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "afterselectionchange": "function (_self)\n{\n    _this.rsearch.setValue('');\n    _this.rgrid.footer.onClick('first');\n}"
+                                            },
+                                            "*prop": "sm",
+                                            "singleSelect": true,
+                                            "xtype": "RowSelectionModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying vohead{0} - {1} of {2}",
+                                            "emptyMsg": "No vohead found",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "cm_status",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "cm_status_name",
+                                                    "triggerAction": "all",
+                                                    "value": "NOTASSIGN",
+                                                    "valueField": "ftype",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ \n    [ 'NOTASSIGN', \"Not Assigned\"],\n    [ 'ASSIGNED' , \"Assigned\"]\n]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.vsearch = _self;\n}",
+                                                        "specialkey": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vohead_gldistdate",
+                                            "header": "Date",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vohead_number",
+                                            "header": "no#",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return String.format('{0} / {1}', v,r.data.vohead_invcnumber); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vohead_reference",
+                                            "header": "Ref#",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vohead_vend_id_vend_name",
+                                            "header": "Vohead vend",
+                                            "width": 150,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "vohead_total",
+                                            "header": "Amount",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n  \n    \n    return String.format('{0} {1}', r.data.vohead_curr_id_curr_symbol,v); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "assigned",
+                                            "header": "Assigned",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    return v ? String.format('${0}',  v) : ''; \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.rpanel = this;\n    //if (_this.rgrid) {\n      //  _this.rgrid.footer.onClick('first');\n    //}\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "east",
+                            "tableName": "recvgrp",
+                            "title": "recvgrp",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.rgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    //if (_this.panel.active) {\n   //    this.footer.onClick('first');\n    //}\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "recvgrp_number",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    var sel = _this.grid.selModel.getSelected();\n    if (!sel) {\n        this.removeAll();\n        return false;\n    }\n    o.params =  o.params || {};\n    o.params._landed_vohead = sel.data.vohead_id;\n    o.params._search = _this.rsearch.getValue();\n    \n    \n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'recvgrp_date', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|url": "baseURL + '/Roo/recvgrp.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'recvgrp_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recvgrp_number',\n        'type': 'string'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying recvgrp{0} - {1} of {2}",
+                                            "emptyMsg": "No recvgrp found",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.rsearch = _self;\n}",
+                                                        "specialkey": "function (_self, e)\n{\n_this.rgrid.footer.onClick('first');\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n_this.rgrid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var recv = _this.rgrid.selModel.getSelected();\n    var vo = _this.grid.selModel.getSelected();\n    if (!vo || !recv) {\n        return;\n    }\n    new Pman.Request({\n        mask : 'saving',\n        method  : 'POST',\n        url : baseURL + '/Roo/Recvgrpland',\n        params : {\n            recvgrpland_vohead_id : vo.data.vohead_id,\n            recvgrpland_recvgrp_id : recv.data.recvgrp_id, \n            recvgrpland_cost : vo.data.vohead_total,\n            recvgrpland_curr_id : vo.data.vohead_curr_id\n        },\n        success : function () {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n            \n    \n    \n}"
+                                                    },
+                                                    "text": "Assign All",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var recv = _this.rgrid.selModel.getSelected();\n    var vo = _this.grid.selModel.getSelected();\n    if (!vo || !recv) {\n        return;\n    }\n    \n    var avail = ((1*vo.data.vohead_total) - (1*vo.data.assigned)).toFixed(2);\n    \n    Roo.MessageBox.prompt(\"How much to assign?\",\n        \"The total available to assign is \" + vo.data.vohead_curr_id_curr_symbol +\n             ' ' + Roo.util.Format.number(avail,2),\n        function (b, n) {\n            if (b != 'ok') {\n                return;\n            }\n            n = n*1;\n            if (isNaN(n)) {\n                Roo.MessageBox.alert(\"Error\", \"did not get a number\");\n                return;\n            }\n\n            //vo.data.vohead_total\n            if (n*1 > avail) {\n                Roo.MessageBox.alert(\"Error\", \"you assigned to much, try again\");\n                return;\n            }\n            \n            \n            new Pman.Request({\n                mask : 'saving',\n                method  : 'POST',\n                url : baseURL + '/Roo/Recvgrpland',\n                params : {\n                    recvgrpland_vohead_id : vo.data.vohead_id,\n                    recvgrpland_recvgrp_id : recv.data.recvgrp_id, \n                    recvgrpland_cost : n,\n                    recvgrpland_curr_id : vo.data.vohead_curr_id\n                },\n                success : function () {\n                    _this.grid.footer.onClick('refresh');\n                }\n            });\n        }\n    );\n    \n    \n}\n\n"
+                                                    },
+                                                    "text": "Assign Some",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var recv = _this.rgrid.selModel.getSelected();\n    var vo = _this.grid.selModel.getSelected();\n    if (!vo || !recv) {\n        return;\n    }\n   var av = recv.data.assigned_landed * 1;\n    if (!av) {\n        return;\n    }\n    \n    new Pman.Request({\n        mask : 'saving',\n        method  : 'POST',\n        url : baseURL + '/Roo/Recvgrpland',\n        params : {\n            _void : 1,\n            recvgrpland_vohead_id : vo.data.vohead_id,\n            recvgrpland_recvgrp_id : recv.data.recvgrp_id\n        },\n        success : function () {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n            \n    \n    \n}"
+                                                    },
+                                                    "text": "Remove Assign",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "recvgrp_date",
+                                            "header": "Date",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v.format('d/M/Y')); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "recvgrp_pohead_id_pohead_number",
+                                            "header": "Po#",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "recvgrp_number",
+                                            "header": "ref#",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vend_name",
+                                            "header": "Vendor",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "recvgrp_location_id_location_descrip",
+                                            "header": "loc",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "recv_qty",
+                                            "header": "Qty",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    if (v*1 <= 0.0) {\n        return '';\n    }\n    return Roo.util.Format.number(v, 2); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "recvgrp_landed_cost",
+                                            "header": "Old landed",
+                                            "hidden": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    if (v*1 <= 0.0) {\n        return '';\n    }\n    return Roo.util.Format.number(v, 2); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "assigned_landed",
+                                            "header": "Assigned Value",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if (v*1 <= 0.0) {\n    \n        if (r.data.total_landed_cost*1 > 0) {\n            return '<span style=\"color:#ccc\">' + \n             String.format('{0}', r.data.base_curr_symbol) + \n             Roo.util.Format.number(r.data.total_landed_cost, 2) + '</span>';\n        }\n    \n        return '';\n    }\n    return  String.format('{0}', r.data.base_curr_symbol) +  Roo.util.Format.number(v, 2); \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "100"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleLanded.js b/Pman.Tab.XtupleLanded.js
new file mode 100644 (file)
index 0000000..e84ccbe
--- /dev/null
@@ -0,0 +1,701 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleLanded = new Roo.XComponent({
+    part     :  ["Xtuple","Landed"],
+    order    : '100-Pman.Tab.XtupleLanded',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtuplePurchases',
+    name     : "Pman.Tab.XtupleLanded",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            region : 'center',
+            title : "Landed Costs",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'vohead',
+                        title : "vohead",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                        _this.grid.footer.onClick('first');
+                                    }); 
+                                }
+                            },
+                            autoExpandColumn : 'vohead_reference',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        options.params._landed = 1;
+                                        if (!_this.vsearch) {
+                                            return false;
+                                        }
+                                        options.params._landed_status = _this.status.getValue();    
+                                     
+                                    
+                                        options.params._search = _this.vsearch.getValue();
+                                    },
+                                    load : function (_self, records, options)
+                                    {
+                                    _this.rgrid.footer.onClick('refresh');
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'vohead_gldistdate', direction: 'DESC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/vohead.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'vohead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'vohead_pohead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_posted',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_duedate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'vohead_invcnumber',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'vohead_amount',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'vohead_docdate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'vohead_1099',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_distdate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'vohead_reference',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'vohead_terms_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_vend_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_curr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_adjtaxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_freighttaxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_gldistdate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'vohead_misc',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_taxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vohead_notes',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            sm : {
+                                xtype: 'RowSelectionModel',
+                                xns: Roo.grid,
+                                listeners : {
+                                    afterselectionchange : function (_self)
+                                    {
+                                        _this.rsearch.setValue('');
+                                        _this.rgrid.footer.onClick('first');
+                                    }
+                                },
+                                singleSelect : true
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying vohead{0} - {1} of {2}",
+                                emptyMsg : "No vohead found"
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.status = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                Roo.log('select');
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'cm_status',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'cm_status_name',
+                                        triggerAction : 'all',
+                                        value : "NOTASSIGN",
+                                        valueField : 'ftype',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ 
+                                                [ 'NOTASSIGN', "Not Assigned"],
+                                                [ 'ASSIGNED' , "Assigned"]
+                                            ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.vsearch = _self;
+                                            },
+                                            specialkey : function (_self, e)
+                                            {
+                                            _this.grid.footer.onClick('first');
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vohead_gldistdate',
+                                    header : 'Date',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vohead_number',
+                                    header : 'no#',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return String.format('{0} / {1}', v,r.data.vohead_invcnumber); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vohead_reference',
+                                    header : 'Ref#',
+                                    width : 120,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vohead_vend_id_vend_name',
+                                    header : 'Vohead vend',
+                                    width : 150,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'vohead_total',
+                                    header : 'Amount',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                      
+                                        
+                                        return String.format('{0} {1}', r.data.vohead_curr_id_curr_symbol,v); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'assigned',
+                                    header : 'Assigned',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        return v ? String.format('${0}',  v) : ''; 
+                                    }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.rpanel = this;
+                                //if (_this.rgrid) {
+                                  //  _this.rgrid.footer.onClick('first');
+                                //}
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'east',
+                        tableName : 'recvgrp',
+                        title : "recvgrp",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.rgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    //if (_this.panel.active) {
+                                   //    this.footer.onClick('first');
+                                    //}
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                        _this.grid.footer.onClick('first');
+                                    }); 
+                                }
+                            },
+                            autoExpandColumn : 'recvgrp_number',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        var sel = _this.grid.selModel.getSelected();
+                                        if (!sel) {
+                                            this.removeAll();
+                                            return false;
+                                        }
+                                        o.params =  o.params || {};
+                                        o.params._landed_vohead = sel.data.vohead_id;
+                                        o.params._search = _this.rsearch.getValue();
+                                        
+                                        
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'recvgrp_date', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/recvgrp.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'recvgrp_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'recvgrp_number',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying recvgrp{0} - {1} of {2}",
+                                emptyMsg : "No recvgrp found"
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.rsearch = _self;
+                                            },
+                                            specialkey : function (_self, e)
+                                            {
+                                            _this.rgrid.footer.onClick('first');
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            _this.rgrid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var recv = _this.rgrid.selModel.getSelected();
+                                                var vo = _this.grid.selModel.getSelected();
+                                                if (!vo || !recv) {
+                                                    return;
+                                                }
+                                                new Pman.Request({
+                                                    mask : 'saving',
+                                                    method  : 'POST',
+                                                    url : baseURL + '/Roo/Recvgrpland',
+                                                    params : {
+                                                        recvgrpland_vohead_id : vo.data.vohead_id,
+                                                        recvgrpland_recvgrp_id : recv.data.recvgrp_id, 
+                                                        recvgrpland_cost : vo.data.vohead_total,
+                                                        recvgrpland_curr_id : vo.data.vohead_curr_id
+                                                    },
+                                                    success : function () {
+                                                        _this.grid.footer.onClick('refresh');
+                                                    }
+                                                });
+                                                        
+                                                
+                                                
+                                            }
+                                        },
+                                        text : "Assign All"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var recv = _this.rgrid.selModel.getSelected();
+                                                var vo = _this.grid.selModel.getSelected();
+                                                if (!vo || !recv) {
+                                                    return;
+                                                }
+                                                
+                                                var avail = ((1*vo.data.vohead_total) - (1*vo.data.assigned)).toFixed(2);
+                                                
+                                                Roo.MessageBox.prompt("How much to assign?",
+                                                    "The total available to assign is " + vo.data.vohead_curr_id_curr_symbol +
+                                                         ' ' + Roo.util.Format.number(avail,2),
+                                                    function (b, n) {
+                                                        if (b != 'ok') {
+                                                            return;
+                                                        }
+                                                        n = n*1;
+                                                        if (isNaN(n)) {
+                                                            Roo.MessageBox.alert("Error", "did not get a number");
+                                                            return;
+                                                        }
+                                            
+                                                        //vo.data.vohead_total
+                                                        if (n*1 > avail) {
+                                                            Roo.MessageBox.alert("Error", "you assigned to much, try again");
+                                                            return;
+                                                        }
+                                                        
+                                                        
+                                                        new Pman.Request({
+                                                            mask : 'saving',
+                                                            method  : 'POST',
+                                                            url : baseURL + '/Roo/Recvgrpland',
+                                                            params : {
+                                                                recvgrpland_vohead_id : vo.data.vohead_id,
+                                                                recvgrpland_recvgrp_id : recv.data.recvgrp_id, 
+                                                                recvgrpland_cost : n,
+                                                                recvgrpland_curr_id : vo.data.vohead_curr_id
+                                                            },
+                                                            success : function () {
+                                                                _this.grid.footer.onClick('refresh');
+                                                            }
+                                                        });
+                                                    }
+                                                );
+                                                
+                                                
+                                            }
+                                        },
+                                        text : "Assign Some"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var recv = _this.rgrid.selModel.getSelected();
+                                                var vo = _this.grid.selModel.getSelected();
+                                                if (!vo || !recv) {
+                                                    return;
+                                                }
+                                               var av = recv.data.assigned_landed * 1;
+                                                if (!av) {
+                                                    return;
+                                                }
+                                                
+                                                new Pman.Request({
+                                                    mask : 'saving',
+                                                    method  : 'POST',
+                                                    url : baseURL + '/Roo/Recvgrpland',
+                                                    params : {
+                                                        _void : 1,
+                                                        recvgrpland_vohead_id : vo.data.vohead_id,
+                                                        recvgrpland_recvgrp_id : recv.data.recvgrp_id
+                                                    },
+                                                    success : function () {
+                                                        _this.grid.footer.onClick('refresh');
+                                                    }
+                                                });
+                                                        
+                                                
+                                                
+                                            }
+                                        },
+                                        text : "Remove Assign"
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'recvgrp_date',
+                                    header : 'Date',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v.format('d/M/Y')); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'recvgrp_pohead_id_pohead_number',
+                                    header : 'Po#',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'recvgrp_number',
+                                    header : 'ref#',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vend_name',
+                                    header : 'Vendor',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'recvgrp_location_id_location_descrip',
+                                    header : 'loc',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'recv_qty',
+                                    header : 'Qty',
+                                    width : 75,
+                                    renderer : function(v) { 
+                                        if (v*1 <= 0.0) {
+                                            return '';
+                                        }
+                                        return Roo.util.Format.number(v, 2); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'recvgrp_landed_cost',
+                                    header : 'Old landed',
+                                    hidden : true,
+                                    width : 75,
+                                    renderer : function(v) { 
+                                        if (v*1 <= 0.0) {
+                                            return '';
+                                        }
+                                        return Roo.util.Format.number(v, 2); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'assigned_landed',
+                                    header : 'Assigned Value',
+                                    width : 75,
+                                    renderer : function(v,x,r) { 
+                                        if (v*1 <= 0.0) {
+                                        
+                                            if (r.data.total_landed_cost*1 > 0) {
+                                                return '<span style="color:#ccc">' + 
+                                                 String.format('{0}', r.data.base_curr_symbol) + 
+                                                 Roo.util.Format.number(r.data.total_landed_cost, 2) + '</span>';
+                                            }
+                                        
+                                            return '';
+                                        }
+                                        return  String.format('{0}', r.data.base_curr_symbol) +  Roo.util.Format.number(v, 2); 
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                east : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    width : 500
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleManage.bjs b/Pman.Tab.XtupleManage.bjs
new file mode 100644 (file)
index 0000000..60fe953
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "id": "roo-file-244",
+    "name": "Pman.Tab.XtupleManage",
+    "parent": "Pman",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleManage.bjs",
+    "items": [
+        {
+            "region": "center",
+            "title": "Manage Xtuple",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "xtype": "BorderLayout",
+                    "|xns": "Roo",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo",
+                            "*prop": "center",
+                            "alwaysShowTabs": true,
+                            "tabPosition": "top"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "100"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleManage.js b/Pman.Tab.XtupleManage.js
new file mode 100644 (file)
index 0000000..39239e7
--- /dev/null
@@ -0,0 +1,34 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleManage = new Roo.XComponent({
+    part     :  ["Xtuple","Manage"],
+    order    : '100-Pman.Tab.XtupleManage',
+    region   : 'center',
+    parent   : 'Pman',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            region : 'center',
+            title : "Manage Xtuple",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    alwaysShowTabs : true,
+                    tabPosition : 'top'
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePeriods.bjs b/Pman.Tab.XtuplePeriods.bjs
new file mode 100644 (file)
index 0000000..9d64945
--- /dev/null
@@ -0,0 +1,339 @@
+{
+    "id": "roo-file-47",
+    "name": "Pman.Tab.XtuplePeriods",
+    "parent": "Pman.Tab.XtupleAccountsTab",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePeriods.bjs",
+    "items": [
+        {
+            "background": true,
+            "fitContainer": true,
+            "fitToFrame": true,
+            "region": "center",
+            "title": "Periods",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "center",
+                            "tabPosition": "top",
+                            "title": "Periods",
+                            "titlebar": false,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "west",
+                            "split": true,
+                            "tabPosition": "top",
+                            "title": "Year Periods",
+                            "titlebar": false,
+                            "width": 400,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.wpanel = this;\n    if (_this.wgrid) {\n        _this.wgrid.ds.load({});\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "west",
+                            "tableName": "yearperiod",
+                            "title": "Year Periods",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.wgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.wpanel.active) {\n       this.ds.load({});\n    }\n}",
+                                        "rowclick": "function (_self, rowIndex, e)\n{\n    _this.grid.ds.load({});\n}",
+                                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n\n    var di = this.colModel.getDataIndex(columnIndex);\n\n    if (di != 'yearperiod_closed') {\n        return;\n    }\n\n    var rec = this.ds.getAt(rowIndex);\n\n\n  var open = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Yearperiod.php',\n            timeout: 600000,\n            mask : 'Processing',\n            method : 'POST',\n            params : {\n                yearperiod_id : rec.data.yearperiod_id,\n                _open : 1\n                \n            }, \n            success : function() {\n                _this.wgrid.ds.load({});\n            }\n        });    \n    };\n    \n    var close = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Yearperiod.php',\n            timeout: 600000,\n            mask : 'Processing',\n            method : 'POST',\n            params : {\n                yearperiod_id : rec.data.yearperiod_id,\n                _close : 1\n                \n            }, \n            success : function() {\n                _this.wgrid.ds.load({});\n            }\n        });    \n    };\n    \n    if(rec.data.yearperiod_id * 1 < 1){\n        Roo.MessageBox.alert('Error', 'Please select a period?');\n        return;\n    }\n\n    //Roo.log(rec.data);\n    if(rec.data.yearperiod_closed *1){\n         Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to open this year period?\" , function(r) {\n            if (r !='yes') {\n                return;\n            }\n            open();\n         \n          });\n         return;\n   }\n        \n    \n\n  \n     Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to close this year period?\" , function(r) {\n        if (r !='yes') {\n            return;\n        }\n        close();\n        \n   })\n   \n    \n    \n    \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "yearperiod_start",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "sm",
+                                            "singleSelect": true,
+                                            "xtype": "RowSelectionModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'yearperiod_start', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Yearperiod.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'yearperiod_id',\n        'type': 'int'\n    },\n    {\n        'name': 'yearperiod_name',\n        'type': 'string'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "yearperiod_name",
+                                            "header": "Name",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{ \n    v = r.data.yearperiod_start.getFullYear() + '-' + r.data.yearperiod_end.getFullYear();\n    \n    return String.format('{0}', v ? v : ''); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "yearperiod_start",
+                                            "header": "Start",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "yearperiod_end",
+                                            "header": "End",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "yearperiod_closed",
+                                            "header": "Closed",
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v  ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "period",
+                            "title": "Periods",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n}",
+                                        "beforeedit": "function (e)\n{\n    if(e.field != 'period_name'){\n        return false;\n    }\n}",
+                                        "afteredit": "function (e)\n{\n    if(e.field != 'period_name' || e.originalValue == e.value){\n        return;\n    }\n    \n    if(e.record.data.period_id * 1 < 1){\n        Roo.MessageBox.alert('Error', 'Error occur on getting the period id');\n        return;\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/Period.php',\n        method : 'POST',\n        params : {\n            period_id : e.record.data.period_id,\n            period_name : e.record.data.period_name\n            \n        }, \n        success : function() {\n            _this.grid.ds.load({});\n        }\n    });\n}",
+                                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n\n    var di = this.colModel.getDataIndex(columnIndex);\n\n    if (di != 'period_closed' && di != 'period_freeze') {\n        return;\n    }\n\n    var rec = _this.grid.ds.getAt(rowIndex);\n    \n    if(rec.data.period_id * 1 < 1){\n        Roo.MessageBox.alert('Error', 'Error occur on getting the period id');\n        return;\n    }\n    \n    var action = rec.data[di] ? 'thaw' : 'freeze';\n    \n    if(di == 'period_closed'){\n        action = rec.data[di] ? 'open' : 'close';\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/Period.php',\n        timeout: 600000,\n        mask : 'Processing',\n        method : 'POST',\n        params : {\n            period_id : rec.data.period_id,\n            _action : action\n            \n        }, \n        success : function() {\n            _this.grid.ds.load({});\n        }\n    });    \n    \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "period_name",
+                                    "clicksToEdit": 2,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    _this.grid.ds.load({});\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "status",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "status",
+                                                    "triggerAction": "all",
+                                                    "value": "A",
+                                                    "valueField": "ftype",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ \n    [ 'O', \"Open\"],\n    [ 'C' , \"Closed\"],\n    [ 'A', \"All\"] \n]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n    var addPeriod = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Period.php',\n            timeout: 600000,\n            mask : 'Processing',\n            method : 'POST',\n            params : {\n                _addExtraYear : 1\n            }, \n            success : function() {\n                _this.wgrid.ds.load({});\n            }\n        });\n    }\n     \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to add extra year\" , function(r) {\n        if (r !='yes') {\n            return;\n        }\n        addPeriod();\n   })\n   \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Add Extra Year",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n    var list = []; \n    \n    \n    \n    _this.grid.ds.each(function (r) {\n        if (r.data.period_closed) {\n            return;\n        }\n    \n        if(r.data.transactions > 0 ){\n            return false;\n        }\n        list.push(r.data);\n\n    });\n    \n    if (!list.length) {\n       Roo.MessageBox.alert(\"Notice\", \"Nothing to close\");\n       return;\n    }\n    \n    var tl = list.length;\n    \n    var closeNext = function(){\n    \n        if (!list.length) {\n            Roo.MessageBox.hide();\n             _this.grid.ds.load({});\n             return;\n        }\n    \n        var item = list.shift();\n        \n        Roo.MessageBox.updateProgress(\n            (tl-list.length) / tl,\n            \"Closing \" + item.period_name\n              \n        );\n    \n        new Pman.Request({\n            url : baseURL + '/Roo/Period.php',\n            timeout: 900000,\n            //mask : 'Processing',\n            method : 'POST',\n            params : {\n                period_id : item.period_id,\n                _action:  'close' ,\n                _second_action : 'freeze'\n            }, \n            success : function() {\n                closeNext();\n//                _this.grid.ds.load({});\n            }\n        });\n    };\n     \n    \n     \n  \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure want to close the period where there are no transactions?\" , function(r) {\n        if (r !='yes') {\n            return;\n        }\n        Roo.MessageBox.progress( \"Closing periods\", \"Closing periods\");\n        closeNext();\n        \n   })\n   \n    \n     \n     \n    \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Close all empty months",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    options.params = options.params || {};\n    \n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!s || !s.data.yearperiod_id * 1 > 0){\n        Roo.MessageBox.alert('Error','Please select a year period');\n        this.removeAll();\n        return false;\n    }\n    \n    options.params._status = _this.status.getValue();\n    options.params.period_yearperiod_id = s.data.yearperiod_id;\n    options.params._with_transactions = 1;\n    \n\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'period_start', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Period.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'period_id',\n        'type': 'int'\n    },\n    {\n        'name': 'period_name',\n        'type': 'string'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "period_name",
+                                            "header": "Name",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) \n{ \n    return String.format('{0}', v ? v : ''); \n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowBlank": false,
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "period_start",
+                                            "header": "Start",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "period_end",
+                                            "header": "End",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "period_closed",
+                                            "header": "Closed",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v  ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "period_freeze",
+                                            "header": "Frozen",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v  ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "transactions",
+                                            "header": "Transactions",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) \n{ \n    return String.format('{0}', v ? v : ''); \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "007"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePeriods.js b/Pman.Tab.XtuplePeriods.js
new file mode 100644 (file)
index 0000000..e2b3786
--- /dev/null
@@ -0,0 +1,635 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePeriods = new Roo.XComponent({
+    part     :  ["Xtuple","Periods"],
+    order    : '007-Pman.Tab.XtuplePeriods',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleAccountsTab',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            fitContainer : true,
+            fitToFrame : true,
+            region : 'center',
+            title : "Periods",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.wpanel = this;
+                                if (_this.wgrid) {
+                                    _this.wgrid.ds.load({});
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'west',
+                        tableName : 'yearperiod',
+                        title : "Year Periods",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.wgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.wpanel.active) {
+                                       this.ds.load({});
+                                    }
+                                },
+                                rowclick : function (_self, rowIndex, e)
+                                {
+                                    _this.grid.ds.load({});
+                                },
+                                cellclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                
+                                    var di = this.colModel.getDataIndex(columnIndex);
+                                
+                                    if (di != 'yearperiod_closed') {
+                                        return;
+                                    }
+                                
+                                    var rec = this.ds.getAt(rowIndex);
+                                
+                                
+                                  var open = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/Yearperiod.php',
+                                            timeout: 600000,
+                                            mask : 'Processing',
+                                            method : 'POST',
+                                            params : {
+                                                yearperiod_id : rec.data.yearperiod_id,
+                                                _open : 1
+                                                
+                                            }, 
+                                            success : function() {
+                                                _this.wgrid.ds.load({});
+                                            }
+                                        });    
+                                    };
+                                    
+                                    var close = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/Yearperiod.php',
+                                            timeout: 600000,
+                                            mask : 'Processing',
+                                            method : 'POST',
+                                            params : {
+                                                yearperiod_id : rec.data.yearperiod_id,
+                                                _close : 1
+                                                
+                                            }, 
+                                            success : function() {
+                                                _this.wgrid.ds.load({});
+                                            }
+                                        });    
+                                    };
+                                    
+                                    if(rec.data.yearperiod_id * 1 < 1){
+                                        Roo.MessageBox.alert('Error', 'Please select a period?');
+                                        return;
+                                    }
+                                
+                                    //Roo.log(rec.data);
+                                    if(rec.data.yearperiod_closed *1){
+                                         Roo.MessageBox.confirm("Confirm", "Are you sure want to open this year period?" , function(r) {
+                                            if (r !='yes') {
+                                                return;
+                                            }
+                                            open();
+                                         
+                                          });
+                                         return;
+                                   }
+                                        
+                                    
+                                
+                                  
+                                     Roo.MessageBox.confirm("Confirm", "Are you sure want to close this year period?" , function(r) {
+                                        if (r !='yes') {
+                                            return;
+                                        }
+                                        close();
+                                        
+                                   })
+                                   
+                                    
+                                    
+                                    
+                                }
+                            },
+                            autoExpandColumn : 'yearperiod_start',
+                            loadMask : true,
+                            sm : {
+                                xtype: 'RowSelectionModel',
+                                xns: Roo.grid,
+                                singleSelect : true
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                remoteSort : true,
+                                sortInfo : { field : 'yearperiod_start', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Yearperiod.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'yearperiod_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'yearperiod_name',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'yearperiod_name',
+                                    header : 'Name',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    { 
+                                        v = r.data.yearperiod_start.getFullYear() + '-' + r.data.yearperiod_end.getFullYear();
+                                        
+                                        return String.format('{0}', v ? v : ''); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'yearperiod_start',
+                                    header : 'Start',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'yearperiod_end',
+                                    header : 'End',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'yearperiod_closed',
+                                    header : 'Closed',
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) {  
+                                        var state = v  ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'period',
+                        title : "Periods",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                },
+                                beforeedit : function (e)
+                                {
+                                    if(e.field != 'period_name'){
+                                        return false;
+                                    }
+                                },
+                                afteredit : function (e)
+                                {
+                                    if(e.field != 'period_name' || e.originalValue == e.value){
+                                        return;
+                                    }
+                                    
+                                    if(e.record.data.period_id * 1 < 1){
+                                        Roo.MessageBox.alert('Error', 'Error occur on getting the period id');
+                                        return;
+                                    }
+                                    
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Period.php',
+                                        method : 'POST',
+                                        params : {
+                                            period_id : e.record.data.period_id,
+                                            period_name : e.record.data.period_name
+                                            
+                                        }, 
+                                        success : function() {
+                                            _this.grid.ds.load({});
+                                        }
+                                    });
+                                },
+                                cellclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                
+                                    var di = this.colModel.getDataIndex(columnIndex);
+                                
+                                    if (di != 'period_closed' && di != 'period_freeze') {
+                                        return;
+                                    }
+                                
+                                    var rec = _this.grid.ds.getAt(rowIndex);
+                                    
+                                    if(rec.data.period_id * 1 < 1){
+                                        Roo.MessageBox.alert('Error', 'Error occur on getting the period id');
+                                        return;
+                                    }
+                                    
+                                    var action = rec.data[di] ? 'thaw' : 'freeze';
+                                    
+                                    if(di == 'period_closed'){
+                                        action = rec.data[di] ? 'open' : 'close';
+                                    }
+                                    
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Period.php',
+                                        timeout: 600000,
+                                        mask : 'Processing',
+                                        method : 'POST',
+                                        params : {
+                                            period_id : rec.data.period_id,
+                                            _action : action
+                                            
+                                        }, 
+                                        success : function() {
+                                            _this.grid.ds.load({});
+                                        }
+                                    });    
+                                    
+                                }
+                            },
+                            autoExpandColumn : 'period_name',
+                            clicksToEdit : 2,
+                            loadMask : true,
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.status = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                _this.grid.ds.load({});
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'status',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'status',
+                                        triggerAction : 'all',
+                                        value : "A",
+                                        valueField : 'ftype',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ 
+                                                [ 'O', "Open"],
+                                                [ 'C' , "Closed"],
+                                                [ 'A', "All"] 
+                                            ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                                var addPeriod = function(){
+                                                    new Pman.Request({
+                                                        url : baseURL + '/Roo/Period.php',
+                                                        timeout: 600000,
+                                                        mask : 'Processing',
+                                                        method : 'POST',
+                                                        params : {
+                                                            _addExtraYear : 1
+                                                        }, 
+                                                        success : function() {
+                                                            _this.wgrid.ds.load({});
+                                                        }
+                                                    });
+                                                }
+                                                 
+                                                Roo.MessageBox.confirm("Confirm", "Are you sure want to add extra year" , function(r) {
+                                                    if (r !='yes') {
+                                                        return;
+                                                    }
+                                                    addPeriod();
+                                               })
+                                               
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Add Extra Year",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                                var list = []; 
+                                                
+                                                
+                                                
+                                                _this.grid.ds.each(function (r) {
+                                                    if (r.data.period_closed) {
+                                                        return;
+                                                    }
+                                                
+                                                    if(r.data.transactions > 0 ){
+                                                        return false;
+                                                    }
+                                                    list.push(r.data);
+                                            
+                                                });
+                                                
+                                                if (!list.length) {
+                                                   Roo.MessageBox.alert("Notice", "Nothing to close");
+                                                   return;
+                                                }
+                                                
+                                                var tl = list.length;
+                                                
+                                                var closeNext = function(){
+                                                
+                                                    if (!list.length) {
+                                                        Roo.MessageBox.hide();
+                                                         _this.grid.ds.load({});
+                                                         return;
+                                                    }
+                                                
+                                                    var item = list.shift();
+                                                    
+                                                    Roo.MessageBox.updateProgress(
+                                                        (tl-list.length) / tl,
+                                                        "Closing " + item.period_name
+                                                          
+                                                    );
+                                                
+                                                    new Pman.Request({
+                                                        url : baseURL + '/Roo/Period.php',
+                                                        timeout: 900000,
+                                                        //mask : 'Processing',
+                                                        method : 'POST',
+                                                        params : {
+                                                            period_id : item.period_id,
+                                                            _action:  'close' ,
+                                                            _second_action : 'freeze'
+                                                        }, 
+                                                        success : function() {
+                                                            closeNext();
+                                            //                _this.grid.ds.load({});
+                                                        }
+                                                    });
+                                                };
+                                                 
+                                                
+                                                 
+                                              
+                                                Roo.MessageBox.confirm("Confirm", "Are you sure want to close the period where there are no transactions?" , function(r) {
+                                                    if (r !='yes') {
+                                                        return;
+                                                    }
+                                                    Roo.MessageBox.progress( "Closing periods", "Closing periods");
+                                                    closeNext();
+                                                    
+                                               })
+                                               
+                                                
+                                                 
+                                                 
+                                                
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Close all empty months",
+                                        icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                    }
+                                ]
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        options.params = options.params || {};
+                                        
+                                        var s = _this.wgrid.getSelectionModel().getSelected();
+                                        
+                                        if(!s || !s.data.yearperiod_id * 1 > 0){
+                                            Roo.MessageBox.alert('Error','Please select a year period');
+                                            this.removeAll();
+                                            return false;
+                                        }
+                                        
+                                        options.params._status = _this.status.getValue();
+                                        options.params.period_yearperiod_id = s.data.yearperiod_id;
+                                        options.params._with_transactions = 1;
+                                        
+                                    
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'period_start', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Period.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'period_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'period_name',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'period_name',
+                                    header : 'Name',
+                                    width : 100,
+                                    renderer : function(v) 
+                                    { 
+                                        return String.format('{0}', v ? v : ''); 
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form,
+                                            allowBlank : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'period_start',
+                                    header : 'Start',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'period_end',
+                                    header : 'End',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('Y-m-d') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'period_closed',
+                                    header : 'Closed',
+                                    width : 75,
+                                    renderer : function(v) {  
+                                        var state = v  ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'period_freeze',
+                                    header : 'Frozen',
+                                    width : 75,
+                                    renderer : function(v) {  
+                                        var state = v  ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'transactions',
+                                    header : 'Transactions',
+                                    width : 100,
+                                    renderer : function(v) 
+                                    { 
+                                        return String.format('{0}', v ? v : ''); 
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    tabPosition : 'top',
+                    title : "Periods",
+                    titlebar : false
+                },
+                west : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    tabPosition : 'top',
+                    title : "Year Periods",
+                    titlebar : false,
+                    width : 400
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePriceLists.bjs b/Pman.Tab.XtuplePriceLists.bjs
new file mode 100644 (file)
index 0000000..57db140
--- /dev/null
@@ -0,0 +1,176 @@
+{
+    "id": "roo-file-44",
+    "name": "Pman.Tab.XtuplePriceLists",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "Pman.Tab.XtuplePriceLists",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePriceLists.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "ipshead",
+            "title": "Price Lists",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    _this.dialog = Pman.Dialog.XtuplePriceList\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n    \n}\n"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "ipshead_descrip",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "*prop": "dataSource",
+                            "xtype": "Store",
+                            "remoteSort": true,
+                            "|sortInfo": "{ field : 'ipshead_name', direction: 'ASC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/ipshead.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'ipshead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'ipshead_name',\n        'type': 'string'\n    },\n    {\n        'name': 'ipshead_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'ipshead_effective',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'ipshead_expires',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'ipshead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'ipshead_updated',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'ipshead_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'ipshead_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'ipshead_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'ipshead_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'ipshead_curr_id_curr_abbr',\n        'type': 'string'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying ipshead{0} - {1} of {2}",
+                            "emptyMsg": "No ipshead found",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n   new Pman.Download({\n        method: 'GET',\n        url : baseURL + '/Roo/Ipsiteminfo',\n        params : {\n            _pricegrid : 1\n        }\n   });\n}"
+                                    },
+                                    "text": "Download Price Matrix",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Pricing'\n        \n       },\n       function (data) {\n            var msg = [];\n            if (data.deleted) {\n                msg.push(\"Deleted \" + data.deleted + \" Price(s)\");\n            }\n            if (data.updated) {\n                msg.push(\"Updated \" + data.updated + \" Price(s)\");\n            }            \n            if (data.inserted) {\n                msg.push(\"Added \" + data.inserted + \" Price(s)\");\n            }\n            if (!msg.length) {\n                msg.push(\"No data changed\");\n            }\n            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n}"
+                                    },
+                                    "text": "Upload Price Matrix",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "cls": "x-btn-text-icon",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "listeners": {
+                                        "|click": "function()\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( { id : 0 } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                    },
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "text": "Delete",
+                                    "cls": "x-btn-text-icon",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "xtype": "Button",
+                                    "listeners": {
+                                        "|click": "function()\n{\n     Pman.genericDelete(_this, 'ipshead'); \n}\n        "
+                                    },
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "ipshead_curr_id_curr_name",
+                            "header": "Ipshead curr",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "ipshead_name",
+                            "header": "Ipshead name",
+                            "sortable": true,
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            "header": "Ipshead descrip",
+                            "width": 200,
+                            "dataIndex": "ipshead_descrip",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            "header": "Ipshead effective",
+                            "width": 75,
+                            "dataIndex": "ipshead_effective",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "ipshead_expires",
+                            "header": "Ipshead expires",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            "header": "Ipshead updated",
+                            "width": 75,
+                            "dataIndex": "ipshead_updated",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePriceLists.js b/Pman.Tab.XtuplePriceLists.js
new file mode 100644 (file)
index 0000000..933e260
--- /dev/null
@@ -0,0 +1,281 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePriceLists = new Roo.XComponent({
+    part     :  ["Xtuple","PriceLists"],
+    order    : '001-Pman.Tab.XtuplePriceLists',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "Pman.Tab.XtuplePriceLists",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'ipshead',
+            title : "Price Lists",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        _this.dialog = Pman.Dialog.XtuplePriceList
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        if (!_this.dialog) return;
+                        _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                            _this.grid.footer.onClick('first');
+                        }); 
+                        
+                    }
+                },
+                autoExpandColumn : 'ipshead_descrip',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    remoteSort : true,
+                    sortInfo : { field : 'ipshead_name', direction: 'ASC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/ipshead.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'ipshead_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'ipshead_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'ipshead_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'ipshead_effective',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'ipshead_expires',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'ipshead_curr_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'ipshead_updated',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'ipshead_curr_id_curr_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'ipshead_curr_id_curr_base',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'ipshead_curr_id_curr_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'ipshead_curr_id_curr_symbol',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'ipshead_curr_id_curr_abbr',
+                                'type': 'string'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying ipshead{0} - {1} of {2}",
+                    emptyMsg : "No ipshead found"
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                   new Pman.Download({
+                                        method: 'GET',
+                                        url : baseURL + '/Roo/Ipsiteminfo',
+                                        params : {
+                                            _pricegrid : 1
+                                        }
+                                   });
+                                }
+                            },
+                            text : "Download Price Matrix"
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                   Pman.Dialog.Image.show(
+                                       {
+                                            _url : baseURL+'/Xtuple/Pricing'
+                                        
+                                       },
+                                       function (data) {
+                                            var msg = [];
+                                            if (data.deleted) {
+                                                msg.push("Deleted " + data.deleted + " Price(s)");
+                                            }
+                                            if (data.updated) {
+                                                msg.push("Updated " + data.updated + " Price(s)");
+                                            }            
+                                            if (data.inserted) {
+                                                msg.push("Added " + data.inserted + " Price(s)");
+                                            }
+                                            if (!msg.length) {
+                                                msg.push("No data changed");
+                                            }
+                                            Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                
+                                       }
+                                   );
+                                }
+                            },
+                            text : "Upload Price Matrix"
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            text : "Add",
+                            cls : 'x-btn-text-icon',
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif',
+                            listeners : {
+                                click : function()
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( { id : 0 } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            text : "Delete",
+                            cls : 'x-btn-text-icon',
+                            icon : rootURL + '/Pman/templates/images/trash.gif',
+                            listeners : {
+                                click : function()
+                                {
+                                     Pman.genericDelete(_this, 'ipshead'); 
+                                }
+                            }
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'ipshead_curr_id_curr_name',
+                        header : 'Ipshead curr',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'ipshead_name',
+                        header : 'Ipshead name',
+                        sortable : true,
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Ipshead descrip',
+                        width : 200,
+                        dataIndex : 'ipshead_descrip',
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Ipshead effective',
+                        width : 75,
+                        dataIndex : 'ipshead_effective',
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'ipshead_expires',
+                        header : 'Ipshead expires',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Ipshead updated',
+                        width : 75,
+                        dataIndex : 'ipshead_updated',
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePurchaseRecv.bjs b/Pman.Tab.XtuplePurchaseRecv.bjs
new file mode 100644 (file)
index 0000000..db11680
--- /dev/null
@@ -0,0 +1,663 @@
+{
+    "id": "roo-file-49",
+    "name": "Pman.Tab.XtuplePurchaseRecv",
+    "parent": "Pman.Tab.XtuplePurchases",
+    "title": "Pman.Tab.XtuplePurchaseRecv",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePurchaseRecv.bjs",
+    "items": [
+        {
+            "background": true,
+            "region": "center",
+            "title": "PO / Recieve Stock",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "east",
+                            "split": true,
+                            "width": 340,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.ppanel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "pohead",
+                            "title": "PO Receive Stock",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.ppanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    var r = _this.grid.ds.getAt(rowIndex);\n    \n    Pman.Dialog.XtuplePurchaseOrder.show( { pohead_id : r.data.pohead_id }, function() {\n        _this.grid.footer.onClick('refresh');\n    }); \n}\n",
+                                        "rowclick": "function (_self, rowIndex, e)\n{\n    _this.rggrid.ds.load({});\n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "pohead_vend_id_vend_name",
+                                    "loadMask": true,
+                                    "trackMouseOver": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "*prop": "sm",
+                                            "singleSelect": true,
+                                            "xtype": "RowSelectionModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    o.params._with_recv = 1;\n\n    \n    o.params['query[number]'] = _this.searchBox.getValue();\n    \n    // only filter by type if the number is empty..\n    if (!o.params['query[number]'].length) {\n        o.params.pohead_status = _this.status.getValue();\n    }\n    \n    \n}",
+                                                "load": "function (_self, records, options)\n{\n    \n    (function() { _this.rggrid.ds.load({}); }).defer(100);\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'pohead_orderdate', direction: 'DESC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|url": "baseURL + '/Roo/pohead.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'pohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_status',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_orderdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'pohead_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_printed',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_agent_username',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_saved',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_dropship',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendcity',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendstate',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendzipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendcountry',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shipto_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shiptoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptocity',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptostate',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptozipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptocountry',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_released',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'pohead_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_code',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_active',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_counttag_prefix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_counttag_number',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_bol_prefix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_bol_number',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_shipping',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_useslips',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_usezones',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_aislesize',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_aislealpha',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_racksize',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_rackalpha',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_binsize',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_binalpha',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_locationsize',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_locationalpha',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_enforcearbl',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_default_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_shipping_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_transit',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_shipform_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_shipvia_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_shipcomments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_costcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_costcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_sitetype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_warehous_id_warehous_sequence',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_code',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vendaddr_id_vendaddr_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_lastpurchdate',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_vend_id_vend_active',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_po',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_pocomments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_exported',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_fobsource',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_vendtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_qualified',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ediemail',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ediemailbody',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_edisubject',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_edifilename',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_accntnum',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_emailpodelivery',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_restrictpurch',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_edicc',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_cntct1_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_cntct2_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_match',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_enabled',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_accnttype',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_use_vendinfo',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_indiv_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_indiv_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ediemailhtml',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_routingnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'pohead_vend_id_vend_ach_accntnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'pohead_vend_id_vend_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_crmacct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_initials',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_active',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_phone2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_webaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_owner_username',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_vend_cntct_id_cntct_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_terms_id_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id_terms_code',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_terms_id_terms_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_terms_id_terms_type',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_terms_id_terms_duedays',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id_terms_discdays',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id_terms_discprcnt',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_terms_id_terms_cutoffday',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id_terms_ap',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_terms_id_terms_ar',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_taxzone_id_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_taxzone_id_taxzone_code',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_taxzone_id_taxzone_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_taxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_taxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_taxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_taxtype_id_taxtype_sys',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_active',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_line1',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_line2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_line3',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_city',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_state',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_postalcode',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_country',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shiptoddress_id_addr_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_crmacct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_initials',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_active',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_phone2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_webaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_owner_username',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_shipto_cntct_id_cntct_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_custponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_type',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_orderdate',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoname',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoaddress4',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptoaddress5',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_origin',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptocity',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptostate',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptozipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_misc',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_ordercomments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipcomments',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptophone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipchrg_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipform_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtoname',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtocity',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtostate',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtozipcode',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_misc_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_misc_accnt_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_miscdate',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_holdtype',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_packdate',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_prj_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_wasquote',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_lastupdated',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipcomplete',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_created',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_creator',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_quote_number',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billtocountry',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shiptocountry',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_calcfreight',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_shipto_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_honorific',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_first_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_middle',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_last_name',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_suffix',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_title',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_billto_cntct_email',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_ophead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_status',\n        'type': 'string'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_targetdate',\n        'type': 'date'\n    },\n    {\n        'name': 'pohead_cohead_id_cohead_location_src',\n        'type': 'int'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying pohead{0} - {1} of {2}",
+                                            "emptyMsg": "No pohead found",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "cm_status",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "cm_status_name",
+                                                    "triggerAction": "all",
+                                                    "value": "O",
+                                                    "valueField": "ftype",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ \n    [ 'O', \"Open\"],\n    [ 'C' , \"Closed\"],\n    [ 'U', \"Unreleased\"] \n]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "specialkey": "function (_self, e)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                                        "render": "function (_self)\n{\n    _this.searchBox = _self;\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\n    \n    \n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n\n   Pman.Dialog.XtuplePurchaseOrderNew.show( {} , function(v) {\n        Pman.Dialog.XtuplePurchaseOrder.show(v , function() {\n            _this.grid.footer.onClick('first');\n        });\n   }); \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Add",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n    var sel = _this.grid.selModel.getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row\");\n        return;\n    }\n    \n    var print = function(){\n        var params  =   {\n            template: 'Purchase-Order',\n            filename : 'Purchase-Order-' + sel.data.pohead_number + \n                '-' + (new Date()).format('Y-m-d'),\n            'param[0]':   \"pohead_id:number=\" + sel.data.pohead_id\n        };   \n        \n        new Pman.Download({\n          url : baseURL + '/Xtuple/Print',\n          \n          params :   params,\n          method : 'GET'\n        });\n        Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n    \n    }\n    \n    \n    if(!sel.data.pohead_printed){\n        new Pman.Request({\n            url : baseURL + '/Roo/pohead',\n            mask : 'Updating',\n            method : 'POST',\n            params : {\n                pohead_id : sel.data.pohead_id,\n                _print : 1\n            },\n            success : function() {\n                print();\n            }\n        });\n        \n        return;\n    }\n    \n    print();\n    \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Print",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/pdf.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Change Status",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var sel = _this.grid.selModel.getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row\");\n        return;\n    }\n    if (sel.data.pohead_status == 'C') {\n        Roo.MessageBox.alert(\"Error\", \"Purchase order is already closed\");\n        return;\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/pohead',\n        mask : 'Closing',\n        method : 'POST',\n        params : {\n            pohead_id : sel.data.pohead_id,\n            _close : 1\n        },\n        success : function() {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n       \n    \n}"
+                                                                    },
+                                                                    "text": "Close Selected",
+                                                                    "xtype": "Item",
+                                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var sel = _this.grid.selModel.getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row\");\n        return;\n    }\n    if (sel.data.pohead_status != 'O') {\n        Roo.MessageBox.alert(\"Error\", \"Purchase order is not Open\");\n        return;\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/pohead',\n        mask : 'Unreleasing',\n        method : 'POST',\n        params : {\n            pohead_id : sel.data.pohead_id,\n            _unrelease : 1\n        },\n        success : function() {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n       \n    \n}"
+                                                                    },
+                                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                                    "text": "Unrelease Selected",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var sel = _this.grid.selModel.getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row\");\n        return;\n    }\n    if (sel.data.pohead_status == 'O') {\n        Roo.MessageBox.alert(\"Error\", \"Purchase order is already Open\");\n        return;\n    }\n    \n    new Pman.Request({\n        url : baseURL + '/Roo/pohead',\n        mask : 'Reopening',\n        method : 'POST',\n        params : {\n            pohead_id : sel.data.pohead_id,\n            _reopen : 1\n        },\n        success : function() {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n       \n    \n}"
+                                                                    },
+                                                                    "text": "Reopen",
+                                                                    "xtype": "Item",
+                                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Reports",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "menu",
+                                                            "xtype": "Menu",
+                                                            "|xns": "Roo.menu",
+                                                            "items": [
+                                                                {
+                                                                    "text": "AP Aging Report",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var dt = (new Date()).format('Y-m-d');\n    \n    var params = {\n        '_group' : 'apAging',\n        '_name' : 'bydate',\n        'limit' : 99999,\n        'relDate:text' : dt,\n        'useDocDate:text' : 'TRUE',\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n    var s = _this.grid.getSelectionModel().getSelected();\n    \n    if(s){\n        if(s.data.pohead_vend_id > 0){\n            params['vend_id:number'] = s.data.pohead_vend_id;\n        }\n    }\n    \n    new Pman.Download({\r\n      url : baseURL + '/Roo/Metasql',\r\n      params :   params,\r\n      method : 'GET'\r\n    });\r\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\r\n    \r\n}"
+                                                                                    },
+                                                                                    "text": "as Excel",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n \n    var params  =   {\n        template: 'APAging',\n        filename : 'ARAging-' + (new Date()).format('Y-m-d'),\n        'param[0]':   \"relDate:string='\" + (new Date()).format('Y-m-d') + \"'\",\n        'param[1]':   \"useDocDate:number=1\"\n    };\n    \n    var s = _this.grid.getSelectionModel().getSelected();\n    \n    if(s){\n        if(s.data.pohead_vend_id > 0){\n            params['param[2]'] = 'vend_id:number=' + s.data.pohead_vend_id;\n        }\n    }\n    \n    new Pman.Download({\n      url : baseURL + '/Xtuple/Print',\n      params :   params,\n      method : 'GET'\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as PDF",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "pohead_number",
+                                            "header": "No#",
+                                            "sortable": true,
+                                            "width": 150,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n    var vv =v;\n    var nn  = '';\n    if (vv.indexOf(',') > -1) {\n        vv = vv.split(',').shift();\n    \n    }\n    if (vv.match(/^NSPO-/)) {\n        vv = vv.replace(/^NSPO-/, '');\n        nn = 'ns:&nbsp;';\n    }\n    \n    return String.format('<i>'+ nn +'</i><b qtip=\"{1}\">{0}</b> {2}', vv,v, r.data.pohead_comments ); \n     \n     \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "pohead_orderdate",
+                                            "header": "Ordered",
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "pohead_vend_id_vend_name",
+                                            "header": "Vendor",
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "pohead_curr_id_curr_abbr",
+                                            "header": "Currency",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "pohead_val",
+                                            "header": "PO value",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "landed_cost",
+                                            "header": "Landed",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if (r.data.landed_missing * 1) {\n            return v ? ('<b style=\"color:red\">' + Roo.util.Format.usMoney( v) + '</b>') : ''; \n    }\n\n    return v ? Roo.util.Format.usMoney( v) : ''; \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "pohead_qty",
+                                            "header": "Order Qty",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? (1*v).toFixed(0) : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "pohead_qty_in_transit",
+                                            "header": "In Transit",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n     var vv = v - (1*r.data.pohead_qty_transfered_unposted) -\n         (1*r.data.pohead_qty_transfered) ;\n     return String.format('{0}',vv ? (1*vv).toFixed(0) : ''); \n     \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "pohead_qty_recv",
+                                            "header": "Recieved",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n   \n    // total recieved = recv + recv_transfered - intransit?\n    \n    // old style = 0 in transit\n    // all delivered direct to warehouse\n    // 0 in \n    \n    // new style = 100 in transit\n    // it will record 100 in transit, and 100 recieved\n    // and \n    \n    // recv 610,unposted = 0 , transfer 610, in transit 610\n   \n     var recv = (1*r.data.pohead_qty_recv) +\n           (1*r.data.pohead_qty_transfered_unposted) +\n             (1*r.data.pohead_qty_transfered) - \n             (1*r.data.pohead_qty_in_transit) ;\n                         \n    \n    if(r.data.pohead_qty_transfered_unposted * 1 > 0){\n        return String.format('<b style=\"color:red\" qtip=\"{1} are Unposted\">{0}</b>', recv ? (1*recv).toFixed(0) : '',\n        r.data.pohead_qty_transfered_unposted); \n    }\n    \n    var format = '{0}';\n    if(recv != r.data.pohead_qty){\n        format = '<span style=\"color:red\">{0}</span>';\n    }\n    \n    return String.format(format, recv ? (1*recv).toFixed(0) : '');\n     \n }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToFrame": true,
+                            "region": "east",
+                            "xtype": "NestedLayoutPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "BorderLayout",
+                                    "*prop": "layout",
+                                    "items": [
+                                        {
+                                            "*prop": "center",
+                                            "title": "Item Receipts",
+                                            "titlebar": true,
+                                            "xtype": "LayoutRegion",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "south",
+                                            "height": 450,
+                                            "split": true,
+                                            "title": "Items",
+                                            "xtype": "LayoutRegion",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|activate": "function() {\n    _this.rgpanel = this;\n    if (_this.rggrid) {\n        //_this.rggrid.ds.load({});\n    }\n}"
+                                            },
+                                            "background": true,
+                                            "fitContainer": true,
+                                            "fitToframe": true,
+                                            "region": "center",
+                                            "tableName": "recvgrp",
+                                            "title": "recvgrp",
+                                            "xtype": "GridPanel",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|render": "function() \n{\n    _this.rggrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.rgpanel.active) {\n       //this.ds.load({});\n    }\n}",
+                                                        "rowdblclick": "function (_self, rowIndex, e)\n{\n     var s  = _this.rggrid.ds.getAt(rowIndex);\n     \n    Pman.Dialog.XtupleRecvGrp.show( {\n         recvgrp_id : s.data.recvgrp_id\n         \n     } , function() {\n        _this.grid.footer.onClick('refresh');\n   }); \n}\n",
+                                                        "rowclick": "function (_self, rowIndex, e)\n{\n    (function() { _this.rgrid.footer.onClick('first');}).defer(100);\n}"
+                                                    },
+                                                    "*prop": "grid",
+                                                    "autoExpandColumn": "recvgrp_number",
+                                                    "loadMask": true,
+                                                    "xtype": "Grid",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeload": "function (_self, options)\n{\n    if (!_this.grid || !_this.grid.selModel.getSelected()) {\n         this.removeAll();\n         if (_this.rgrid) {\n            _this.rgrid.ds.removeAll();\n        }\n        return false;\n    }\n    var r = _this.grid.selModel.getSelected();\n    options.params = options.params || {};\n    options.params.recvgrp_pohead_id = _this.grid.selModel.getSelected().data.pohead_id;\n    \n}",
+                                                                "load": "function (_self, records, options)\n{\n    _this.rgrid.footer.onClick('first');\n}"
+                                                            },
+                                                            "*prop": "dataSource",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ field : 'recvgrp_id', direction: 'ASC' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/recvgrp.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.data",
+                                                                    "xtype": "JsonReader",
+                                                                    "totalProperty": "total",
+                                                                    "root": "data",
+                                                                    "*prop": "reader",
+                                                                    "id": "id",
+                                                                    "|fields": "[\n    {\n        'name': 'recv_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_order_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_order_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_orderitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_agent_username',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_purchcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_recvcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_recvcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_freight_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_date',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_invoiced',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_trans_usr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_gldistdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_splitfrom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_rlsd_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_poitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_close',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_pohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_docdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_distdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_reference',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_adjtaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_freighttaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_gldistdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_misc',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_lastpurchdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vend_id_vend_active',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_po',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_pocomments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_exported',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_fobsource',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_vendtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_qualified',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemail',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemailbody',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_edisubject',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_edifilename',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_accntnum',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_emailpodelivery',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_restrictpurch',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_edicc',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_cntct1_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_cntct2_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_match',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_enabled',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_accnttype',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_use_vendinfo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_indiv_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_indiv_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemailhtml',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_routingnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_accntnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'recv_vend_id_vend_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_order_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_order_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_orderitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_agent_username',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_purchcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_purchcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_recvcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_recvcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_freight_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_date',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_invoiced',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_trans_usr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_gldistdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_splitfrom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_rlsd_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_qtyonhand',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_reorderlevel',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordertoqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_cyclecountfreq',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_datelastcount',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_datelastused',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_loccntrl',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_safetystock',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_minordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_multordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_leadtime',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_abcclass',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_issuemethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_controlmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_active',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_plancode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_costcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_eventfence',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_sold',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_stocked',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_freeze',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_useparams',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_useparamsmanual',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_soldranking',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createpr',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_perishable',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_nnqoh',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_autoabcclass',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordergroup',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_disallowblankwip',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_maxordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_mps_timefence',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createwo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_warrpurc',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_autoreg',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordergroup_first',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_supply_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_planning_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_wosupply',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_posupply',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_lsseq_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_cosdefault',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createsopr',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createsopo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_dropship',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_abbr',\n        'type': 'string'\n    }\n]"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "toolbar",
+                                                            "xtype": "Toolbar",
+                                                            "|xns": "Roo",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    \n   var sel =  _this.rggrid.selModel.getSelected();\n   if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select Item receipt\");\n        return;\n    }\n    \n    \n    \n    Pman.Dialog.XtupleTransfer.show({ createFromRev : sel.data.recvgrp_id },\n        function() {\n            _this.grid.ds.load({});\n        }\n        );\n}"
+                                                                    },
+                                                                    "cls": "x-btn-text-icon",
+                                                                    "hidden": true,
+                                                                    "text": "Create Transfer",
+                                                                    "xtype": "Button",
+                                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                    "|xns": "Roo.Toolbar"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.Toolbar",
+                                                                    "xtype": "Fill"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "|click": "function()\n{\n     var s  = _this.grid.selModel.getSelected();\n     if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a purchase order\");\n        return\n    }\n    Pman.Dialog.XtupleRecvGrp.show( {\n         recvgrp_pohead_id : s.data.pohead_id ,\n         recvgrp_pohead_id_pohead_number : s.data.pohead_number\n     } , function() {\n        _this.grid.footer.onClick('refresh');\n   }); \n}\n"
+                                                                    },
+                                                                    "cls": "x-btn-text-icon",
+                                                                    "text": "Add Receipt",
+                                                                    "xtype": "Button",
+                                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                                    "|xns": "Roo.Toolbar"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "recvgrp_number",
+                                                            "header": "ref#",
+                                                            "width": 120,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n    var vv =v;\n    var nn  = '';\n    if (vv.indexOf(',') > -1) {\n        vv = vv.split(',').shift();\n    \n    }\n    if (vv.match(/^NSPO-/)) {\n        vv = vv.replace(/^NSPO-/, '');\n        nn = 'ns:&nbsp;';\n    }\n    \n    var format = '<i>'+ nn +'</i><b qtip=\"{1}\">{0}</b>';\n    if (r.data.recvgrp_void *1) {\n        format = '<s>'  + format + '</s>';\n    }\n    return String.format(format, vv,v); \n     \n     \n }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "recvgrp_location_id_location_name",
+                                                            "header": "To",
+                                                            "width": 80,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n     \n    return String.format('{0}',  v); \n     \n     \n }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "recvgrp_date",
+                                                            "header": "Date",
+                                                            "width": 75,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return v ? v.format('d/M/Y')  : ''; }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "total_landed_cost",
+                                                            "header": "Landed Cost",
+                                                            "width": 80,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) { \n    return String.format('{1}{0}', v, r.data.base_curr_symbol); \n}",
+                                                            "|xns": "Roo.grid"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|activate": "function() {\n    _this.rpanel = this;\n    if (_this.rgrid) {\n        _this.rgrid.footer.onClick('first');\n    }\n}"
+                                            },
+                                            "background": true,
+                                            "fitContainer": true,
+                                            "fitToframe": false,
+                                            "region": "south",
+                                            "tableName": "poitem",
+                                            "title": "Items",
+                                            "xtype": "GridPanel",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|render": "function() \n{\n    _this.rgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.rpanel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                                                    },
+                                                    "*prop": "grid",
+                                                    "autoExpandColumn": "item_number",
+                                                    "loadMask": true,
+                                                    "xtype": "Grid",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeload": "function (_self, options)\n{\n    if (!_this.grid || !_this.grid.selModel.getSelected()) {\n        return false;\n    }\n    var r = _this.grid.selModel.getSelected();\n    options.params.poitem_pohead_id = _this.grid.selModel.getSelected().data.pohead_id;\n    var rr = _this.rggrid.selModel.getSelected();\n\n    options.params.recvgrp_id = 0;\n    if (rr) {\n        options.params.recvgrp_id = rr.data.recvgrp_id;\n    }\n    \n    options.params._with_item  = 1;\n        options.params.item_type = 'P';\n}"
+                                                            },
+                                                            "*prop": "dataSource",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ field : 'recv_order_type', direction: 'ASC' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/poitem.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.data",
+                                                                    "xtype": "JsonReader",
+                                                                    "totalProperty": "total",
+                                                                    "root": "data",
+                                                                    "*prop": "reader",
+                                                                    "id": "id",
+                                                                    "|fields": "[\n    {\n        'name': 'recv_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_order_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_order_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_orderitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_agent_username',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_purchcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_recvcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_recvcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_freight_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_date',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_invoiced',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_trans_usr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_gldistdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_splitfrom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_rlsd_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_poitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_close',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_voitem_id_voitem_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_pohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_amount',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_docdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_distdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_reference',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_adjtaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_freighttaxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_gldistdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_misc',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vohead_id_vohead_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_lastpurchdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_vend_id_vend_active',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_po',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_pocomments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_1099',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_exported',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_fobsource',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_fob',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_terms_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_vendtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_qualified',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemail',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemailbody',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_edisubject',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_edifilename',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_accntnum',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_emailpodelivery',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_restrictpurch',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_edicc',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_cntct1_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_cntct2_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_addr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_match',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_enabled',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_accnttype',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_use_vendinfo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_indiv_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_indiv_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_vend_id_vend_ediemailhtml',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_routingnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'recv_vend_id_vend_ach_accntnumber',\n        'type': 'text'\n    },\n    {\n        'name': 'recv_vend_id_vend_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_order_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_order_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_orderitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_agent_username',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_item_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vend_uom',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_purchcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_purchcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_recvcost',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_recvcost_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_freight',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_freight_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_date',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_invoiced',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_vohead_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_voitem_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_trans_usr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_gldistdate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_splitfrom_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_splitfrom_id_recv_rlsd_duedate',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_recvcost_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_purchcost_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_item_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_qtyonhand',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_reorderlevel',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordertoqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_cyclecountfreq',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_datelastcount',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_datelastused',\n        'type': 'date'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_loccntrl',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_safetystock',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_minordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_multordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_leadtime',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_abcclass',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_issuemethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_controlmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_active',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_plancode_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_costcat_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_eventfence',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_sold',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_stocked',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_freeze',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_useparams',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_useparamsmanual',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_soldranking',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createpr',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_location_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_perishable',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_nnqoh',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_autoabcclass',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordergroup',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_disallowblankwip',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_maxordqty',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_mps_timefence',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createwo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_warrpurc',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_autoreg',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_value',\n        'type': 'float'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_ordergroup_first',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_supply_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_planning_type',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_wosupply',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_posupply',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_lsseq_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_cosdefault',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createsopr',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_createsopo',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_itemsite_id_itemsite_dropship',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'recv_freight_curr_id_curr_abbr',\n        'type': 'string'\n    }\n]"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "footer",
+                                                            "displayInfo": true,
+                                                            "displayMsg": " ",
+                                                            "emptyMsg": "No recv found",
+                                                            "pageSize": 100,
+                                                            "xtype": "PagingToolbar",
+                                                            "|xns": "Roo"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "item_number",
+                                                            "header": "Item",
+                                                            "width": 75,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "poitem_qty_ordered",
+                                                            "header": "Ordered",
+                                                            "width": 60,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "r.data.poitem_qty_received",
+                                                            "header": "Outstanding",
+                                                            "width": 60,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n\n\n    var  d = r.data.poitem_qty_ordered - ( r.data.poitem_qty_received - r.data.poitem_qty_returned);\n\n    if (!d) {\n        return '';\n    }\n    return String.format('<b style=\"color:red\">{0}</b>', d); \n }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "recv_qty_in_transit",
+                                                            "header": "In Transit",
+                                                            "width": 60,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n    // recv_qty\n    // this should show in transit.. (only applicable to \n    //var rr = _this.rggrid.selModel.getSelected();\n        //if (rr) {\n            //return '';\n    //    }\n    \n    // in transit = recieved, but not transfered.\n    if ((v*1) == 0.0) {\n        return '';\n    }\n    return String.format('{0}',  (v*1).toFixed(0)); \n/*\n        // no reciept selected..\n    d = r.data.poitem_qty_received - r.data.poitem_qty_returned ;\n    d -= (r.data.poitem_qty_transfered_unposted*1 + r.data.poitem_qty_transfered*1) ;\n\n    if (!d) {\n        return '';\n    }\n    return String.format('{0}',  d); \n    */\n }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "align": "right",
+                                                            "dataIndex": "recv_qty",
+                                                            "header": "Recieved",
+                                                            "width": 60,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n\n    var d = parseInt(v);;\n    var rr = _this.rggrid.selModel.getSelected();\n    if (!rr) {\n        // show summary\n        //d = r.data.poitem_qty_received - r.data.poitem_qty_returned;\n        // real recived amount = the total that has been transfered out \n       \n       \n       \n       //d =  (r.data.poitem_qty_transfered_unposted*1 + r.data.poitem_qty_transfered*1) ;\n        //var tot_rec =  r.data.poitem_qty_received - r.data.poitem_qty_returned;\n        //if (d < tot_rec) {\n        //    return String.format('<b style=\"color:red\">{0}</b>',  d); \n        //}\n\n        //return String.format('{0}',  d); \n        \n        \n    } \n     \n\n    if (!d) {\n        return '';\n    }\n    if (rr && rr.data.recvgrp_void *1 ) {\n            return String.format('<s>{0}</s>',  d); \n    \n    }\n\n    \n    \n    return String.format('{0}',  d); \n }",
+                                                            "|xns": "Roo.grid"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePurchaseRecv.js b/Pman.Tab.XtuplePurchaseRecv.js
new file mode 100644 (file)
index 0000000..d82fc6b
--- /dev/null
@@ -0,0 +1,3815 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePurchaseRecv = new Roo.XComponent({
+    part     :  ["Xtuple","PurchaseRecv"],
+    order    : '001-Pman.Tab.XtuplePurchaseRecv',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtuplePurchases',
+    name     : "Pman.Tab.XtuplePurchaseRecv",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            region : 'center',
+            title : "PO / Recieve Stock",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.ppanel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'pohead',
+                        title : "PO Receive Stock",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.ppanel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    var r = _this.grid.ds.getAt(rowIndex);
+                                    
+                                    Pman.Dialog.XtuplePurchaseOrder.show( { pohead_id : r.data.pohead_id }, function() {
+                                        _this.grid.footer.onClick('refresh');
+                                    }); 
+                                },
+                                rowclick : function (_self, rowIndex, e)
+                                {
+                                    _this.rggrid.ds.load({});
+                                }
+                            },
+                            autoExpandColumn : 'pohead_vend_id_vend_name',
+                            loadMask : true,
+                            trackMouseOver : true,
+                            sm : {
+                                xtype: 'RowSelectionModel',
+                                xns: Roo.grid,
+                                singleSelect : true
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        o.params._with_recv = 1;
+                                    
+                                        
+                                        o.params['query[number]'] = _this.searchBox.getValue();
+                                        
+                                        // only filter by type if the number is empty..
+                                        if (!o.params['query[number]'].length) {
+                                            o.params.pohead_status = _this.status.getValue();
+                                        }
+                                        
+                                        
+                                    },
+                                    load : function (_self, records, options)
+                                    {
+                                        
+                                        (function() { _this.rggrid.ds.load({}); }).defer(100);
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'pohead_orderdate', direction: 'DESC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/pohead.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'pohead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_status',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_orderdate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_fob',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipvia',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_comments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_freight',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_printed',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_agent_username',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_saved',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_taxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_dropship',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddress1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddress2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddress3',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendcity',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendstate',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendzipcode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendcountry',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoaddress1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoaddress2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoaddress3',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptocity',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptostate',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptozipcode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptocountry',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_released',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id_curr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id_curr_base',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id_curr_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id_curr_symbol',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_curr_id_curr_abbr',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_fob',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_counttag_prefix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_counttag_number',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_bol_prefix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_bol_number',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_shipping',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_useslips',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_usezones',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_aislesize',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_aislealpha',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_racksize',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_rackalpha',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_binsize',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_binalpha',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_locationsize',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_locationalpha',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_enforcearbl',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_default_accnt_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_shipping_commission',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_transit',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_shipform_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_shipvia_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_shipcomments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_costcat_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_costcat_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_sitetype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_warehous_id_warehous_sequence',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_vend_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_comments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vendaddr_id_vendaddr_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_lastpurchdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_po',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_comments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_pocomments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_1099',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_exported',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_fobsource',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_fob',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_terms_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_shipvia',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_vendtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_qualified',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ediemail',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ediemailbody',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_edisubject',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_edifilename',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_accntnum',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_emailpodelivery',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_restrictpurch',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_edicc',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_curr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_cntct1_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_cntct2_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_match',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_enabled',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_accnttype',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_use_vendinfo',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_indiv_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_indiv_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ediemailhtml',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_routingnumber',
+                                            'type': 'text'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_ach_accntnumber',
+                                            'type': 'text'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_id_vend_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_crmacct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_initials',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_phone2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_webaddr',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_notes',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_owner_username',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_vend_cntct_id_cntct_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_duedays',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_discdays',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_discprcnt',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_cutoffday',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_ap',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_terms_id_terms_ar',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_taxzone_id_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_taxzone_id_taxzone_code',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_taxzone_id_taxzone_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_taxtype_id_taxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_taxtype_id_taxtype_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_taxtype_id_taxtype_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_taxtype_id_taxtype_sys',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_line1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_line2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_line3',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_city',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_state',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_postalcode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_country',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_notes',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shiptoddress_id_addr_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_crmacct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_addr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_initials',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_phone2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_webaddr',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_notes',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_owner_username',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_shipto_cntct_id_cntct_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_cust_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_custponumber',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_orderdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_warehous_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoname',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoaddress1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoaddress2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoaddress3',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoaddress4',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptoaddress5',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_salesrep_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_terms_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_origin',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_fob',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipvia',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptocity',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptostate',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptozipcode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_freight',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_misc',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_imported',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_ordercomments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipcomments',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptophone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipchrg_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipform_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtoname',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtoaddress1',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtoaddress2',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtoaddress3',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtocity',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtostate',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtozipcode',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_misc_accnt_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_misc_accnt_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_misc_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_commission',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_miscdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_holdtype',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_packdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_prj_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_wasquote',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_lastupdated',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipcomplete',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_created',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_creator',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_quote_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billtocountry',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shiptocountry',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_curr_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_calcfreight',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_shipto_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_honorific',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_first_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_middle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_last_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_suffix',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_title',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_billto_cntct_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_taxzone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_taxtype_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_ophead_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_status',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_targetdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'pohead_cohead_id_cohead_location_src',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying pohead{0} - {1} of {2}",
+                                emptyMsg : "No pohead found"
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.status = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                Roo.log('select');
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'cm_status',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'cm_status_name',
+                                        triggerAction : 'all',
+                                        value : "O",
+                                        valueField : 'ftype',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ 
+                                                [ 'O', "Open"],
+                                                [ 'C' , "Closed"],
+                                                [ 'U', "Unreleased"] 
+                                            ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            specialkey : function (_self, e)
+                                            {
+                                              _this.grid.footer.onClick('first');
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.searchBox = _self;
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.searchBox.setValue('');
+                                                
+                                                
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                            
+                                               Pman.Dialog.XtuplePurchaseOrderNew.show( {} , function(v) {
+                                                    Pman.Dialog.XtuplePurchaseOrder.show(v , function() {
+                                                        _this.grid.footer.onClick('first');
+                                                    });
+                                               }); 
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Add",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var sel = _this.grid.selModel.getSelected();
+                                                if (!sel) {
+                                                    Roo.MessageBox.alert("Error", "Select a row");
+                                                    return;
+                                                }
+                                                
+                                                var print = function(){
+                                                    var params  =   {
+                                                        template: 'Purchase-Order',
+                                                        filename : 'Purchase-Order-' + sel.data.pohead_number + 
+                                                            '-' + (new Date()).format('Y-m-d'),
+                                                        'param[0]':   "pohead_id:number=" + sel.data.pohead_id
+                                                    };   
+                                                    
+                                                    new Pman.Download({
+                                                      url : baseURL + '/Xtuple/Print',
+                                                      
+                                                      params :   params,
+                                                      method : 'GET'
+                                                    });
+                                                    Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                
+                                                }
+                                                
+                                                
+                                                if(!sel.data.pohead_printed){
+                                                    new Pman.Request({
+                                                        url : baseURL + '/Roo/pohead',
+                                                        mask : 'Updating',
+                                                        method : 'POST',
+                                                        params : {
+                                                            pohead_id : sel.data.pohead_id,
+                                                            _print : 1
+                                                        },
+                                                        success : function() {
+                                                            print();
+                                                        }
+                                                    });
+                                                    
+                                                    return;
+                                                }
+                                                
+                                                print();
+                                                
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Print",
+                                        icon : rootURL + '/Pman/templates/images/pdf.gif'
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        cls : 'x-btn-text-icon',
+                                        text : "Change Status",
+                                        icon : Roo.rootURL + 'images/default/tree/leaf.gif',
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var sel = _this.grid.selModel.getSelected();
+                                                            if (!sel) {
+                                                                Roo.MessageBox.alert("Error", "Select a row");
+                                                                return;
+                                                            }
+                                                            if (sel.data.pohead_status == 'C') {
+                                                                Roo.MessageBox.alert("Error", "Purchase order is already closed");
+                                                                return;
+                                                            }
+                                                            
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead',
+                                                                mask : 'Closing',
+                                                                method : 'POST',
+                                                                params : {
+                                                                    pohead_id : sel.data.pohead_id,
+                                                                    _close : 1
+                                                                },
+                                                                success : function() {
+                                                                    _this.grid.footer.onClick('refresh');
+                                                                }
+                                                            });
+                                                               
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Close Selected",
+                                                    icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var sel = _this.grid.selModel.getSelected();
+                                                            if (!sel) {
+                                                                Roo.MessageBox.alert("Error", "Select a row");
+                                                                return;
+                                                            }
+                                                            if (sel.data.pohead_status != 'O') {
+                                                                Roo.MessageBox.alert("Error", "Purchase order is not Open");
+                                                                return;
+                                                            }
+                                                            
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead',
+                                                                mask : 'Unreleasing',
+                                                                method : 'POST',
+                                                                params : {
+                                                                    pohead_id : sel.data.pohead_id,
+                                                                    _unrelease : 1
+                                                                },
+                                                                success : function() {
+                                                                    _this.grid.footer.onClick('refresh');
+                                                                }
+                                                            });
+                                                               
+                                                            
+                                                        }
+                                                    },
+                                                    icon : Roo.rootURL + 'images/default/tree/leaf.gif',
+                                                    text : "Unrelease Selected"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var sel = _this.grid.selModel.getSelected();
+                                                            if (!sel) {
+                                                                Roo.MessageBox.alert("Error", "Select a row");
+                                                                return;
+                                                            }
+                                                            if (sel.data.pohead_status == 'O') {
+                                                                Roo.MessageBox.alert("Error", "Purchase order is already Open");
+                                                                return;
+                                                            }
+                                                            
+                                                            new Pman.Request({
+                                                                url : baseURL + '/Roo/pohead',
+                                                                mask : 'Reopening',
+                                                                method : 'POST',
+                                                                params : {
+                                                                    pohead_id : sel.data.pohead_id,
+                                                                    _reopen : 1
+                                                                },
+                                                                success : function() {
+                                                                    _this.grid.footer.onClick('refresh');
+                                                                }
+                                                            });
+                                                               
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Reopen",
+                                                    icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        cls : 'x-btn-text-icon',
+                                        text : "Reports",
+                                        icon : rootURL + '/Pman/templates/images/spreadsheet.gif',
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "AP Aging Report",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var dt = (new Date()).format('Y-m-d');
+                                                                        
+                                                                        var params = {
+                                                                            '_group' : 'apAging',
+                                                                            '_name' : 'bydate',
+                                                                            'limit' : 99999,
+                                                                            'relDate:text' : dt,
+                                                                            'useDocDate:text' : 'TRUE',
+                                                                            'csvTitles' : '*',
+                                                                            'csvCols' : '*'
+                                                                        };
+                                                                        var s = _this.grid.getSelectionModel().getSelected();
+                                                                        
+                                                                        if(s){
+                                                                            if(s.data.pohead_vend_id > 0){
+                                                                                params['vend_id:number'] = s.data.pohead_vend_id;
+                                                                            }
+                                                                        }
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Roo/Metasql',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                        
+                                                                    }
+                                                                },
+                                                                text : "as Excel"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                     
+                                                                        var params  =   {
+                                                                            template: 'APAging',
+                                                                            filename : 'ARAging-' + (new Date()).format('Y-m-d'),
+                                                                            'param[0]':   "relDate:string='" + (new Date()).format('Y-m-d') + "'",
+                                                                            'param[1]':   "useDocDate:number=1"
+                                                                        };
+                                                                        
+                                                                        var s = _this.grid.getSelectionModel().getSelected();
+                                                                        
+                                                                        if(s){
+                                                                            if(s.data.pohead_vend_id > 0){
+                                                                                params['param[2]'] = 'vend_id:number=' + s.data.pohead_vend_id;
+                                                                            }
+                                                                        }
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Xtuple/Print',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as PDF"
+                                                            }
+                                                        ]
+                                                    }
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'pohead_number',
+                                    header : 'No#',
+                                    sortable : true,
+                                    width : 150,
+                                    renderer : function(v,x,r) {
+                                        var vv =v;
+                                        var nn  = '';
+                                        if (vv.indexOf(',') > -1) {
+                                            vv = vv.split(',').shift();
+                                        
+                                        }
+                                        if (vv.match(/^NSPO-/)) {
+                                            vv = vv.replace(/^NSPO-/, '');
+                                            nn = 'ns:&nbsp;';
+                                        }
+                                        
+                                        return String.format('<i>'+ nn +'</i><b qtip="{1}">{0}</b> {2}', vv,v, r.data.pohead_comments ); 
+                                         
+                                         
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'pohead_orderdate',
+                                    header : 'Ordered',
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'pohead_vend_id_vend_name',
+                                    header : 'Vendor',
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'pohead_curr_id_curr_abbr',
+                                    header : 'Currency',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'pohead_val',
+                                    header : 'PO value',
+                                    width : 75,
+                                    renderer : function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'landed_cost',
+                                    header : 'Landed',
+                                    width : 75,
+                                    renderer : function(v,x,r) { 
+                                        if (r.data.landed_missing * 1) {
+                                                return v ? ('<b style="color:red">' + Roo.util.Format.usMoney( v) + '</b>') : ''; 
+                                        }
+                                    
+                                        return v ? Roo.util.Format.usMoney( v) : ''; 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'pohead_qty',
+                                    header : 'Order Qty',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? (1*v).toFixed(0) : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'pohead_qty_in_transit',
+                                    header : 'In Transit',
+                                    width : 75,
+                                    renderer : function(v,x,r) {
+                                         var vv = v - (1*r.data.pohead_qty_transfered_unposted) -
+                                             (1*r.data.pohead_qty_transfered) ;
+                                         return String.format('{0}',vv ? (1*vv).toFixed(0) : ''); 
+                                         
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'pohead_qty_recv',
+                                    header : 'Recieved',
+                                    width : 75,
+                                    renderer : function(v,x,r) {
+                                       
+                                        // total recieved = recv + recv_transfered - intransit?
+                                        
+                                        // old style = 0 in transit
+                                        // all delivered direct to warehouse
+                                        // 0 in 
+                                        
+                                        // new style = 100 in transit
+                                        // it will record 100 in transit, and 100 recieved
+                                        // and 
+                                        
+                                        // recv 610,unposted = 0 , transfer 610, in transit 610
+                                       
+                                         var recv = (1*r.data.pohead_qty_recv) +
+                                               (1*r.data.pohead_qty_transfered_unposted) +
+                                                 (1*r.data.pohead_qty_transfered) - 
+                                                 (1*r.data.pohead_qty_in_transit) ;
+                                                             
+                                        
+                                        if(r.data.pohead_qty_transfered_unposted * 1 > 0){
+                                            return String.format('<b style="color:red" qtip="{1} are Unposted">{0}</b>', recv ? (1*recv).toFixed(0) : '',
+                                            r.data.pohead_qty_transfered_unposted); 
+                                        }
+                                        
+                                        var format = '{0}';
+                                        if(recv != r.data.pohead_qty){
+                                            format = '<span style="color:red">{0}</span>';
+                                        }
+                                        
+                                        return String.format(format, recv ? (1*recv).toFixed(0) : '');
+                                         
+                                     }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'NestedLayoutPanel',
+                        xns: Roo,
+                        background : true,
+                        fitContainer : true,
+                        fitToFrame : true,
+                        region : 'east',
+                        layout : {
+                            xtype: 'BorderLayout',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'GridPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        activate : function() {
+                                            _this.rgpanel = this;
+                                            if (_this.rggrid) {
+                                                //_this.rggrid.ds.load({});
+                                            }
+                                        }
+                                    },
+                                    background : true,
+                                    fitContainer : true,
+                                    fitToframe : true,
+                                    region : 'center',
+                                    tableName : 'recvgrp',
+                                    title : "recvgrp",
+                                    grid : {
+                                        xtype: 'Grid',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            render : function() 
+                                            {
+                                                _this.rggrid = this; 
+                                                //_this.dialog = Pman.Dialog.FILL_IN
+                                                if (_this.rgpanel.active) {
+                                                   //this.ds.load({});
+                                                }
+                                            },
+                                            rowdblclick : function (_self, rowIndex, e)
+                                            {
+                                                 var s  = _this.rggrid.ds.getAt(rowIndex);
+                                                 
+                                                Pman.Dialog.XtupleRecvGrp.show( {
+                                                     recvgrp_id : s.data.recvgrp_id
+                                                     
+                                                 } , function() {
+                                                    _this.grid.footer.onClick('refresh');
+                                               }); 
+                                            },
+                                            rowclick : function (_self, rowIndex, e)
+                                            {
+                                                (function() { _this.rgrid.footer.onClick('first');}).defer(100);
+                                            }
+                                        },
+                                        autoExpandColumn : 'recvgrp_number',
+                                        loadMask : true,
+                                        dataSource : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, options)
+                                                {
+                                                    if (!_this.grid || !_this.grid.selModel.getSelected()) {
+                                                         this.removeAll();
+                                                         if (_this.rgrid) {
+                                                            _this.rgrid.ds.removeAll();
+                                                        }
+                                                        return false;
+                                                    }
+                                                    var r = _this.grid.selModel.getSelected();
+                                                    options.params = options.params || {};
+                                                    options.params.recvgrp_pohead_id = _this.grid.selModel.getSelected().data.pohead_id;
+                                                    
+                                                },
+                                                load : function (_self, records, options)
+                                                {
+                                                    _this.rgrid.footer.onClick('first');
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { field : 'recvgrp_id', direction: 'ASC' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/recvgrp.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                totalProperty : 'total',
+                                                root : 'data',
+                                                id : 'id',
+                                                fields : [
+                                                    {
+                                                        'name': 'recv_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_order_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_order_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_orderitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_agent_username',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_item_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_item_descrip',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_uom',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_duedate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_date',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_invoiced',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_trans_usr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_gldistdate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_rlsd_duedate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_poitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_close',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_taxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_pohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_invcnumber',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_amount',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_docdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_1099',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_distdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_reference',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_terms_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_adjtaxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_freighttaxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_gldistdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_misc',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_taxzone_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_taxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_lastpurchdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_active',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_po',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_comments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_pocomments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_1099',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_exported',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_fobsource',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_fob',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_terms_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_shipvia',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_vendtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_qualified',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemail',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemailbody',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edisubject',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edifilename',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_accntnum',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_emailpodelivery',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_restrictpurch',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edicc',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_cntct1_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_cntct2_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_addr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_match',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_enabled',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_accnttype',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_use_vendinfo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_indiv_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_indiv_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemailhtml',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_routingnumber',
+                                                        'type': 'text'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_accntnumber',
+                                                        'type': 'text'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_taxzone_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_order_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_order_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_orderitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_agent_username',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_item_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_item_descrip',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_uom',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_purchcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_purchcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_recvcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_recvcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_freight_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_date',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_invoiced',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_trans_usr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_gldistdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_splitfrom_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_rlsd_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_item_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_warehous_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_qtyonhand',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_reorderlevel',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordertoqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_cyclecountfreq',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_datelastcount',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_datelastused',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_loccntrl',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_safetystock',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_minordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_multordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_leadtime',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_abcclass',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_issuemethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_controlmethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_active',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_plancode_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_costcat_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_eventfence',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_sold',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_stocked',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_freeze',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_useparams',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_useparamsmanual',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_soldranking',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createpr',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location_comments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_perishable',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_nnqoh',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_autoabcclass',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordergroup',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_disallowblankwip',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_maxordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_mps_timefence',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createwo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_warrpurc',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_autoreg',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_costmethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordergroup_first',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_supply_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_planning_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_wosupply',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_posupply',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_lsseq_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_cosdefault',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createsopr',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createsopo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_dropship',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    }
+                                                ]
+                                            }
+                                        },
+                                        toolbar : {
+                                            xtype: 'Toolbar',
+                                            xns: Roo,
+                                            items : [
+                                                {
+                                                    xtype: 'Button',
+                                                    xns: Roo.Toolbar,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            
+                                                           var sel =  _this.rggrid.selModel.getSelected();
+                                                           if (!sel) {
+                                                                Roo.MessageBox.alert("Error", "Select Item receipt");
+                                                                return;
+                                                            }
+                                                            
+                                                            
+                                                            
+                                                            Pman.Dialog.XtupleTransfer.show({ createFromRev : sel.data.recvgrp_id },
+                                                                function() {
+                                                                    _this.grid.ds.load({});
+                                                                }
+                                                                );
+                                                        }
+                                                    },
+                                                    cls : 'x-btn-text-icon',
+                                                    hidden : true,
+                                                    text : "Create Transfer",
+                                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                },
+                                                {
+                                                    xtype: 'Fill',
+                                                    xns: Roo.Toolbar
+                                                },
+                                                {
+                                                    xtype: 'Button',
+                                                    xns: Roo.Toolbar,
+                                                    listeners : {
+                                                        click : function()
+                                                        {
+                                                             var s  = _this.grid.selModel.getSelected();
+                                                             if (!s) {
+                                                                Roo.MessageBox.alert("Error", "Select a purchase order");
+                                                                return
+                                                            }
+                                                            Pman.Dialog.XtupleRecvGrp.show( {
+                                                                 recvgrp_pohead_id : s.data.pohead_id ,
+                                                                 recvgrp_pohead_id_pohead_number : s.data.pohead_number
+                                                             } , function() {
+                                                                _this.grid.footer.onClick('refresh');
+                                                           }); 
+                                                        }
+                                                    },
+                                                    cls : 'x-btn-text-icon',
+                                                    text : "Add Receipt",
+                                                    icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                                }
+                                            ]
+                                        },
+                                        colModel : [
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'recvgrp_number',
+                                                header : 'ref#',
+                                                width : 120,
+                                                renderer : function(v,x,r) {
+                                                    var vv =v;
+                                                    var nn  = '';
+                                                    if (vv.indexOf(',') > -1) {
+                                                        vv = vv.split(',').shift();
+                                                    
+                                                    }
+                                                    if (vv.match(/^NSPO-/)) {
+                                                        vv = vv.replace(/^NSPO-/, '');
+                                                        nn = 'ns:&nbsp;';
+                                                    }
+                                                    
+                                                    var format = '<i>'+ nn +'</i><b qtip="{1}">{0}</b>';
+                                                    if (r.data.recvgrp_void *1) {
+                                                        format = '<s>'  + format + '</s>';
+                                                    }
+                                                    return String.format(format, vv,v); 
+                                                     
+                                                     
+                                                 }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'recvgrp_location_id_location_name',
+                                                header : 'To',
+                                                width : 80,
+                                                renderer : function(v,x,r) {
+                                                     
+                                                    return String.format('{0}',  v); 
+                                                     
+                                                     
+                                                 }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'recvgrp_date',
+                                                header : 'Date',
+                                                width : 75,
+                                                renderer : function(v) { return v ? v.format('d/M/Y')  : ''; }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'total_landed_cost',
+                                                header : 'Landed Cost',
+                                                width : 80,
+                                                renderer : function(v,x,r) { 
+                                                    return String.format('{1}{0}', v, r.data.base_curr_symbol); 
+                                                }
+                                            }
+                                        ]
+                                    }
+                                },
+                                {
+                                    xtype: 'GridPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        activate : function() {
+                                            _this.rpanel = this;
+                                            if (_this.rgrid) {
+                                                _this.rgrid.footer.onClick('first');
+                                            }
+                                        }
+                                    },
+                                    background : true,
+                                    fitContainer : true,
+                                    fitToframe : false,
+                                    region : 'south',
+                                    tableName : 'poitem',
+                                    title : "Items",
+                                    grid : {
+                                        xtype: 'Grid',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            render : function() 
+                                            {
+                                                _this.rgrid = this; 
+                                                //_this.dialog = Pman.Dialog.FILL_IN
+                                                if (_this.rpanel.active) {
+                                                   this.footer.onClick('first');
+                                                }
+                                            }
+                                        },
+                                        autoExpandColumn : 'item_number',
+                                        loadMask : true,
+                                        dataSource : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, options)
+                                                {
+                                                    if (!_this.grid || !_this.grid.selModel.getSelected()) {
+                                                        return false;
+                                                    }
+                                                    var r = _this.grid.selModel.getSelected();
+                                                    options.params.poitem_pohead_id = _this.grid.selModel.getSelected().data.pohead_id;
+                                                    var rr = _this.rggrid.selModel.getSelected();
+                                                
+                                                    options.params.recvgrp_id = 0;
+                                                    if (rr) {
+                                                        options.params.recvgrp_id = rr.data.recvgrp_id;
+                                                    }
+                                                    
+                                                    options.params._with_item  = 1;
+                                                        options.params.item_type = 'P';
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { field : 'recv_order_type', direction: 'ASC' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/poitem.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                totalProperty : 'total',
+                                                root : 'data',
+                                                id : 'id',
+                                                fields : [
+                                                    {
+                                                        'name': 'recv_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_order_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_order_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_orderitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_agent_username',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_item_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_item_descrip',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_uom',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_duedate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_date',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_invoiced',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_trans_usr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_gldistdate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_rlsd_duedate',
+                                                        'type': 'date',
+                                                        'dateFormat': 'Y-m-d'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_poitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_close',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_voitem_id_voitem_taxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_pohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_invcnumber',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_amount',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_docdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_1099',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_distdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_reference',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_terms_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_adjtaxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_freighttaxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_gldistdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_misc',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_taxzone_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_taxtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vohead_id_vohead_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_lastpurchdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_active',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_po',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_comments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_pocomments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_1099',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_exported',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_fobsource',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_fob',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_terms_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_shipvia',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_vendtype_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_qualified',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemail',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemailbody',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edisubject',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edifilename',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_accntnum',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_emailpodelivery',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_restrictpurch',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_edicc',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_cntct1_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_cntct2_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_addr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_match',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_enabled',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_accnttype',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_use_vendinfo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_indiv_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_indiv_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ediemailhtml',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_routingnumber',
+                                                        'type': 'text'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_ach_accntnumber',
+                                                        'type': 'text'
+                                                    },
+                                                    {
+                                                        'name': 'recv_vend_id_vend_taxzone_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_order_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_order_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_orderitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_agent_username',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_item_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_item_descrip',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vend_uom',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_purchcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_purchcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_qty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_recvcost',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_recvcost_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_freight',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_freight_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_date',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_posted',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_invoiced',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_vohead_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_voitem_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_trans_usr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_gldistdate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_splitfrom_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_splitfrom_id_recv_rlsd_duedate',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_recvcost_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_purchcost_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_item_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_warehous_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_qtyonhand',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_reorderlevel',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordertoqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_cyclecountfreq',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_datelastcount',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_datelastused',
+                                                        'type': 'date'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_loccntrl',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_safetystock',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_minordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_multordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_leadtime',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_abcclass',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_issuemethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_controlmethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_active',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_plancode_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_costcat_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_eventfence',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_sold',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_stocked',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_freeze',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_useparams',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_useparamsmanual',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_soldranking',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createpr',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_location_comments',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_notes',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_perishable',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_nnqoh',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_autoabcclass',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordergroup',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_disallowblankwip',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_maxordqty',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_mps_timefence',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createwo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_warrpurc',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_autoreg',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_costmethod',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_value',
+                                                        'type': 'float'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_ordergroup_first',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_supply_itemsite_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_planning_type',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_wosupply',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_posupply',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_lsseq_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_cosdefault',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createsopr',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_createsopo',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_itemsite_id_itemsite_dropship',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_base',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_name',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_symbol',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'recv_freight_curr_id_curr_abbr',
+                                                        'type': 'string'
+                                                    }
+                                                ]
+                                            }
+                                        },
+                                        footer : {
+                                            xtype: 'PagingToolbar',
+                                            xns: Roo,
+                                            displayInfo : true,
+                                            displayMsg : " ",
+                                            emptyMsg : "No recv found",
+                                            pageSize : 100
+                                        },
+                                        colModel : [
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'item_number',
+                                                header : 'Item',
+                                                width : 75,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'poitem_qty_ordered',
+                                                header : 'Ordered',
+                                                width : 60,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'r.data.poitem_qty_received',
+                                                header : 'Outstanding',
+                                                width : 60,
+                                                renderer : function(v,x,r) {
+                                                
+                                                
+                                                    var  d = r.data.poitem_qty_ordered - ( r.data.poitem_qty_received - r.data.poitem_qty_returned);
+                                                
+                                                    if (!d) {
+                                                        return '';
+                                                    }
+                                                    return String.format('<b style="color:red">{0}</b>', d); 
+                                                 }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'recv_qty_in_transit',
+                                                header : 'In Transit',
+                                                width : 60,
+                                                renderer : function(v,x,r) {
+                                                    // recv_qty
+                                                    // this should show in transit.. (only applicable to 
+                                                    //var rr = _this.rggrid.selModel.getSelected();
+                                                        //if (rr) {
+                                                            //return '';
+                                                    //    }
+                                                    
+                                                    // in transit = recieved, but not transfered.
+                                                    if ((v*1) == 0.0) {
+                                                        return '';
+                                                    }
+                                                    return String.format('{0}',  (v*1).toFixed(0)); 
+                                                /*
+                                                        // no reciept selected..
+                                                    d = r.data.poitem_qty_received - r.data.poitem_qty_returned ;
+                                                    d -= (r.data.poitem_qty_transfered_unposted*1 + r.data.poitem_qty_transfered*1) ;
+                                                
+                                                    if (!d) {
+                                                        return '';
+                                                    }
+                                                    return String.format('{0}',  d); 
+                                                    */
+                                                 }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                align : 'right',
+                                                dataIndex : 'recv_qty',
+                                                header : 'Recieved',
+                                                width : 60,
+                                                renderer : function(v,x,r) {
+                                                
+                                                    var d = parseInt(v);;
+                                                    var rr = _this.rggrid.selModel.getSelected();
+                                                    if (!rr) {
+                                                        // show summary
+                                                        //d = r.data.poitem_qty_received - r.data.poitem_qty_returned;
+                                                        // real recived amount = the total that has been transfered out 
+                                                       
+                                                       
+                                                       
+                                                       //d =  (r.data.poitem_qty_transfered_unposted*1 + r.data.poitem_qty_transfered*1) ;
+                                                        //var tot_rec =  r.data.poitem_qty_received - r.data.poitem_qty_returned;
+                                                        //if (d < tot_rec) {
+                                                        //    return String.format('<b style="color:red">{0}</b>',  d); 
+                                                        //}
+                                                
+                                                        //return String.format('{0}',  d); 
+                                                        
+                                                        
+                                                    } 
+                                                     
+                                                
+                                                    if (!d) {
+                                                        return '';
+                                                    }
+                                                    if (rr && rr.data.recvgrp_void *1 ) {
+                                                            return String.format('<s>{0}</s>',  d); 
+                                                    
+                                                    }
+                                                
+                                                    
+                                                    
+                                                    return String.format('{0}',  d); 
+                                                 }
+                                            }
+                                        ]
+                                    }
+                                }
+                            ],
+                            center : {
+                                xtype: 'LayoutRegion',
+                                xns: Roo,
+                                title : "Item Receipts",
+                                titlebar : true
+                            },
+                            south : {
+                                xtype: 'LayoutRegion',
+                                xns: Roo,
+                                height : 450,
+                                split : true,
+                                title : "Items"
+                            }
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                east : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    width : 340
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePurchaseStock.bjs b/Pman.Tab.XtuplePurchaseStock.bjs
new file mode 100644 (file)
index 0000000..884db18
--- /dev/null
@@ -0,0 +1,581 @@
+{
+    "id": "roo-file-46",
+    "name": "Pman.Tab.XtuplePurchaseStock",
+    "parent": "Pman.Tab.XtuplePurchases",
+    "title": "Pman.Tab.XtuplePurchaseStock",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePurchaseStock.bjs",
+    "items": [
+        {
+            "background": true,
+            "title": "Incoming Stock Schedule",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "poitem",
+                            "title": "Incoming Stock Schedule",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "afteredit": "function (e)\n{\n    if (e.originalValue == e.value || e.field == 'join_poitem_location_name') {\n        return;\n    }\n    \n    e.record.commit();\n    \n}",
+                                        "rowdblclick": "function (_self, rowIndex, e)\r\n{\r\n    \n    var r = _this.grid.ds.getAt(rowIndex);\r\n    Pman.Dialog.XtuplePurchaseOrder.show( { pohead_id : r.data.join_poitem_pohead_id , office : _this.office.getValue()}, function() {\r\n        _this.grid.footer.onClick('refresh');\r\n    }); \r\n}\r",
+                                        "beforeedit": "function (e)\n{\n    var office = _this.office.getValue();\n    var local = baseURL.split('/').pop().split('.').shift();\n    \n    if(office != local){\n        return false;\n    }\n}",
+                                        "rowclick": "function (_self, rowIndex, e)\n{\n\n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "item_descrip",
+                                    "clicksToEdit": 1,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    \n    o.params._incoming_stock = 1;\n    \n    o.params.poitem_status = _this.status.getValue();\n    \n    o.params._roo_office = _this.office.getValue();\n    \n    o.params['search[location]'] = _this.location.getValue();\n    \n    o.params['search[name]'] = _this.searchBox.getValue();\n\n}",
+                                                "update": "function (_self, record, operation)\n{\n    if (operation != 'commit') {\n        Roo.log(operation);\n        return;\n    }\n    var params = {\n            pohead_id : record.data.join_poitem_pohead_id,\n            pohead_comments : record.data.join_poitem_pohead_comments,\n            pohead_bg_va : record.data.join_poitem_pohead_bg_va,\n            pohead_bg_arrival_est_day : record.data.join_poitem_pohead_bg_arrival_est_day,\n            pohead_bg_available_est_day : record.data.join_poitem_pohead_bg_available_est_day,\n            pohead_bg_available_latest_day : record.data.join_poitem_pohead_bg_available_latest_day,\n            pohead_notes : record.data.join_poitem_pohead_notes\n    };\n        \n\n    new Pman.Request({\n        method : 'POST',\n        url : baseURL + '/Roo/pohead',\n        params :  params\n    });\n    \n\n    _this.grid.footer.onClick('refresh');\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Xtuple/Roo/Poitem.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'name',\n        'type': 'string'\n    },\n    {\n        'name': 'type',\n        'type': 'int'\n    },\n    {\n        'name': 'leader',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_name',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_email',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_role',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_active',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_deleted_dt',\n        'type': 'date'\n    },\n    {\n        'name': 'leader_firstname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_lastname',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_name_facebook',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_blog',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_twitter',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_url_linkedin',\n        'type': 'string'\n    },\n    {\n        'name': 'leader_crm_lead_percentage',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_industry_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_updated_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_created_action_id',\n        'type': 'int'\n    },\n    {\n        'name': 'leader_crm_type_id',\n        'type': 'int'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "specialkey": "function (_self, e)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                                        "render": "function (_self)\n{\n    _this.searchBox = _self;\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\r\n    _this.grid.footer.onClick('first');\r\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": true,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "emptyText": "Select Status",
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "poitem_status",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "poitem_status",
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{fname}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "value": "",
+                                                    "valueField": "ftype",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ \n    [ 'O', \"Open\"],\n    [ 'C' , \"Closed\"],\n    [ 'U', \"Unreleased\"] \n]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.location = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": true,
+                                                    "alwaysQuery": true,
+                                                    "displayField": "location_name",
+                                                    "editable": true,
+                                                    "emptyText": "Select a location",
+                                                    "fieldLabel": "Location",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "pohead_location_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "pohead_location_id",
+                                                    "pageSize": 200,
+                                                    "qtip": "Select terms",
+                                                    "queryParam": "query[location_name]",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": false,
+                                                    "valueField": "location_id",
+                                                    "width": 200,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n     o.params.location_netable = 1;\n     o.params._roo_office = _this.office.getValue();\n     o.params._notinternalcompany = 1;\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Xtuple/Roo/location.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "location_id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n  _this.office = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    _this.location.reset();\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "office",
+                                                    "editable": false,
+                                                    "fieldLabel": "Office",
+                                                    "hiddenName": "office",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "office",
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{office}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "valueField": "office",
+                                                    "width": 150,
+                                                    "xtype": "ComboBox",
+                                                    "|value": "(function() {  \n    if(uiConfig.incomming_default_company){\n        return uiConfig.incomming_default_company;\n    }\n    return 'hk';  \n})()",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "(function() {             \n    var officeList = []; \n    if(uiConfig.incomming_default_company){\n        officeList.push([uiConfig.incomming_default_company]);\n    }            \n    officeList.push(['hk']);             \n  return officeList;\n})()",
+                                                            "|fields": "['office']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n    var sel = _this.grid.getSelectionModel().getSelectedCell();\n    if (!sel)  {\n        Roo.MessageBox.alert(\"Error\", \"Select a Row\");\n        return;\n    } \n    var s = _this.grid.ds.getAt(sel[0]);\n    if(!s.data.join_poitem_pohead_id.length){\n        return;\n    }\n    \n    var office = _this.office.getValue();\n    var local = baseURL.split('/').pop().split('.').shift();\n\n    if(office != local){\n        Roo.MessageBox.alert(\"Error\", \"You cannot edit the remote date, Only local data can be edited!\");\n        return;\n    }\n    \n     Pman.Dialog.XtuplePurchaseOrderEdit.show({pohead_id : s.data.join_poitem_pohead_id} , function () {\n           _this.grid.footer.onClick('refresh');\n     });\n    \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Fill location",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying poitem{0} - {1} of {2}",
+                                            "emptyMsg": "No poitem found",
+                                            "pageSize": 25,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function ()\n{\n    \n     new Pman.Download({\n        grid : _this.grid\n    });\n            \n   \n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Download Schedule",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_number",
+                                            "header": "P/O No#",
+                                            "sortable": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "brand_value",
+                                            "header": "Brand",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_name",
+                                            "header": "Item (SKU)",
+                                            "sortable": true,
+                                            "width": 70,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "item_descrip",
+                                            "header": "Description",
+                                            "width": 300,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_comments",
+                                            "header": "B&G reference",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_bg_va",
+                                            "header": "VA?",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_bg_arrival_est_day",
+                                            "header": "Est. Arrival",
+                                            "width": 70,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    if(typeof(v) == 'object'){\n       return String.format('{0}',v.format('d/M/Y'));\n    }\n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_bg_available_est_day",
+                                            "header": "Est. Avail",
+                                            "width": 70,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    if(typeof(v) == 'object'){\n       return String.format('{0}',v.format('d/M/Y'));\n    }\n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_bg_available_latest_day",
+                                            "header": "Confirm Avail",
+                                            "sortable": true,
+                                            "width": 70,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { \n    if(typeof(v) == 'object'){\n       return String.format('{0}',v.format('d/M/Y'));\n    }\n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "format": "d/M/Y",
+                                                            "useIso": true,
+                                                            "xtype": "DateField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_location_name",
+                                            "header": "Location",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n    \n    return String.format('{0}', v ? v : ''); \n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeselect": "function (combo, record, index)\n{\n    var ar = _this.grid.activeEditor.record;\n    \n    if(record.data.location_id == ar.data.join_poitem_location_id){\n        return;\n    }\n    \n    var params = {\r\n            poitem_id : ar.data.poitem_id,\r\n            poitem_location_id : record.data.location_id\r\n    };\r\n        \r\n\r\n    new Pman.Request({\r\n        method : 'POST',\r\n        url : baseURL + '/Roo/poitem',\r\n        params :  params\r\n    });\n    \n\r\n}"
+                                                            },
+                                                            "*prop": "field",
+                                                            "displayField": "location_name",
+                                                            "editable": true,
+                                                            "emptyText": "Select a location",
+                                                            "forceSelection": true,
+                                                            "hiddenName": "join_poitem_location_id",
+                                                            "listWidth": 400,
+                                                            "loadingText": "Searching...",
+                                                            "minChars": 2,
+                                                            "name": "join_poitem_location_name",
+                                                            "pageSize": 20,
+                                                            "qtip": "Select a location",
+                                                            "queryParam": "query[location_name]",
+                                                            "selectOnFocus": true,
+                                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b> </div>",
+                                                            "triggerAction": "all",
+                                                            "typeAhead": false,
+                                                            "valueField": "location_id",
+                                                            "xtype": "ComboBox",
+                                                            "|xns": "Roo.form",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.location_netable = 1;\n}\n"
+                                                                    },
+                                                                    "*prop": "store",
+                                                                    "remoteSort": true,
+                                                                    "xtype": "Store",
+                                                                    "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                                                    "|xns": "Roo.data",
+                                                                    "items": [
+                                                                        {
+                                                                            "*prop": "proxy",
+                                                                            "method": "GET",
+                                                                            "xtype": "HttpProxy",
+                                                                            "|url": "baseURL + '/Roo/location.php'",
+                                                                            "|xns": "Roo.data"
+                                                                        },
+                                                                        {
+                                                                            "*prop": "reader",
+                                                                            "id": "location_id",
+                                                                            "root": "data",
+                                                                            "totalProperty": "total",
+                                                                            "xtype": "JsonReader",
+                                                                            "|fields": "[{\"name\":\"location_id\",\"type\":\"int\"},\"location_name\"]",
+                                                                            "|xns": "Roo.data"
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_vend_name",
+                                            "header": "Originating from",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n    if(v && r.data.join_poitem_pohead_vendcountry)\n    {\n        return String.format('{0}', v + ' (' + r.data.join_poitem_pohead_vendcountry + ')'); \n    }\n    return String.format('{0}', v); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "poitem_qty_ordered",
+                                            "header": "Qty",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v : '' ); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_orderdate",
+                                            "header": "Order Created",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) \n{ \n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "poitem_duedate",
+                                            "header": "ETA Date",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) \n{ \n   // var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', v ? v.format('d/M/Y') : '');\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_last_updated",
+                                            "header": "Last Updated",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \r\n{\r\n   if(!v){\r\n    return '';\r\n   }\r\n   var d = (new Date()).add(Date.DAY, -15);\r\n   v = new Date(v);\r\n   \r\n   if(v > d){\r\n        return '<span style=\"color:red\">' + v.format('d/M/Y') + '</span>';\r\n   }\r\n   \r\n   return String.format('{0}', v ? v.format('d/M/Y') : '');\r\n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "join_poitem_pohead_notes",
+                                            "header": "Notes",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "xtype": "TextField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "200"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePurchaseStock.js b/Pman.Tab.XtuplePurchaseStock.js
new file mode 100644 (file)
index 0000000..ba9e506
--- /dev/null
@@ -0,0 +1,867 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePurchaseStock = new Roo.XComponent({
+    part     :  ["Xtuple","PurchaseStock"],
+    order    : '200-Pman.Tab.XtuplePurchaseStock',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtuplePurchases',
+    name     : "Pman.Tab.XtuplePurchaseStock",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            title : "Incoming Stock Schedule",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'poitem',
+                        title : "Incoming Stock Schedule",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                afteredit : function (e)
+                                {
+                                    if (e.originalValue == e.value || e.field == 'join_poitem_location_name') {
+                                        return;
+                                    }
+                                    
+                                    e.record.commit();
+                                    
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    
+                                    var r = _this.grid.ds.getAt(rowIndex);
+                                    Pman.Dialog.XtuplePurchaseOrder.show( { pohead_id : r.data.join_poitem_pohead_id , office : _this.office.getValue()}, function() {
+                                        _this.grid.footer.onClick('refresh');
+                                    }); 
+                                },
+                                beforeedit : function (e)
+                                {
+                                    var office = _this.office.getValue();
+                                    var local = baseURL.split('/').pop().split('.').shift();
+                                    
+                                    if(office != local){
+                                        return false;
+                                    }
+                                },
+                                rowclick : function (_self, rowIndex, e)
+                                {
+                                
+                                }
+                            },
+                            autoExpandColumn : 'item_descrip',
+                            clicksToEdit : 1,
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        o.params = o.params || {};
+                                        
+                                        o.params._incoming_stock = 1;
+                                        
+                                        o.params.poitem_status = _this.status.getValue();
+                                        
+                                        o.params._roo_office = _this.office.getValue();
+                                        
+                                        o.params['search[location]'] = _this.location.getValue();
+                                        
+                                        o.params['search[name]'] = _this.searchBox.getValue();
+                                    
+                                    },
+                                    update : function (_self, record, operation)
+                                    {
+                                        if (operation != 'commit') {
+                                            Roo.log(operation);
+                                            return;
+                                        }
+                                        var params = {
+                                                pohead_id : record.data.join_poitem_pohead_id,
+                                                pohead_comments : record.data.join_poitem_pohead_comments,
+                                                pohead_bg_va : record.data.join_poitem_pohead_bg_va,
+                                                pohead_bg_arrival_est_day : record.data.join_poitem_pohead_bg_arrival_est_day,
+                                                pohead_bg_available_est_day : record.data.join_poitem_pohead_bg_available_est_day,
+                                                pohead_bg_available_latest_day : record.data.join_poitem_pohead_bg_available_latest_day,
+                                                pohead_notes : record.data.join_poitem_pohead_notes
+                                        };
+                                            
+                                    
+                                        new Pman.Request({
+                                            method : 'POST',
+                                            url : baseURL + '/Roo/pohead',
+                                            params :  params
+                                        });
+                                        
+                                    
+                                        _this.grid.footer.onClick('refresh');
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Xtuple/Roo/Poitem.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'type',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_office_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_phone',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_fax',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_email',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_company_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_role',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_active',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_remarks',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_passwd',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_owner_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_lang',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_no_reset_sent',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_action_type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_project_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_deleted_by',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_deleted_dt',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'leader_firstname',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_lastname',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_name_facebook',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_url_blog',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_url_twitter',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_url_linkedin',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'leader_crm_lead_percentage',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_crm_industry_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_crm_updated_action_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_crm_created_action_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'leader_crm_type_id',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            specialkey : function (_self, e)
+                                            {
+                                              _this.grid.footer.onClick('first');
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.searchBox = _self;
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.searchBox.setValue('');
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.status = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                            
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        emptyText : "Select Status",
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'poitem_status',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'poitem_status',
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{fname}</b> </div>',
+                                        triggerAction : 'all',
+                                        value : "",
+                                        valueField : 'ftype',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ 
+                                                [ 'O', "Open"],
+                                                [ 'C' , "Closed"],
+                                                [ 'U', "Unreleased"] 
+                                            ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.location = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        alwaysQuery : true,
+                                        displayField : 'location_name',
+                                        editable : true,
+                                        emptyText : "Select a location",
+                                        fieldLabel : 'Location',
+                                        forceSelection : true,
+                                        hiddenName : 'pohead_location_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'pohead_location_id',
+                                        pageSize : 200,
+                                        qtip : "Select terms",
+                                        queryParam : 'query[location_name]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'location_id',
+                                        width : 200,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                     o.params.location_netable = 1;
+                                                     o.params._roo_office = _this.office.getValue();
+                                                     o.params._notinternalcompany = 1;
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'location_name' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Xtuple/Roo/location.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'location_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"location_id","type":"int"},"location_name"]
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                              _this.office = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                _this.location.reset();
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'office',
+                                        editable : false,
+                                        fieldLabel : 'Office',
+                                        hiddenName : 'office',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'office',
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{office}</b> </div>',
+                                        triggerAction : 'all',
+                                        valueField : 'office',
+                                        width : 150,
+                                        value : (function() {  
+                                            if(uiConfig.incomming_default_company){
+                                                return uiConfig.incomming_default_company;
+                                            }
+                                            return 'hk';  
+                                        })(),
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : (function() {             
+                                                var officeList = []; 
+                                                if(uiConfig.incomming_default_company){
+                                                    officeList.push([uiConfig.incomming_default_company]);
+                                                }            
+                                                officeList.push(['hk']);             
+                                              return officeList;
+                                            })(),
+                                            fields : ['office']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                                var sel = _this.grid.getSelectionModel().getSelectedCell();
+                                                if (!sel)  {
+                                                    Roo.MessageBox.alert("Error", "Select a Row");
+                                                    return;
+                                                } 
+                                                var s = _this.grid.ds.getAt(sel[0]);
+                                                if(!s.data.join_poitem_pohead_id.length){
+                                                    return;
+                                                }
+                                                
+                                                var office = _this.office.getValue();
+                                                var local = baseURL.split('/').pop().split('.').shift();
+                                            
+                                                if(office != local){
+                                                    Roo.MessageBox.alert("Error", "You cannot edit the remote date, Only local data can be edited!");
+                                                    return;
+                                                }
+                                                
+                                                 Pman.Dialog.XtuplePurchaseOrderEdit.show({pohead_id : s.data.join_poitem_pohead_id} , function () {
+                                                       _this.grid.footer.onClick('refresh');
+                                                 });
+                                                
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Fill location",
+                                        icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                    }
+                                ]
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : "Displaying poitem{0} - {1} of {2}",
+                                emptyMsg : "No poitem found",
+                                pageSize : 25,
+                                items : [
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function ()
+                                            {
+                                                
+                                                 new Pman.Download({
+                                                    grid : _this.grid
+                                                });
+                                                        
+                                               
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Download Schedule",
+                                        icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_number',
+                                    header : 'P/O No#',
+                                    sortable : true,
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'brand_value',
+                                    header : 'Brand',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_name',
+                                    header : 'Item (SKU)',
+                                    sortable : true,
+                                    width : 70,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'item_descrip',
+                                    header : 'Description',
+                                    width : 300,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_comments',
+                                    header : 'B&G reference',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_bg_va',
+                                    header : 'VA?',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_bg_arrival_est_day',
+                                    header : 'Est. Arrival',
+                                    width : 70,
+                                    renderer : function(v) { 
+                                        if(typeof(v) == 'object'){
+                                           return String.format('{0}',v.format('d/M/Y'));
+                                        }
+                                        var d = Date.parseDate(v, 'Y-m-d');
+                                        return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'DateField',
+                                            xns: Roo.form,
+                                            format : 'd/M/Y',
+                                            useIso : true
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_bg_available_est_day',
+                                    header : 'Est. Avail',
+                                    width : 70,
+                                    renderer : function(v) { 
+                                        if(typeof(v) == 'object'){
+                                           return String.format('{0}',v.format('d/M/Y'));
+                                        }
+                                        var d = Date.parseDate(v, 'Y-m-d');
+                                        return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'DateField',
+                                            xns: Roo.form,
+                                            format : 'd/M/Y',
+                                            useIso : true
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_bg_available_latest_day',
+                                    header : 'Confirm Avail',
+                                    sortable : true,
+                                    width : 70,
+                                    renderer : function(v) { 
+                                        if(typeof(v) == 'object'){
+                                           return String.format('{0}',v.format('d/M/Y'));
+                                        }
+                                        var d = Date.parseDate(v, 'Y-m-d');
+                                        return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'DateField',
+                                            xns: Roo.form,
+                                            format : 'd/M/Y',
+                                            useIso : true
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_location_name',
+                                    header : 'Location',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                        
+                                        return String.format('{0}', v ? v : ''); 
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'ComboBox',
+                                            xns: Roo.form,
+                                            listeners : {
+                                                beforeselect : function (combo, record, index)
+                                                {
+                                                    var ar = _this.grid.activeEditor.record;
+                                                    
+                                                    if(record.data.location_id == ar.data.join_poitem_location_id){
+                                                        return;
+                                                    }
+                                                    
+                                                    var params = {
+                                                            poitem_id : ar.data.poitem_id,
+                                                            poitem_location_id : record.data.location_id
+                                                    };
+                                                        
+                                                
+                                                    new Pman.Request({
+                                                        method : 'POST',
+                                                        url : baseURL + '/Roo/poitem',
+                                                        params :  params
+                                                    });
+                                                    
+                                                
+                                                }
+                                            },
+                                            displayField : 'location_name',
+                                            editable : true,
+                                            emptyText : "Select a location",
+                                            forceSelection : true,
+                                            hiddenName : 'join_poitem_location_id',
+                                            listWidth : 400,
+                                            loadingText : "Searching...",
+                                            minChars : 2,
+                                            name : 'join_poitem_location_name',
+                                            pageSize : 20,
+                                            qtip : "Select a location",
+                                            queryParam : 'query[location_name]',
+                                            selectOnFocus : true,
+                                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b> </div>',
+                                            triggerAction : 'all',
+                                            typeAhead : false,
+                                            valueField : 'location_id',
+                                            store : {
+                                                xtype: 'Store',
+                                                xns: Roo.data,
+                                                listeners : {
+                                                    beforeload : function (_self, o){
+                                                        o.params = o.params || {};
+                                                        o.params.location_netable = 1;
+                                                    }
+                                                },
+                                                remoteSort : true,
+                                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                                proxy : {
+                                                    xtype: 'HttpProxy',
+                                                    xns: Roo.data,
+                                                    method : 'GET',
+                                                    url : baseURL + '/Roo/location.php'
+                                                },
+                                                reader : {
+                                                    xtype: 'JsonReader',
+                                                    xns: Roo.data,
+                                                    id : 'location_id',
+                                                    root : 'data',
+                                                    totalProperty : 'total',
+                                                    fields : [{"name":"location_id","type":"int"},"location_name"]
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_vend_name',
+                                    header : 'Originating from',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                        if(v && r.data.join_poitem_pohead_vendcountry)
+                                        {
+                                            return String.format('{0}', v + ' (' + r.data.join_poitem_pohead_vendcountry + ')'); 
+                                        }
+                                        return String.format('{0}', v); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'poitem_qty_ordered',
+                                    header : 'Qty',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v ? v : '' ); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_orderdate',
+                                    header : 'Order Created',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) 
+                                    { 
+                                        var d = Date.parseDate(v, 'Y-m-d');
+                                        return String.format('{0}', d ? d.format('d/M/Y') : '');
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'poitem_duedate',
+                                    header : 'ETA Date',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) 
+                                    { 
+                                       // var d = Date.parseDate(v, 'Y-m-d');
+                                        return String.format('{0}', v ? v.format('d/M/Y') : '');
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_last_updated',
+                                    header : 'Last Updated',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       if(!v){
+                                        return '';
+                                       }
+                                       var d = (new Date()).add(Date.DAY, -15);
+                                       v = new Date(v);
+                                       
+                                       if(v > d){
+                                            return '<span style="color:red">' + v.format('d/M/Y') + '</span>';
+                                       }
+                                       
+                                       return String.format('{0}', v ? v.format('d/M/Y') : '');
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'join_poitem_pohead_notes',
+                                    header : 'Notes',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'TextField',
+                                            xns: Roo.form
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePurchases.bjs b/Pman.Tab.XtuplePurchases.bjs
new file mode 100644 (file)
index 0000000..e311efc
--- /dev/null
@@ -0,0 +1,32 @@
+{
+    "id": "roo-file-393",
+    "name": "Pman.Tab.XtuplePurchases",
+    "parent": "Pman",
+    "title": "Pman.Tab.XtuplePurchases",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePurchases.bjs",
+    "items": [
+        {
+            "region": "center",
+            "title": "Purchases",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "*prop": "center",
+                            "tabPosition": "top",
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "004"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePurchases.js b/Pman.Tab.XtuplePurchases.js
new file mode 100644 (file)
index 0000000..a719e8c
--- /dev/null
@@ -0,0 +1,33 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePurchases = new Roo.XComponent({
+    part     :  ["Xtuple","Purchases"],
+    order    : '004-Pman.Tab.XtuplePurchases',
+    region   : 'center',
+    parent   : 'Pman',
+    name     : "Pman.Tab.XtuplePurchases",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            region : 'center',
+            title : "Purchases",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    tabPosition : 'top'
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtuplePurchasesVendors.bjs b/Pman.Tab.XtuplePurchasesVendors.bjs
new file mode 100644 (file)
index 0000000..84ef7bb
--- /dev/null
@@ -0,0 +1,166 @@
+{
+    "id": "roo-file-314",
+    "name": "Pman.Tab.XtuplePurchasesVendors",
+    "parent": "Pman.Tab.XtuplePurchases",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtuplePurchasesVendors.bjs",
+    "items": [
+        {
+            "background": true,
+            "fitContainer": true,
+            "fitToFrame": true,
+            "region": "center",
+            "title": "Vendors",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": false,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "vendinfo",
+                            "title": "Vendors",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "vend_name",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    \n    if (! _this.searchBox) {\n    // not rendered yet...\n        return false;\n            \n    }\n    options.params = options.params || {};\n    options.params._with_char = 1;\n    options.params['search[name]'] = _this.searchBox.getValue();\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'vend_name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Vendinfo.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "vend_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'vend_id',\n        'type': 'int'\n    },\n    {\n        'name': 'vend_name',\n        'type': 'string'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying vendinfo{0} - {1} of {2}",
+                                            "emptyMsg": "No vendinfo found",
+                                            "pageSize": 25,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "text": "Search : ",
+                                                    "xtype": "TextItem",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.searchBox = _self;\n}",
+                                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "xtype": "TextField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\n    \n    \n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Vendors' \n        \n       },\n       function (data) {\n            _this.grid.footer.onClick('first');\n            Roo.MessageBox.alert(\"Notice\", \"DONE\");\n//            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n}"
+                                                    },
+                                                    "text": "Upload Vendors",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vend_name",
+                                            "header": "Name",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "vend_char_internalcompany",
+                                            "header": "Internal?",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "300"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtuplePurchasesVendors.js b/Pman.Tab.XtuplePurchasesVendors.js
new file mode 100644 (file)
index 0000000..63fabdd
--- /dev/null
@@ -0,0 +1,218 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtuplePurchasesVendors = new Roo.XComponent({
+    part     :  ["Xtuple","PurchasesVendors"],
+    order    : '300-Pman.Tab.XtuplePurchasesVendors',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtuplePurchases',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            background : true,
+            fitContainer : true,
+            fitToFrame : true,
+            region : 'center',
+            title : "Vendors",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : false,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'vendinfo',
+                        title : "Vendors",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                }
+                            },
+                            autoExpandColumn : 'vend_name',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        
+                                        if (! _this.searchBox) {
+                                        // not rendered yet...
+                                            return false;
+                                                
+                                        }
+                                        options.params = options.params || {};
+                                        options.params._with_char = 1;
+                                        options.params['search[name]'] = _this.searchBox.getValue();
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'vend_name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Vendinfo.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'vend_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'vend_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'vend_name',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : "Displaying vendinfo{0} - {1} of {2}",
+                                emptyMsg : "No vendinfo found",
+                                pageSize : 25
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextItem',
+                                        xns: Roo.Toolbar,
+                                        text : "Search : "
+                                    },
+                                    {
+                                        xtype: 'TextField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.searchBox = _self;
+                                            },
+                                            specialkey : function (_self, e)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/search.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.searchBox.setValue('');
+                                                
+                                                
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/Vendors' 
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        _this.grid.footer.onClick('first');
+                                                        Roo.MessageBox.alert("Notice", "DONE");
+                                            //            Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                            
+                                                   }
+                                               );
+                                            }
+                                        },
+                                        text : "Upload Vendors"
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vend_name',
+                                    header : 'Name',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'vend_char_internalcompany',
+                                    header : 'Internal?',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleReconcile.bjs b/Pman.Tab.XtupleReconcile.bjs
new file mode 100644 (file)
index 0000000..6e9a20a
--- /dev/null
@@ -0,0 +1,505 @@
+{
+    "id": "roo-file-53",
+    "name": "Pman.Tab.XtupleReconcile",
+    "parent": "Pman.Tab.XtupleAccountsTab",
+    "title": "Pman.Tab.XtupleReconcile",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleReconcile.bjs",
+    "items": [
+        {
+            "title": "Bank Reconcile",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "west",
+                            "split": true,
+                            "width": 400,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "metasql",
+                            "title": "Bank Reconcile",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var clear = function(ar) \n    {\n        var ar_in = ar;\n        if (ar === true) {\n            ar = [];\n            \n            _this.grid.ds.each(function(rec) {\n                if (rec.data.doc_type == 'BF') {\n                    return;\n                }\n                ar.push(rec);\n            });\n        }\n        var sortdate = false;\n        var data = [];\n        Roo.each(ar, function(rec) {\n            if (rec.data.cleared || rec.data.bankrec_posted) {\n                return;\n            }\n            if(!sortdate){\n                sortdate = rec.data.sortdate;\n            }\n            data.push({\n                 id : rec.data.id,\n                altid : rec.data.altid,\n                curr_rate : rec.data.doc_exchrate,\n                amount : rec.data.amount\n                \n            });\n        });\n       new Pman.Request({\n        url : baseURL + '/Roo/bankrecitem',\n            method : 'POST',\n            mask : 'Clearing',\n            params : {\n                bankaccnt_id : _this.bankacct.getValue(),\n                sortdate : sortdate,\n                set_clear : Roo.encode(data)\n            },\n            success : function() {\n                Roo.each(ar, function(rec) {\n                    rec.set('cleared', true);\n                });\n                if (ar_in === true) {\n                    _this.grid.ds.getAt(0).set('cleared', true);\n                }\n                _this.wgrid.footer.onClick('refresh');\n            }\n        });\n    }\n    \n    \n    var unclear = function(ar)\n    {\n        var ar_in = ar;\n        if (ar === true) {\n            ar = [];\n            \n            _this.grid.ds.each(function(rec) {\n                if (rec.data.doc_type == 'BF') {\n                    return;\n                }\n                ar.push(rec);\n            });\n        }\n        var sortdate = false;\n        var data = [];\n        Roo.each(ar, function(rec) {\n            if (!rec.data.cleared  || rec.data.bankrec_posted) {\n                return;\n            }\n            if(!sortdate){\n                sortdate = rec.data.sortdate;\n            }\n            data.push({\n                id : rec.data.id,\n                altid : rec.data.altid                \n            });\n        });\n\n        new Pman.Request({\n            url : baseURL + '/Roo/bankrecitem',\n            method : 'POST',\n            mask : 'Clearing',\n            params : {\n                bankaccnt_id : _this.bankacct.getValue(),\n                sortdate : sortdate,\n                remove_clear :Roo.encode(data)\n                \n            },\n            success : function() {\n                Roo.each(ar, function(rec) {\n                    rec.set('cleared', false);\n                });\n               if (ar_in === true) {\n                    _this.grid.ds.getAt(0).set('cleared', false);\n                }  \n                _this.wgrid.footer.onClick('refresh');\n            }\n        });\n     \n      \n    };\n    \n    \n    \n    var di = this.colModel.config[columnIndex].dataIndex;\n    if (di != 'cleared') {\n        return;\n    }\n    var  rec = this.ds.getAt(rowIndex);\n    if (rec.data.doc_type == 'BF') {\n    \n        if (rec.data.cleared) {\n            unclear(true);\n        \n        } else {\n            clear(true);\n        }\n    \n        return;\n    }\n    \n        \n        \n    if (rec.data.cleared) {\n    \n        unclear([rec]);\n        return;\n        \n    }\n    \n    clear([rec]);\n    \n    \n     \n         \n  \n}",
+                                        "beforeedit": "function (e)\n{\n    //    Roo.log(e);\n       var ch =  _this.grid.colModel.config[e.column].header;\n       var val = e.value *1;\n  // Roo.log(ch);\n  // Roo.log(val);\n\n       if (val > 0.0 && ch == 'Debit') {\n            e.cancel = true;\n            return;\n        }\n       if (val < 0.0 && ch == 'Credit') {\n            e.cancel = true;\n            return;\n        }\n        if (e.record.data.cleared || e.record.data.bankrec_posted) {\n            e.cancel = true;\n            return;\n        }\n        \n        // allow start editing..\n}",
+                                        "afteredit": "function (e)\n{\n\n    if (e.cancel) {\n        return;\n    }\n       var ch =  _this.grid.colModel.config[e.column].header;\n           var val = e.originalValue *1;\n      // Roo.log(ch);\n      // Roo.log(val);\n\n       if (val > 0.0 && ch == 'Debit') {\n            e.cancel = true;\n            return;\n        }\n       if (val < 0.0 && ch == 'Credit') {\n            e.cancel = true;\n            return;\n        }\n        if (e.record.data.cleared || e.record.data.bankrec_posted) {\n            e.cancel = true;\n            return;\n        }\n        if (val > 0.0 && e.value < 0.0) {\n        Roo.log(\"CANCEL\");  \n            e.record.set('amount', e.originalValue);\n            e.cancel = true;\n            return;\n        }\n        if (val < 0.0 && e.value > 0.0) {\n        Roo.log(\"CANCEL\");\n            e.record.set('amount', e.originalValue);\n            e.cancel = true;\n            return;\n        } \n        if (e.originalValue*1 == e.value*1) {\n            return;\n        }\n          \n        e.record.set('doc_exchrate', Math.abs(e.value  * 1)  / Math.abs(e.record.data.base_amount * 1));\n        Roo.log(e.record);\n        \n        _this.grid.ds.updateBalance();\n        // send it down the line...\n        new Pman.Request({\n            method : 'POST',\n            url : baseURL + '/Roo/bankrecitem',\n            mask : 'Saving',\n            params : {\n                bankaccnt_id : _this.bankacct.getValue(),\n                set_amount : Math.abs(e.value),\n                sortdate : e.record.data.sortdate,\n                source_id : e.record.data.id,\n                altid : e.record.data.altid\n            }\n        \n        });\n        \n         \n        \n        \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "notes",
+                                    "clicksToEdit": 1,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeloadadd": "function (_self, records, options, res)\n{\n //  _this.total = 0.0;\n\n  \n\n\n      _this.total = 1 * res.raw.amount;\n        _this.bf = 1 * res.raw.amount;\n    Roo.log(\"TOTAL:\" + _this.total);\n}\n",
+                                                "load": "function (_self, records, options)\n{\n    \n    var bal = _this.bf;\n      var cleared = true;\n      var posted = true;\n    Roo.each(records, function(rec) {\n        if (!rec.data.cleared) {\n            cleared = false;\n\n        }\n        if (!rec.data.bankrec_posted) {\n            posted = false;\n        }\n        if (rec.data.doc_type != 'BF') {\n            bal += rec.data.amount *1;\n            rec.set('balance', bal);   \n        } else {\n            rec.set('balance', _this.bf);\n        }\n        \n        \n    });\n    \n    var rec = this.reader.newRow({\n        notes : 'Brought Forward',\n        balance : _this.bf,\n        doc_type : 'BF',\n        cleared : cleared,\n        bankrec_posted : posted\n    });\n    this.insert(0, [rec]);\n}",
+                                                "beforeload": "function (_self, o)\n{\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if (!s) {\n        return false;\n    }\n    o.params._group = 'bankrec';\n    o.params._name = 'all';\n    o.params['sortdate:text'] = s.data.sortdate;\n    o.params['bankaccntid:number'] =     _this.bankacct.getValue();\n\n    o.params['_cals'] = 'amount'\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'metasql_group', direction: 'ASC' }",
+                                            "|updateBalance": "function() {\n     var bal = _this.bf;\n    this.each( function(rec) {\n        if (rec.data.doc_type != 'BF') {\n            bal += rec.data.amount *1;\n            rec.set('balance', bal);   \n        } else {\n            rec.set('balance', _this.bf);\n        }\n        \n        \n    });\n}\n",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/metasql.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "idx",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'metasql_id',\n        'type': 'int'\n    },\n    {\n        'name': 'metasql_group',\n        'type': 'string'\n    },\n    {\n        'name': 'metasql_name',\n        'type': 'string'\n    },\n    {\n        'name': 'metasql_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'metasql_query',\n        'type': 'string'\n    },\n    {\n        'name': 'metasql_lastuser',\n        'type': 'string'\n    },\n    {\n        'name': 'metasql_lastupdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'metasql_grade',\n        'type': 'int'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying records {0} - {1} of {2}",
+                                            "emptyMsg": "Nothing found",
+                                            "pageSize": 50,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.bankacct = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{ \n    var curr = record.data.bankaccnt_curr_id_curr_abbr;\n    var col = _this.grid.colModel.config.length -1;\n    \n    _this.grid.colModel.setColumnHeader(col, 'Balance (' + curr +')');\n    \n    _this.grid.ds.removeAll();\n    \n    _this.wgrid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "bankaccnt_bankname",
+                                                    "editable": false,
+                                                    "emptyText": "Select bankaccnt",
+                                                    "fieldLabel": "bankaccnt",
+                                                    "forceSelection": true,
+                                                    "hiddenName": "bankaccnt_id",
+                                                    "listWidth": 400,
+                                                    "loadingText": "Searching...",
+                                                    "minChars": 2,
+                                                    "name": "bankaccnt_bankname",
+                                                    "pageSize": 50,
+                                                    "qtip": "Select bankaccnt",
+                                                    "queryParam": "",
+                                                    "selectOnFocus": true,
+                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{bankaccnt_bankname}</b> </div>",
+                                                    "triggerAction": "all",
+                                                    "typeAhead": true,
+                                                    "valueField": "bankaccnt_id",
+                                                    "width": 300,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                            },
+                                                            "*prop": "store",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ direction : 'ASC', field: 'bankaccnt_bankname' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "xtype": "HttpProxy",
+                                                                    "method": "GET",
+                                                                    "|xns": "Roo.data",
+                                                                    "|url": "baseURL + '/Roo/bankaccnt.php'"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "xtype": "JsonReader",
+                                                                    "|xns": "Roo.data",
+                                                                    "id": "id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"bankaccnt_name\",\"type\":\"string\"}]"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var o = {params : {}}; \n    if (!_this.bankacct.getValue()) {\n        return false;\n    }\n    o.params._group = 'bankrec';\n    o.params._name = 'all';\n    o.params['bankaccntid:number'] =     _this.bankacct.getValue();\n    o.params['_sum_prev'] = 'amount';\n     o.url = baseURL + '/Roo/Metasql';\n     o.method = 'GET';\n     \n     var cols = {\n        'cleared' : 'Cleared',\n        'sortdate' : 'Date',\n        'doc_type' : 'Doctype',\n        'doc_number' : 'Doc number',\n        'notes' : 'Notes',\n        'doc_curr' : 'Currency',\n        'base_amount' : 'Base Amount',\n        'doc_exchrate' : 'Exchange Rate',\n        'amount' : 'Amount (Bank Currency)'\n    };\n     var n =0;\n     for (var i in cols) {\n        \n     \n        o.params['csvCols['+n+']'] =  i\n        o.params['csvTitles['+n+']'] =  cols[i];\n        n++;\n    }\n\n     \n     new Pman.Download(o);\n    Roo.MessageBox.alert(\"Notice\", \"Should be downloading now\");\n}"
+                                                    },
+                                                    "text": "Download",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "cleared",
+                                            "header": "Cleared",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if (r.data.bankrec_posted) {\n        return 'POSTED';\n    }\n\n    var state = v   ?  '-checked' : '';\n                                    \n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "sortdate",
+                                            "header": "Date",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {   \n\n    return v ? Date.parseDate(v,'Y-m-d').format('d/M/Y') : '';\n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "doc_type",
+                                            "header": "Doctype",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "doc_number",
+                                            "header": "Doc Number",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "notes",
+                                            "header": "Notes",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "doc_curr",
+                                            "header": "Currency",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "doc_exchrate",
+                                            "header": "Exchange Rate",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? (v*1).toFixed(3) : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "base_amount",
+                                            "header": "Base Amount",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', Roo.util.Format.number(v*1,2)); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "amount",
+                                            "header": "Credit",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if (r.data.doc_type == 'BF') {\n        return '';\n    }\n    return String.format('{0}', v > 0 ? Roo.util.Format.number(v*1,2)   : ''); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "cls": "align-right",
+                                                            "decimalPrecision": 2,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "amount",
+                                            "header": "Debit",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if (r.data.doc_type == 'BF') {\n        return '';\n    }\n    return String.format('{0}', v < 0 ? Roo.util.Format.number(v*1,2): ''); }",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "cls": "align-right",
+                                                            "decimalPrecision": 2,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "balance",
+                                            "header": "Balance",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "\nfunction(v,x,r) { \n    if (r.data.doc_type == 'BF') {\n        return String.format('{0}', Roo.util.Format.number(v*1,2)); \n    }\n\n\n    //_this.total += (v*1)\n     return String.format('{0}', Roo.util.Format.number(v*1,2)); \n}",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.wpanel = this;\n    //if (_this.wgrid) {\n    //    _this.wgrid.footer.onClick('first');\n    //}\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "west",
+                            "tableName": "Groups",
+                            "title": "Pick a Date",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.wgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    //if (_this.wpanel.active) {\n    //   this.footer.onClick('first');\n    //}\n}",
+                                        "cellclick": "function (_self, rowIndex, columnIndex, e)\n{\n    var di = this.colModel.getDataIndex(columnIndex);\n\n    if (di != 'is_reconciled') {\n        return;\n    }\n     \n    var rec = this.ds.getAt(rowIndex);\n    \n    var voidit = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Bankrec.php',\n            method :'POST',\n            params : {\n                _void : 1,\n                bankaccnt_id : _this.bankacct.getValue(),\n                sotrdate : rec.data.sortdate\n                \n            },\n            success : function() {\n                _this.wgrid.footer.onClick('refresh');\n            }\n        });\n    }\n    \n    var postit = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/Bankrec.php',\n            method :'POST',\n            params : {\n                _post : 1,\n                bankaccnt_id : _this.bankacct.getValue(),\n                sotrdate : rec.data.sortdate\n                \n            },\n            success : function() {\n                _this.wgrid.footer.onClick('refresh');\n            }\n        });\n    \n    }\n    \n    if(rec.data.is_reconciled == 1){\n        voidit();\n        return;\n    }\n    \n    postit();\n    return;\n    \n    \n    \n}",
+                                        "rowclick": "function (_self, rowIndex, e)\n{\n    \n     _this.wgrid.lastSelectedRow = rowIndex;\n    \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "sortdate",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.monthSel = _self;\n}",
+                                                        "select": "function (combo, date)\n{\n    _this.grid.ds.removeAll();\n    _this.wgrid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": true,
+                                                    "format": "M Y",
+                                                    "useIso": true,
+                                                    "width": 150,
+                                                    "xtype": "MonthField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    _this.monthSel.setValue('');\n    _this.grid.ds.removeAll();\r\n    _this.wgrid.footer.onClick('first');\r\n}"
+                                                    },
+                                                    "cls": "x-btn-icon",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Fix Data",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "menu",
+                                                            "xtype": "Menu",
+                                                            "|xns": "Roo.menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n\n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to fix all the historical data? It will recreate all the posted bankrec and delect all the unpost\",\n        function (res) {\n            if(res!='yes') {\n                return;\n            \n            }\n            new Pman.Request({\n                url : baseURL + '/Roo/Bankrec.php',\n                method :'POST',\n                params : {\n                    _fix : 1\n                },\n                success : function() {\n                    if(_this.wgrid){\n                        _this.wgrid.footer.onClick('refresh');\n                    }\n                    Roo.MessageBox.alert('Notice', 'FIXED');\n                }\n            });\n    });\n\n}"
+                                                                    },
+                                                                    "cls": "x-btn-text-icon",
+                                                                    "text": "Fix historical data",
+                                                                    "xtype": "Item",
+                                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n\n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want?\",\n        function (res) {\n            if(res!='yes') {\n                return;\n            \n            }\n            new Pman.Request({\n                url : baseURL + '/Roo/Bankrec.php',\n                method :'POST',\n                params : {\n                    _closedPeriod : 1\n                },\n                success : function() {\n                    if(_this.wgrid){\n                        _this.wgrid.footer.onClick('refresh');\n                    }\n                    Roo.MessageBox.alert('Notice', 'DONE');\n                }\n            });\n    });\n\n}"
+                                                                    },
+                                                                    "cls": "x-btn-text-icon",
+                                                                    "text": "Fix Closed Periods",
+                                                                    "xtype": "Item",
+                                                                    "|icon": "Roo.rootURL + 'images/default/tree/leaf.gif'",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "selectionchange": "function (_self)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "*prop": "sm",
+                                            "singleSelect": true,
+                                            "xtype": "RowSelectionModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n\n    if (!_this.bankacct.getValue()) {\n        return false;\n    }\n    var dt = _this.monthSel.getValue();\n    \n    if(dt.length){\n        o.params['sortdate:text'] = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');\n    }\n    o.params._group = 'bankrec';\n    o.params._name = 'bydate';\n    o.params['bankaccntid:number'] =  _this.bankacct.getValue();\n    \n\n    \n}",
+                                                "load": "function (_self, records, options, res)\n{   \n    var sm = _this.wgrid.getSelectionModel();\n    \n    if(_this.wgrid.lastSelectedRow * 1 >0){\n        sm.selectRow(_this.wgrid.lastSelectedRow);\n        return;\n    }\n    \n    if (!sm.getSelections().length) {\n        sm.selectFirstRow();\n    }\n\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'sotrdate', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "timeout": 900000,
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/metasql.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'sortdate',\n        'type': 'string'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": false,
+                                            "displayMsg": "Displaying Date{0} - {1} of {2}",
+                                            "emptyMsg": "No Date found",
+                                            "pageSize": 25,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "sortdate",
+                                            "header": "Date",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {   \n\n    return v ? Date.parseDate(v,'Y-m-d').format('d/M/Y') : '';\n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "balance",
+                                            "header": "Closing Balance",
+                                            "width": 120,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    \n    var color = 'red'; // has some not 'ticked'\n    \n    if(r.data.no_records - r.data.no_posted == 0){ // all posted on that date\n        color = 'black';\n    }\n    if(r.data.no_records - r.data.no_cleared == 0 && r.data.no_posted != r.data.no_cleared){ // has 'ticked' or posted\n        color = 'blue';\n    }\n    \n    return String.format('<span style=\"color:{0}\">{1}</span>', color, Roo.util.Format.number(v*1,2)); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "reconciled",
+                                            "header": "Reconciled",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    \n    if(!v){\n        return '';\n    }\n    \n    if((r.data.no_records * 1 != r.data.no_posted * 1) || r.data.balance * 1 != v * 1){ // not match\n        \n        return '<span style=\"color:red;font-weight:bold\">' + Roo.util.Format.number(v*1,2); \n    }\n    \n    return String.format('<span style=\"color:black\">{0}</span>', Roo.util.Format.number(v*1,2)); \n        \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "is_reconciled",
+                                            "header": "Post?",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    var state = v  ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n }\n \n",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "003"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleReconcile.js b/Pman.Tab.XtupleReconcile.js
new file mode 100644 (file)
index 0000000..d920809
--- /dev/null
@@ -0,0 +1,1064 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleReconcile = new Roo.XComponent({
+    part     :  ["Xtuple","Reconcile"],
+    order    : '003-Pman.Tab.XtupleReconcile',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleAccountsTab',
+    name     : "Pman.Tab.XtupleReconcile",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            title : "Bank Reconcile",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'metasql',
+                        title : "Bank Reconcile",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                cellclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                    var clear = function(ar) 
+                                    {
+                                        var ar_in = ar;
+                                        if (ar === true) {
+                                            ar = [];
+                                            
+                                            _this.grid.ds.each(function(rec) {
+                                                if (rec.data.doc_type == 'BF') {
+                                                    return;
+                                                }
+                                                ar.push(rec);
+                                            });
+                                        }
+                                        var sortdate = false;
+                                        var data = [];
+                                        Roo.each(ar, function(rec) {
+                                            if (rec.data.cleared || rec.data.bankrec_posted) {
+                                                return;
+                                            }
+                                            if(!sortdate){
+                                                sortdate = rec.data.sortdate;
+                                            }
+                                            data.push({
+                                                 id : rec.data.id,
+                                                altid : rec.data.altid,
+                                                curr_rate : rec.data.doc_exchrate,
+                                                amount : rec.data.amount
+                                                
+                                            });
+                                        });
+                                       new Pman.Request({
+                                        url : baseURL + '/Roo/bankrecitem',
+                                            method : 'POST',
+                                            mask : 'Clearing',
+                                            params : {
+                                                bankaccnt_id : _this.bankacct.getValue(),
+                                                sortdate : sortdate,
+                                                set_clear : Roo.encode(data)
+                                            },
+                                            success : function() {
+                                                Roo.each(ar, function(rec) {
+                                                    rec.set('cleared', true);
+                                                });
+                                                if (ar_in === true) {
+                                                    _this.grid.ds.getAt(0).set('cleared', true);
+                                                }
+                                                _this.wgrid.footer.onClick('refresh');
+                                            }
+                                        });
+                                    }
+                                    
+                                    
+                                    var unclear = function(ar)
+                                    {
+                                        var ar_in = ar;
+                                        if (ar === true) {
+                                            ar = [];
+                                            
+                                            _this.grid.ds.each(function(rec) {
+                                                if (rec.data.doc_type == 'BF') {
+                                                    return;
+                                                }
+                                                ar.push(rec);
+                                            });
+                                        }
+                                        var sortdate = false;
+                                        var data = [];
+                                        Roo.each(ar, function(rec) {
+                                            if (!rec.data.cleared  || rec.data.bankrec_posted) {
+                                                return;
+                                            }
+                                            if(!sortdate){
+                                                sortdate = rec.data.sortdate;
+                                            }
+                                            data.push({
+                                                id : rec.data.id,
+                                                altid : rec.data.altid                
+                                            });
+                                        });
+                                
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/bankrecitem',
+                                            method : 'POST',
+                                            mask : 'Clearing',
+                                            params : {
+                                                bankaccnt_id : _this.bankacct.getValue(),
+                                                sortdate : sortdate,
+                                                remove_clear :Roo.encode(data)
+                                                
+                                            },
+                                            success : function() {
+                                                Roo.each(ar, function(rec) {
+                                                    rec.set('cleared', false);
+                                                });
+                                               if (ar_in === true) {
+                                                    _this.grid.ds.getAt(0).set('cleared', false);
+                                                }  
+                                                _this.wgrid.footer.onClick('refresh');
+                                            }
+                                        });
+                                     
+                                      
+                                    };
+                                    
+                                    
+                                    
+                                    var di = this.colModel.config[columnIndex].dataIndex;
+                                    if (di != 'cleared') {
+                                        return;
+                                    }
+                                    var  rec = this.ds.getAt(rowIndex);
+                                    if (rec.data.doc_type == 'BF') {
+                                    
+                                        if (rec.data.cleared) {
+                                            unclear(true);
+                                        
+                                        } else {
+                                            clear(true);
+                                        }
+                                    
+                                        return;
+                                    }
+                                    
+                                        
+                                        
+                                    if (rec.data.cleared) {
+                                    
+                                        unclear([rec]);
+                                        return;
+                                        
+                                    }
+                                    
+                                    clear([rec]);
+                                    
+                                    
+                                     
+                                         
+                                  
+                                },
+                                beforeedit : function (e)
+                                {
+                                    //    Roo.log(e);
+                                       var ch =  _this.grid.colModel.config[e.column].header;
+                                       var val = e.value *1;
+                                  // Roo.log(ch);
+                                  // Roo.log(val);
+                                
+                                       if (val > 0.0 && ch == 'Debit') {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                       if (val < 0.0 && ch == 'Credit') {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                        if (e.record.data.cleared || e.record.data.bankrec_posted) {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                        
+                                        // allow start editing..
+                                },
+                                afteredit : function (e)
+                                {
+                                
+                                    if (e.cancel) {
+                                        return;
+                                    }
+                                       var ch =  _this.grid.colModel.config[e.column].header;
+                                           var val = e.originalValue *1;
+                                      // Roo.log(ch);
+                                      // Roo.log(val);
+                                
+                                       if (val > 0.0 && ch == 'Debit') {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                       if (val < 0.0 && ch == 'Credit') {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                        if (e.record.data.cleared || e.record.data.bankrec_posted) {
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                        if (val > 0.0 && e.value < 0.0) {
+                                        Roo.log("CANCEL");  
+                                            e.record.set('amount', e.originalValue);
+                                            e.cancel = true;
+                                            return;
+                                        }
+                                        if (val < 0.0 && e.value > 0.0) {
+                                        Roo.log("CANCEL");
+                                            e.record.set('amount', e.originalValue);
+                                            e.cancel = true;
+                                            return;
+                                        } 
+                                        if (e.originalValue*1 == e.value*1) {
+                                            return;
+                                        }
+                                          
+                                        e.record.set('doc_exchrate', Math.abs(e.value  * 1)  / Math.abs(e.record.data.base_amount * 1));
+                                        Roo.log(e.record);
+                                        
+                                        _this.grid.ds.updateBalance();
+                                        // send it down the line...
+                                        new Pman.Request({
+                                            method : 'POST',
+                                            url : baseURL + '/Roo/bankrecitem',
+                                            mask : 'Saving',
+                                            params : {
+                                                bankaccnt_id : _this.bankacct.getValue(),
+                                                set_amount : Math.abs(e.value),
+                                                sortdate : e.record.data.sortdate,
+                                                source_id : e.record.data.id,
+                                                altid : e.record.data.altid
+                                            }
+                                        
+                                        });
+                                        
+                                         
+                                        
+                                        
+                                }
+                            },
+                            autoExpandColumn : 'notes',
+                            clicksToEdit : 1,
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeloadadd : function (_self, records, options, res)
+                                    {
+                                     //  _this.total = 0.0;
+                                    
+                                      
+                                    
+                                    
+                                          _this.total = 1 * res.raw.amount;
+                                            _this.bf = 1 * res.raw.amount;
+                                        Roo.log("TOTAL:" + _this.total);
+                                    },
+                                    load : function (_self, records, options)
+                                    {
+                                        
+                                        var bal = _this.bf;
+                                          var cleared = true;
+                                          var posted = true;
+                                        Roo.each(records, function(rec) {
+                                            if (!rec.data.cleared) {
+                                                cleared = false;
+                                    
+                                            }
+                                            if (!rec.data.bankrec_posted) {
+                                                posted = false;
+                                            }
+                                            if (rec.data.doc_type != 'BF') {
+                                                bal += rec.data.amount *1;
+                                                rec.set('balance', bal);   
+                                            } else {
+                                                rec.set('balance', _this.bf);
+                                            }
+                                            
+                                            
+                                        });
+                                        
+                                        var rec = this.reader.newRow({
+                                            notes : 'Brought Forward',
+                                            balance : _this.bf,
+                                            doc_type : 'BF',
+                                            cleared : cleared,
+                                            bankrec_posted : posted
+                                        });
+                                        this.insert(0, [rec]);
+                                    },
+                                    beforeload : function (_self, o)
+                                    {
+                                        var s = _this.wgrid.getSelectionModel().getSelected();
+                                        
+                                        if (!s) {
+                                            return false;
+                                        }
+                                        o.params._group = 'bankrec';
+                                        o.params._name = 'all';
+                                        o.params['sortdate:text'] = s.data.sortdate;
+                                        o.params['bankaccntid:number'] =     _this.bankacct.getValue();
+                                    
+                                        o.params['_cals'] = 'amount'
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'metasql_group', direction: 'ASC' },
+                                updateBalance : function() {
+                                     var bal = _this.bf;
+                                    this.each( function(rec) {
+                                        if (rec.data.doc_type != 'BF') {
+                                            bal += rec.data.amount *1;
+                                            rec.set('balance', bal);   
+                                        } else {
+                                            rec.set('balance', _this.bf);
+                                        }
+                                        
+                                        
+                                    });
+                                },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/metasql.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'idx',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'metasql_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'metasql_group',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'metasql_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'metasql_notes',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'metasql_query',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'metasql_lastuser',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'metasql_lastupdate',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'metasql_grade',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : "Displaying records {0} - {1} of {2}",
+                                emptyMsg : "Nothing found",
+                                pageSize : 50
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.bankacct = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            { 
+                                                var curr = record.data.bankaccnt_curr_id_curr_abbr;
+                                                var col = _this.grid.colModel.config.length -1;
+                                                
+                                                _this.grid.colModel.setColumnHeader(col, 'Balance (' + curr +')');
+                                                
+                                                _this.grid.ds.removeAll();
+                                                
+                                                _this.wgrid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'bankaccnt_bankname',
+                                        editable : false,
+                                        emptyText : "Select bankaccnt",
+                                        fieldLabel : 'bankaccnt',
+                                        forceSelection : true,
+                                        hiddenName : 'bankaccnt_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'bankaccnt_bankname',
+                                        pageSize : 50,
+                                        qtip : "Select bankaccnt",
+                                        queryParam : '',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{bankaccnt_bankname}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        valueField : 'bankaccnt_id',
+                                        width : 300,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'bankaccnt_bankname' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/bankaccnt.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"id","type":"int"},{"name":"bankaccnt_name","type":"string"}]
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var o = {params : {}}; 
+                                                if (!_this.bankacct.getValue()) {
+                                                    return false;
+                                                }
+                                                o.params._group = 'bankrec';
+                                                o.params._name = 'all';
+                                                o.params['bankaccntid:number'] =     _this.bankacct.getValue();
+                                                o.params['_sum_prev'] = 'amount';
+                                                 o.url = baseURL + '/Roo/Metasql';
+                                                 o.method = 'GET';
+                                                 
+                                                 var cols = {
+                                                    'cleared' : 'Cleared',
+                                                    'sortdate' : 'Date',
+                                                    'doc_type' : 'Doctype',
+                                                    'doc_number' : 'Doc number',
+                                                    'notes' : 'Notes',
+                                                    'doc_curr' : 'Currency',
+                                                    'base_amount' : 'Base Amount',
+                                                    'doc_exchrate' : 'Exchange Rate',
+                                                    'amount' : 'Amount (Bank Currency)'
+                                                };
+                                                 var n =0;
+                                                 for (var i in cols) {
+                                                    
+                                                 
+                                                    o.params['csvCols['+n+']'] =  i
+                                                    o.params['csvTitles['+n+']'] =  cols[i];
+                                                    n++;
+                                                }
+                                            
+                                                 
+                                                 new Pman.Download(o);
+                                                Roo.MessageBox.alert("Notice", "Should be downloading now");
+                                            }
+                                        },
+                                        text : "Download"
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cleared',
+                                    header : 'Cleared',
+                                    width : 50,
+                                    renderer : function(v,x,r) { 
+                                        if (r.data.bankrec_posted) {
+                                            return 'POSTED';
+                                        }
+                                    
+                                        var state = v   ?  '-checked' : '';
+                                                                        
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'sortdate',
+                                    header : 'Date',
+                                    width : 75,
+                                    renderer : function(v) {   
+                                    
+                                        return v ? Date.parseDate(v,'Y-m-d').format('d/M/Y') : '';
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'doc_type',
+                                    header : 'Doctype',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'doc_number',
+                                    header : 'Doc Number',
+                                    width : 120,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'notes',
+                                    header : 'Notes',
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'doc_curr',
+                                    header : 'Currency',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'doc_exchrate',
+                                    header : 'Exchange Rate',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? (v*1).toFixed(3) : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'base_amount',
+                                    header : 'Base Amount',
+                                    width : 120,
+                                    renderer : function(v) { return String.format('{0}', Roo.util.Format.number(v*1,2)); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'amount',
+                                    header : 'Credit',
+                                    width : 120,
+                                    renderer : function(v,x,r) { 
+                                        if (r.data.doc_type == 'BF') {
+                                            return '';
+                                        }
+                                        return String.format('{0}', v > 0 ? Roo.util.Format.number(v*1,2)   : ''); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            cls : 'align-right',
+                                            decimalPrecision : 2
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'amount',
+                                    header : 'Debit',
+                                    width : 120,
+                                    renderer : function(v,x,r) { 
+                                        if (r.data.doc_type == 'BF') {
+                                            return '';
+                                        }
+                                        return String.format('{0}', v < 0 ? Roo.util.Format.number(v*1,2): ''); },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            cls : 'align-right',
+                                            decimalPrecision : 2
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'balance',
+                                    header : 'Balance',
+                                    width : 120,
+                                    renderer : function(v,x,r) { 
+                                        if (r.data.doc_type == 'BF') {
+                                            return String.format('{0}', Roo.util.Format.number(v*1,2)); 
+                                        }
+                                    
+                                    
+                                        //_this.total += (v*1)
+                                         return String.format('{0}', Roo.util.Format.number(v*1,2)); 
+                                    }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.wpanel = this;
+                                //if (_this.wgrid) {
+                                //    _this.wgrid.footer.onClick('first');
+                                //}
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'west',
+                        tableName : 'Groups',
+                        title : "Pick a Date",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.wgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    //if (_this.wpanel.active) {
+                                    //   this.footer.onClick('first');
+                                    //}
+                                },
+                                cellclick : function (_self, rowIndex, columnIndex, e)
+                                {
+                                    var di = this.colModel.getDataIndex(columnIndex);
+                                
+                                    if (di != 'is_reconciled') {
+                                        return;
+                                    }
+                                     
+                                    var rec = this.ds.getAt(rowIndex);
+                                    
+                                    var voidit = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/Bankrec.php',
+                                            method :'POST',
+                                            params : {
+                                                _void : 1,
+                                                bankaccnt_id : _this.bankacct.getValue(),
+                                                sotrdate : rec.data.sortdate
+                                                
+                                            },
+                                            success : function() {
+                                                _this.wgrid.footer.onClick('refresh');
+                                            }
+                                        });
+                                    }
+                                    
+                                    var postit = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/Bankrec.php',
+                                            method :'POST',
+                                            params : {
+                                                _post : 1,
+                                                bankaccnt_id : _this.bankacct.getValue(),
+                                                sotrdate : rec.data.sortdate
+                                                
+                                            },
+                                            success : function() {
+                                                _this.wgrid.footer.onClick('refresh');
+                                            }
+                                        });
+                                    
+                                    }
+                                    
+                                    if(rec.data.is_reconciled == 1){
+                                        voidit();
+                                        return;
+                                    }
+                                    
+                                    postit();
+                                    return;
+                                    
+                                    
+                                    
+                                },
+                                rowclick : function (_self, rowIndex, e)
+                                {
+                                    
+                                     _this.wgrid.lastSelectedRow = rowIndex;
+                                    
+                                }
+                            },
+                            autoExpandColumn : 'sortdate',
+                            loadMask : true,
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'MonthField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.monthSel = _self;
+                                            },
+                                            select : function (combo, date)
+                                            {
+                                                _this.grid.ds.removeAll();
+                                                _this.wgrid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        format : 'M Y',
+                                        useIso : true,
+                                        width : 150
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                _this.monthSel.setValue('');
+                                                _this.grid.ds.removeAll();
+                                                _this.wgrid.footer.onClick('first');
+                                            }
+                                        },
+                                        cls : 'x-btn-icon',
+                                        icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        cls : 'x-btn-text-icon',
+                                        text : "Fix Data",
+                                        icon : Roo.rootURL + 'images/default/tree/leaf.gif',
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                        
+                                                            Roo.MessageBox.confirm("Confirm", "Are you sure you want to fix all the historical data? It will recreate all the posted bankrec and delect all the unpost",
+                                                                function (res) {
+                                                                    if(res!='yes') {
+                                                                        return;
+                                                                    
+                                                                    }
+                                                                    new Pman.Request({
+                                                                        url : baseURL + '/Roo/Bankrec.php',
+                                                                        method :'POST',
+                                                                        params : {
+                                                                            _fix : 1
+                                                                        },
+                                                                        success : function() {
+                                                                            if(_this.wgrid){
+                                                                                _this.wgrid.footer.onClick('refresh');
+                                                                            }
+                                                                            Roo.MessageBox.alert('Notice', 'FIXED');
+                                                                        }
+                                                                    });
+                                                            });
+                                                        
+                                                        }
+                                                    },
+                                                    cls : 'x-btn-text-icon',
+                                                    text : "Fix historical data",
+                                                    icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                        
+                                                            Roo.MessageBox.confirm("Confirm", "Are you sure you want?",
+                                                                function (res) {
+                                                                    if(res!='yes') {
+                                                                        return;
+                                                                    
+                                                                    }
+                                                                    new Pman.Request({
+                                                                        url : baseURL + '/Roo/Bankrec.php',
+                                                                        method :'POST',
+                                                                        params : {
+                                                                            _closedPeriod : 1
+                                                                        },
+                                                                        success : function() {
+                                                                            if(_this.wgrid){
+                                                                                _this.wgrid.footer.onClick('refresh');
+                                                                            }
+                                                                            Roo.MessageBox.alert('Notice', 'DONE');
+                                                                        }
+                                                                    });
+                                                            });
+                                                        
+                                                        }
+                                                    },
+                                                    cls : 'x-btn-text-icon',
+                                                    text : "Fix Closed Periods",
+                                                    icon : Roo.rootURL + 'images/default/tree/leaf.gif'
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            sm : {
+                                xtype: 'RowSelectionModel',
+                                xns: Roo.grid,
+                                listeners : {
+                                    selectionchange : function (_self)
+                                    {
+                                        _this.grid.footer.onClick('first');
+                                    }
+                                },
+                                singleSelect : true
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                    
+                                        if (!_this.bankacct.getValue()) {
+                                            return false;
+                                        }
+                                        var dt = _this.monthSel.getValue();
+                                        
+                                        if(dt.length){
+                                            o.params['sortdate:text'] = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');
+                                        }
+                                        o.params._group = 'bankrec';
+                                        o.params._name = 'bydate';
+                                        o.params['bankaccntid:number'] =  _this.bankacct.getValue();
+                                        
+                                    
+                                        
+                                    },
+                                    load : function (_self, records, options, res)
+                                    {   
+                                        var sm = _this.wgrid.getSelectionModel();
+                                        
+                                        if(_this.wgrid.lastSelectedRow * 1 >0){
+                                            sm.selectRow(_this.wgrid.lastSelectedRow);
+                                            return;
+                                        }
+                                        
+                                        if (!sm.getSelections().length) {
+                                            sm.selectFirstRow();
+                                        }
+                                    
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'sotrdate', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    timeout : 900000,
+                                    url : baseURL + '/Roo/metasql.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'sortdate',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : false,
+                                displayMsg : "Displaying Date{0} - {1} of {2}",
+                                emptyMsg : "No Date found",
+                                pageSize : 25
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'sortdate',
+                                    header : 'Date',
+                                    width : 100,
+                                    renderer : function(v) {   
+                                    
+                                        return v ? Date.parseDate(v,'Y-m-d').format('d/M/Y') : '';
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'balance',
+                                    header : 'Closing Balance',
+                                    width : 120,
+                                    renderer : function(v,x,r) { 
+                                        
+                                        var color = 'red'; // has some not 'ticked'
+                                        
+                                        if(r.data.no_records - r.data.no_posted == 0){ // all posted on that date
+                                            color = 'black';
+                                        }
+                                        if(r.data.no_records - r.data.no_cleared == 0 && r.data.no_posted != r.data.no_cleared){ // has 'ticked' or posted
+                                            color = 'blue';
+                                        }
+                                        
+                                        return String.format('<span style="color:{0}">{1}</span>', color, Roo.util.Format.number(v*1,2)); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'reconciled',
+                                    header : 'Reconciled',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        
+                                        if(!v){
+                                            return '';
+                                        }
+                                        
+                                        if((r.data.no_records * 1 != r.data.no_posted * 1) || r.data.balance * 1 != v * 1){ // not match
+                                            
+                                            return '<span style="color:red;font-weight:bold">' + Roo.util.Format.number(v*1,2); 
+                                        }
+                                        
+                                        return String.format('<span style="color:black">{0}</span>', Roo.util.Format.number(v*1,2)); 
+                                            
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'is_reconciled',
+                                    header : 'Post?',
+                                    width : 50,
+                                    renderer : function(v,x,r) { 
+                                        var state = v  ?  '-checked' : '';
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                     }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                west : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    width : 400
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSales.bjs b/Pman.Tab.XtupleSales.bjs
new file mode 100644 (file)
index 0000000..163591e
--- /dev/null
@@ -0,0 +1,121 @@
+{
+    "id": "roo-file-297",
+    "name": "Pman.Tab.XtupleSales",
+    "parent": "Pman",
+    "title": "Pman.Tab.XtupleSales",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSales.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function () {\n   \n    \n    if (typeof(Pman.Login) != 'undefined') {\n         var db = baseURL.split('.php').shift().substr(-2,2)\n    \n        this.setTitle('Sales (' + Pman.Login.authUser.dbname +')');\n        \n    }\n    \n    (function() {\n         var c= _this.layout.getRegion('center');\n         c.showPanel(c.getActivePanel());\n    \n             }).defer(100);\n}"
+            },
+            "region": "center",
+            "title": "Sales",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "xtype": "BorderLayout",
+                    "|xns": "Roo",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo",
+                            "*prop": "east",
+                            "title": "last edited",
+                            "collapsible": true,
+                            "width": "150",
+                            "split": true
+                        },
+                        {
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo",
+                            "*prop": "center",
+                            "tabPosition": "top"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "east",
+                            "tableName": "events",
+                            "title": "events",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    _this.dialog = Pman.Dialog.XtupleSalesOrder;\n    \n    data = this.getDataSource().getAt(rowIndex).data;\n    \n    _this.dialog.show( \n        { cohead_id : data.on_id_cohead_id } , \n        function() {\n            _this.grid.footer.onClick('first');\n            Pman.Tab.XtupleSalesOrder.grid.footer.onClick('refresh');\n            \n        }\n    ); \n}\n"
+                                    },
+                                    "*prop": "grid",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"on_id\",\"columnshort\":\"on_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"on_id\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "autoExpandColumn": "on_id",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    options.params._join = 'cohead';\n    options.params.on_table = 'cohead';\n    options.params._join_cols   = 'cohead_number,cohead_id';\n    options.params.sort = '';\n    options.params.person_id = Pman.Login.authUser.id;\n    \n     /// on_table=cohead\n        //   &_join=cohead\n        //   &_join_cols=cohead_number\n        //    &_columns=on_id_cohead_number,event_when << this is ignored at present.\n        // max(event_when) is not supported... by any query yet..\n        \n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"on_id\",\"columnshort\":\"on_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"on_id\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|url": "baseURL + '/Roo/events.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    ".builderCfg": "{\"cols\":[{\"table\":\"events\",\"column\":\"on_id\",\"columnshort\":\"on_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}],\"cols_ex\":[\"on_id\"],\"table\":\"events\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'on_id',\n        'type': 'int'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": ".",
+                                            "emptyMsg": ".",
+                                            "pageSize": 25,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"events\",\"column\":\"on_id\",\"columnshort\":\"on_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}",
+                                            "dataIndex": "on_id_cohead_number",
+                                            "header": "on",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "002"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSales.js b/Pman.Tab.XtupleSales.js
new file mode 100644 (file)
index 0000000..cd80382
--- /dev/null
@@ -0,0 +1,169 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSales = new Roo.XComponent({
+    part     :  ["Xtuple","Sales"],
+    order    : '002-Pman.Tab.XtupleSales',
+    region   : 'center',
+    parent   : 'Pman',
+    name     : "Pman.Tab.XtupleSales",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            listeners : {
+                activate : function () {
+                   
+                    
+                    if (typeof(Pman.Login) != 'undefined') {
+                         var db = baseURL.split('.php').shift().substr(-2,2)
+                    
+                        this.setTitle('Sales (' + Pman.Login.authUser.dbname +')');
+                        
+                    }
+                    
+                    (function() {
+                         var c= _this.layout.getRegion('center');
+                         c.showPanel(c.getActivePanel());
+                    
+                             }).defer(100);
+                }
+            },
+            region : 'center',
+            title : "Sales",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'east',
+                        tableName : 'events',
+                        title : "events",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    _this.dialog = Pman.Dialog.XtupleSalesOrder;
+                                    
+                                    data = this.getDataSource().getAt(rowIndex).data;
+                                    
+                                    _this.dialog.show( 
+                                        { cohead_id : data.on_id_cohead_id } , 
+                                        function() {
+                                            _this.grid.footer.onClick('first');
+                                            Pman.Tab.XtupleSalesOrder.grid.footer.onClick('refresh');
+                                            
+                                        }
+                                    ); 
+                                }
+                            },
+                            autoExpandColumn : 'on_id',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        options.params._join = 'cohead';
+                                        options.params.on_table = 'cohead';
+                                        options.params._join_cols   = 'cohead_number,cohead_id';
+                                        options.params.sort = '';
+                                        options.params.person_id = Pman.Login.authUser.id;
+                                        
+                                         /// on_table=cohead
+                                            //   &_join=cohead
+                                            //   &_join_cols=cohead_number
+                                            //    &_columns=on_id_cohead_number,event_when << this is ignored at present.
+                                            // max(event_when) is not supported... by any query yet..
+                                            
+                                    }
+                                },
+                                remoteSort : true,
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/events.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'on_id',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : ".",
+                                emptyMsg : ".",
+                                pageSize : 25
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'on_id_cohead_number',
+                                    header : 'on',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                east : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    title : "last edited",
+                    collapsible : true,
+                    width : '150',
+                    split : true
+                },
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    tabPosition : 'top'
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSalesHistory.bjs b/Pman.Tab.XtupleSalesHistory.bjs
new file mode 100644 (file)
index 0000000..4cd69e9
--- /dev/null
@@ -0,0 +1,721 @@
+{
+    "id": "roo-file-332",
+    "name": "Pman.Tab.XtupleSalesHistory",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "Pman.Tab.XtupleSalesHistory",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSalesHistory.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.hpanel = this;\n    if (_this.hgrid) {\n        _this.hgrid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "cohist",
+            "title": "Sales History",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.hgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.hpanel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "item_descrip1",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n  \n    Roo.apply(o.params, {\n        _group : 'salesHistory',\n        _name : 'bydate',\n     \n        'credit:text' : 'credit',\n        'return:text' : 'return',\n        'includeFormatted:int' :  1,\n        'startDate:text' : _this.dateFrom.getValue(),\n        'endDate:text' :  _this.dateTo.getValue()\n        \n    });\n    \n    if (_this.custSel.getValue()) {\n       o.params['cust_id:number'] = _this.custSel.getValue();\n    }\n    \n    if (_this.countrySel.getValue()) {\n       o.params['addr_country:text'] = _this.countrySel.getValue();\n    }\n    \n    if (_this.postalCodeSel.getValue()) {\n       o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();\n    }\n    \n    if (_this.itemSel.getValue()) {\n       o.params['item_id:number'] = _this.itemSel.getValue();\n    }\n    \n    if (_this.orderRep.getValue()) {\n       o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();\n    }\n    \n    if (_this.custRep.getValue()) {\n       o.params['cust_salesrep_id:number'] = _this.custRep.getValue();\n    }\n    \n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'cohist_shipvia', direction: 'ASC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "method": "GET",
+                                    "xtype": "HttpProxy",
+                                    "|url": "baseURL + '/Roo/metasql.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'cohist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_shipdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_shipvia',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_ordernumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_orderdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_invcnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_invcdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_qtyshipped',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_unitprice',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_shipto_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_salesrep_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_duedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_billtoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_billtozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoname',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress1',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress2',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptoaddress3',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptocity',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptostate',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_shiptozip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_commission',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_commissionpaid',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_unitcost',\n        'type': 'float'\n    },\n    {\n        'name': 'cohist_misc_type',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_misc_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_misc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_doctype',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_promisedate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'cohist_ponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_sequence',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_base',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_curr_id_curr_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id_curr_symbol',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_curr_id_curr_abbr',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_code',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxzone_id_taxzone_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohist_taxtype_id_taxtype_sys',\n        'type': 'int'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "displayInfo": true,
+                            "displayMsg": "Displaying Sales History {0} - {1} of {2}",
+                            "emptyMsg": "No cohist found",
+                            "pageSize": 25,
+                            "xtype": "PagingToolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "text": "<span class=\"sales-footer-text\"></span>",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n   _this.custSel = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "emptyText": "Select Customer",
+                                    "fieldLabel": "cust_name",
+                                    "forceSelection": true,
+                                    "hiddenName": "cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Customer",
+                                    "queryParam": "query[cust_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "cust_id",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.countrySel = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "addr_country",
+                                    "editable": true,
+                                    "emptyText": "Select Country",
+                                    "fieldLabel": "addr_country",
+                                    "forceSelection": true,
+                                    "hiddenName": "addr_country",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "addr_country",
+                                    "pageSize": 20,
+                                    "qtip": "Select Country",
+                                    "queryParam": "query[addr_country]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_country}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "addr_country",
+                                    "width": 100,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params._distinct = 'addr_country';\n    o.params._columns = 'addr_country';   \n    o.params['!addr_country'] = '';        \n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'addr_country' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/addr.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "addr_country",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"addr_country\",\"type\":\"string\"}]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.postalCodeSel = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "addr_postalcode",
+                                    "editable": true,
+                                    "emptyText": "Select Postal Code",
+                                    "fieldLabel": "addr_postalcode",
+                                    "forceSelection": true,
+                                    "hiddenName": "addr_postalcode",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "addr_postalcode",
+                                    "pageSize": 20,
+                                    "qtip": "Select Postal Code",
+                                    "queryParam": "query[addr_postalcode]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{addr_postalcode}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "addr_postalcode",
+                                    "width": 100,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params._distinct = 'addr_postalcode';\n    o.params._columns = 'addr_postalcode';   \n    o.params['!addr_postalcode'] = '';        \n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'addr_postalcode' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/addr.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "addr_postalcode",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"addr_postalcode\",\"type\":\"string\"}]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n   _this.itemSel = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "item_number",
+                                    "editable": true,
+                                    "emptyText": "Select Item Number",
+                                    "fieldLabel": "item_number",
+                                    "forceSelection": true,
+                                    "hiddenName": "item_number",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "item_number",
+                                    "pageSize": 20,
+                                    "qtip": "Select Item Number",
+                                    "queryParam": "query[number_or_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{item_number}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "item_id",
+                                    "width": 100,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'item_number' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Item.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "item_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"item_id\",\"type\":\"int\"},\"item_number\"]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n   _this.orderRep = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "salesrep_name",
+                                    "editable": true,
+                                    "emptyText": "Order Sales Rep",
+                                    "fieldLabel": "Order Sales Rep",
+                                    "forceSelection": true,
+                                    "hiddenName": "salesrep_name",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "salesrep_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Order Sales Rep",
+                                    "queryParam": "query[name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "salesrep_id",
+                                    "width": 120,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.salesrep_active = 1\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'salesrep_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Salesrep.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "salesrep_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"}]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n   _this.custRep = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "salesrep_name",
+                                    "editable": true,
+                                    "emptyText": "Customer Sales Rep",
+                                    "fieldLabel": "Customer Sales Rep",
+                                    "forceSelection": true,
+                                    "hiddenName": "salesrep_name",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "salesrep_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select Customer Sales Rep",
+                                    "queryParam": "query[name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{salesrep_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "salesrep_id",
+                                    "width": 120,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params.salesrep_active = 1\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'salesrep_id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Salesrep.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "salesrep_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[{\"name\":\"salesrep_id\",\"type\":\"int\"}]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "text": "From",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.dateFrom = _self;\n}"
+                                    },
+                                    "format": "d/M/Y",
+                                    "useIso": true,
+                                    "xtype": "DateField",
+                                    "|value": "(function() {return (new Date()).add(Date.MONTH, -3); })()",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "text": "To",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n_this.dateTo = _self;\n}"
+                                    },
+                                    "format": "d/M/Y",
+                                    "useIso": true,
+                                    "xtype": "DateField",
+                                    "|value": "(function() {return (new Date()) })()",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n    _this.hgrid.footer.onClick('first');\n}"
+                                    },
+                                    "text": "Refresh",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "text": "Download",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n  var o = { params : {}};\n     Roo.apply(o.params, {\n        _group : 'salesHistory',\n        _name : 'bydate',\n        csvCols : '*', csvTitles : '*',\n        'credit:text' : 'credit',\n        'return:text' : 'return',\n        'includeFormatted:int' :  1,\n        'startDate:text' : _this.dateFrom.getValue(),\n        'endDate:text' :  _this.dateTo.getValue(),\n        limit : 99999\n        \n    });\n    \n    if (_this.custSel.getValue()) {\n       o.params['cust_id:number'] = _this.custSel.getValue();\n    }\n    \n    if (_this.countrySel.getValue()) {\n       o.params['addr_country:text'] = _this.countrySel.getValue();\n    }\n    \n    if (_this.postalCodeSel.getValue()) {\n       o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();\n    }\n    \n    if (_this.itemSel.getValue()) {\n       o.params['item_id:number'] = _this.itemSel.getValue();\n    }\n    \n    if (_this.orderRep.getValue()) {\n       o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();\n    }\n    \n    if (_this.custRep.getValue()) {\n       o.params['cust_salesrep_id:number'] = _this.custRep.getValue();\n    }\n    \n    \n    new Pman.Download({\n        url: baseURL + '/Roo/Metasql',\n        params : o.params,\n        limit : 100000,\n        newWindow : true\n    });\n}"
+                                                    },
+                                                    "text": "Sales History",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n var o = { params : {}};\n     Roo.apply(o.params, {\n        _group : 'salesHistory',\n        _name : 'stockist',\n      csvCols : '*', csvTitles : '*',\n        'credit:text' : 'credit',\n        'return:text' : 'return',\n        'includeFormatted:int' :  1,\n        'startDate:text' : _this.dateFrom.getValue(),\n        'endDate:text' :  _this.dateTo.getValue(),\n        limit : 99999\n        \n    });\n    \n    if (_this.custSel.getValue()) {\n       o.params['cust_id:number'] = _this.custSel.getValue();\n    }\n    \n    if (_this.countrySel.getValue()) {\n       o.params['addr_country:text'] = _this.countrySel.getValue();\n    }\n    \n    if (_this.postalCodeSel.getValue()) {\n       o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();\n    }\n    \n    if (_this.itemSel.getValue()) {\n       o.params['item_id:number'] = _this.itemSel.getValue();\n    }\n    \n    if (_this.orderRep.getValue()) {\n       o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();\n    }\n    \n    if (_this.custRep.getValue()) {\n       o.params['cust_salesrep_id:number'] = _this.custRep.getValue();\n    }\n    \n    \n    new Pman.Download({\n        url: baseURL + '/Roo/Metasql',\n        params : o.params,\n        limit : 100000,\n        newWindow : true\n    });\n}"
+                                                    },
+                                                    "text": "Stockists Summary",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_id",
+                            "header": "Cust#",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_name",
+                            "header": "Customer",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "order_salesrep_name",
+                            "header": "Order Sales Rep",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_salesrep_name",
+                            "header": "Customer Sales Rep",
+                            "hidden": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "addr_country",
+                            "header": "Country",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "addr_city",
+                            "header": "City",
+                            "hidden": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "addr_state",
+                            "header": "State",
+                            "hidden": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "addr_postalcode",
+                            "header": "Postal Code",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cohist_ordernumber",
+                            "header": "Order",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cohead_orderdate",
+                            "header": "Order date",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invmonth",
+                            "header": "Invoice Month",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n   \n    return String.format('{0}', v);\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cohist_invcdate",
+                            "header": "Invoice date",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    var d = Date.parseDate(v, 'Y-m-d');\n    return String.format('{0}', d ? d.format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cohist_invcnumber",
+                            "header": "Invoice#",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "item_brand",
+                            "header": "Brand",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v   : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "item_number",
+                            "header": "Item No.",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v   : ''); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "item_descrip1",
+                            "header": "Description",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cohist_qtyshipped",
+                            "header": "Shipped",
+                            "width": 70,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return parseInt(v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "currabbr",
+                            "header": "Currency",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v.split(/\\s+/)[0]); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "cohist_unitprice",
+                            "header": "Unit Price",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "extprice",
+                            "header": "Ext Cost",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "extpricebase",
+                            "header": "Ext Price (Base)",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "baseunitprice",
+                            "header": "Unit Price (Base)",
+                            "hidden": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "basefifovalue",
+                            "header": "Fifo Cost",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return Roo.util.Format.number( v, 2); }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "400"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSalesHistory.js b/Pman.Tab.XtupleSalesHistory.js
new file mode 100644 (file)
index 0000000..0e0702c
--- /dev/null
@@ -0,0 +1,1083 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSalesHistory = new Roo.XComponent({
+    part     :  ["Xtuple","SalesHistory"],
+    order    : '400-Pman.Tab.XtupleSalesHistory',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "Pman.Tab.XtupleSalesHistory",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.hpanel = this;
+                    if (_this.hgrid) {
+                        _this.hgrid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'cohist',
+            title : "Sales History",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.hgrid = this; 
+                        //_this.dialog = Pman.Dialog.FILL_IN
+                        if (_this.hpanel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                        if (!_this.dialog) return;
+                        _this.dialog.show( this.getDataSource().getAt(rowIndex), function() {
+                            _this.grid.footer.onClick('first');
+                        }); 
+                    }
+                },
+                autoExpandColumn : 'item_descrip1',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                          
+                            Roo.apply(o.params, {
+                                _group : 'salesHistory',
+                                _name : 'bydate',
+                             
+                                'credit:text' : 'credit',
+                                'return:text' : 'return',
+                                'includeFormatted:int' :  1,
+                                'startDate:text' : _this.dateFrom.getValue(),
+                                'endDate:text' :  _this.dateTo.getValue()
+                                
+                            });
+                            
+                            if (_this.custSel.getValue()) {
+                               o.params['cust_id:number'] = _this.custSel.getValue();
+                            }
+                            
+                            if (_this.countrySel.getValue()) {
+                               o.params['addr_country:text'] = _this.countrySel.getValue();
+                            }
+                            
+                            if (_this.postalCodeSel.getValue()) {
+                               o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();
+                            }
+                            
+                            if (_this.itemSel.getValue()) {
+                               o.params['item_id:number'] = _this.itemSel.getValue();
+                            }
+                            
+                            if (_this.orderRep.getValue()) {
+                               o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();
+                            }
+                            
+                            if (_this.custRep.getValue()) {
+                               o.params['cust_salesrep_id:number'] = _this.custRep.getValue();
+                            }
+                            
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'cohist_shipvia', direction: 'ASC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/metasql.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'cohist_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_cust_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_itemsite_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_shipdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cohist_shipvia',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_ordernumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_orderdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cohist_invcnumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_invcdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cohist_qtyshipped',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cohist_unitprice',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cohist_shipto_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_salesrep_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_duedate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cohist_imported',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_billtoname',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtoaddress1',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtoaddress2',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtoaddress3',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtocity',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtostate',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_billtozip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptoname',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptoaddress1',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptoaddress2',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptoaddress3',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptocity',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptostate',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_shiptozip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_commission',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cohist_commissionpaid',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_unitcost',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'cohist_misc_type',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_misc_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_misc_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_doctype',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_promisedate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'cohist_ponumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_curr_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_sequence',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_taxtype_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_taxzone_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_curr_id_curr_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_curr_id_curr_base',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_curr_id_curr_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_curr_id_curr_symbol',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_curr_id_curr_abbr',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_taxzone_id_taxzone_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_taxzone_id_taxzone_code',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_taxzone_id_taxzone_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_taxtype_id_taxtype_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'cohist_taxtype_id_taxtype_name',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_taxtype_id_taxtype_descrip',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'cohist_taxtype_id_taxtype_sys',
+                                'type': 'int'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    displayInfo : true,
+                    displayMsg : "Displaying Sales History {0} - {1} of {2}",
+                    emptyMsg : "No cohist found",
+                    pageSize : 25,
+                    items : [
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "<span class=\"sales-footer-text\"></span>"
+                        }
+                    ]
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                   _this.custSel = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'cust_name',
+                            editable : true,
+                            emptyText : "Select Customer",
+                            fieldLabel : 'cust_name',
+                            forceSelection : true,
+                            hiddenName : 'cust_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'cust_name',
+                            pageSize : 20,
+                            qtip : "Select Customer",
+                            queryParam : 'query[cust_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'cust_id',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/custinfo.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'cust_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.countrySel = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'addr_country',
+                            editable : true,
+                            emptyText : "Select Country",
+                            fieldLabel : 'addr_country',
+                            forceSelection : true,
+                            hiddenName : 'addr_country',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'addr_country',
+                            pageSize : 20,
+                            qtip : "Select Country",
+                            queryParam : 'query[addr_country]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_country}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'addr_country',
+                            width : 100,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params._distinct = 'addr_country';
+                                        o.params._columns = 'addr_country';   
+                                        o.params['!addr_country'] = '';        
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'addr_country' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/addr.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'addr_country',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"addr_country","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.postalCodeSel = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'addr_postalcode',
+                            editable : true,
+                            emptyText : "Select Postal Code",
+                            fieldLabel : 'addr_postalcode',
+                            forceSelection : true,
+                            hiddenName : 'addr_postalcode',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'addr_postalcode',
+                            pageSize : 20,
+                            qtip : "Select Postal Code",
+                            queryParam : 'query[addr_postalcode]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{addr_postalcode}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'addr_postalcode',
+                            width : 100,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params._distinct = 'addr_postalcode';
+                                        o.params._columns = 'addr_postalcode';   
+                                        o.params['!addr_postalcode'] = '';        
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'addr_postalcode' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/addr.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'addr_postalcode',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"addr_postalcode","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                   _this.itemSel = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'item_number',
+                            editable : true,
+                            emptyText : "Select Item Number",
+                            fieldLabel : 'item_number',
+                            forceSelection : true,
+                            hiddenName : 'item_number',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'item_number',
+                            pageSize : 20,
+                            qtip : "Select Item Number",
+                            queryParam : 'query[number_or_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{item_number}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'item_id',
+                            width : 100,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'item_number' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Item.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'item_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"item_id","type":"int"},"item_number"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                   _this.orderRep = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'salesrep_name',
+                            editable : true,
+                            emptyText : "Order Sales Rep",
+                            fieldLabel : 'Order Sales Rep',
+                            forceSelection : true,
+                            hiddenName : 'salesrep_name',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'salesrep_name',
+                            pageSize : 20,
+                            qtip : "Select Order Sales Rep",
+                            queryParam : 'query[name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'salesrep_id',
+                            width : 120,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params.salesrep_active = 1
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'salesrep_id' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Salesrep.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'salesrep_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"salesrep_id","type":"int"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                   _this.custRep = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'salesrep_name',
+                            editable : true,
+                            emptyText : "Customer Sales Rep",
+                            fieldLabel : 'Customer Sales Rep',
+                            forceSelection : true,
+                            hiddenName : 'salesrep_name',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'salesrep_name',
+                            pageSize : 20,
+                            qtip : "Select Customer Sales Rep",
+                            queryParam : 'query[name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{salesrep_name}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'salesrep_id',
+                            width : 120,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params.salesrep_active = 1
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'salesrep_id' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Salesrep.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'salesrep_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"salesrep_id","type":"int"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "From"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.dateFrom = _self;
+                                }
+                            },
+                            format : 'd/M/Y',
+                            useIso : true,
+                            value : (function() {return (new Date()).add(Date.MONTH, -3); })()
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "To"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                _this.dateTo = _self;
+                                }
+                            },
+                            format : 'd/M/Y',
+                            useIso : true,
+                            value : (function() {return (new Date()) })()
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    _this.hgrid.footer.onClick('first');
+                                }
+                            },
+                            text : "Refresh"
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            text : "Download",
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                              var o = { params : {}};
+                                                 Roo.apply(o.params, {
+                                                    _group : 'salesHistory',
+                                                    _name : 'bydate',
+                                                    csvCols : '*', csvTitles : '*',
+                                                    'credit:text' : 'credit',
+                                                    'return:text' : 'return',
+                                                    'includeFormatted:int' :  1,
+                                                    'startDate:text' : _this.dateFrom.getValue(),
+                                                    'endDate:text' :  _this.dateTo.getValue(),
+                                                    limit : 99999
+                                                    
+                                                });
+                                                
+                                                if (_this.custSel.getValue()) {
+                                                   o.params['cust_id:number'] = _this.custSel.getValue();
+                                                }
+                                                
+                                                if (_this.countrySel.getValue()) {
+                                                   o.params['addr_country:text'] = _this.countrySel.getValue();
+                                                }
+                                                
+                                                if (_this.postalCodeSel.getValue()) {
+                                                   o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();
+                                                }
+                                                
+                                                if (_this.itemSel.getValue()) {
+                                                   o.params['item_id:number'] = _this.itemSel.getValue();
+                                                }
+                                                
+                                                if (_this.orderRep.getValue()) {
+                                                   o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();
+                                                }
+                                                
+                                                if (_this.custRep.getValue()) {
+                                                   o.params['cust_salesrep_id:number'] = _this.custRep.getValue();
+                                                }
+                                                
+                                                
+                                                new Pman.Download({
+                                                    url: baseURL + '/Roo/Metasql',
+                                                    params : o.params,
+                                                    limit : 100000,
+                                                    newWindow : true
+                                                });
+                                            }
+                                        },
+                                        text : "Sales History"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                             var o = { params : {}};
+                                                 Roo.apply(o.params, {
+                                                    _group : 'salesHistory',
+                                                    _name : 'stockist',
+                                                  csvCols : '*', csvTitles : '*',
+                                                    'credit:text' : 'credit',
+                                                    'return:text' : 'return',
+                                                    'includeFormatted:int' :  1,
+                                                    'startDate:text' : _this.dateFrom.getValue(),
+                                                    'endDate:text' :  _this.dateTo.getValue(),
+                                                    limit : 99999
+                                                    
+                                                });
+                                                
+                                                if (_this.custSel.getValue()) {
+                                                   o.params['cust_id:number'] = _this.custSel.getValue();
+                                                }
+                                                
+                                                if (_this.countrySel.getValue()) {
+                                                   o.params['addr_country:text'] = _this.countrySel.getValue();
+                                                }
+                                                
+                                                if (_this.postalCodeSel.getValue()) {
+                                                   o.params['addr_postalcode:text'] = _this.postalCodeSel.getValue();
+                                                }
+                                                
+                                                if (_this.itemSel.getValue()) {
+                                                   o.params['item_id:number'] = _this.itemSel.getValue();
+                                                }
+                                                
+                                                if (_this.orderRep.getValue()) {
+                                                   o.params['cohist_salesrep_id:number'] = _this.orderRep.getValue();
+                                                }
+                                                
+                                                if (_this.custRep.getValue()) {
+                                                   o.params['cust_salesrep_id:number'] = _this.custRep.getValue();
+                                                }
+                                                
+                                                
+                                                new Pman.Download({
+                                                    url: baseURL + '/Roo/Metasql',
+                                                    params : o.params,
+                                                    limit : 100000,
+                                                    newWindow : true
+                                                });
+                                            }
+                                        },
+                                        text : "Stockists Summary"
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_id',
+                        header : 'Cust#',
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_name',
+                        header : 'Customer',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'order_salesrep_name',
+                        header : 'Order Sales Rep',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_salesrep_name',
+                        header : 'Customer Sales Rep',
+                        hidden : true,
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'addr_country',
+                        header : 'Country',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'addr_city',
+                        header : 'City',
+                        hidden : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'addr_state',
+                        header : 'State',
+                        hidden : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'addr_postalcode',
+                        header : 'Postal Code',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cohist_ordernumber',
+                        header : 'Order',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cohead_orderdate',
+                        header : 'Order date',
+                        width : 75,
+                        renderer : function(v) { 
+                            var d = Date.parseDate(v, 'Y-m-d');
+                            return String.format('{0}', d ? d.format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invmonth',
+                        header : 'Invoice Month',
+                        width : 75,
+                        renderer : function(v) { 
+                           
+                            return String.format('{0}', v);
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cohist_invcdate',
+                        header : 'Invoice date',
+                        width : 75,
+                        renderer : function(v) { 
+                            var d = Date.parseDate(v, 'Y-m-d');
+                            return String.format('{0}', d ? d.format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cohist_invcnumber',
+                        header : 'Invoice#',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'item_brand',
+                        header : 'Brand',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v   : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'item_number',
+                        header : 'Item No.',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v   : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'item_descrip1',
+                        header : 'Description',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cohist_qtyshipped',
+                        header : 'Shipped',
+                        width : 70,
+                        renderer : function(v) { return parseInt(v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'currabbr',
+                        header : 'Currency',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v.split(/\s+/)[0]); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'cohist_unitprice',
+                        header : 'Unit Price',
+                        width : 75,
+                        renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'extprice',
+                        header : 'Ext Cost',
+                        width : 75,
+                        renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'extpricebase',
+                        header : 'Ext Price (Base)',
+                        width : 75,
+                        renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'baseunitprice',
+                        header : 'Unit Price (Base)',
+                        hidden : true,
+                        width : 75,
+                        renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'basefifovalue',
+                        header : 'Fifo Cost',
+                        width : 75,
+                        renderer : function(v) { return Roo.util.Format.number( v, 2); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSalesInvoice.bjs b/Pman.Tab.XtupleSalesInvoice.bjs
new file mode 100644 (file)
index 0000000..468373f
--- /dev/null
@@ -0,0 +1,434 @@
+{
+    "id": "roo-file-330",
+    "name": "Pman.Tab.XtupleSalesInvoice",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSalesInvoice.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            ".builderCfg": "{\"cols\":[{\"table\":\"invchead\",\"column\":\"invchead_ordernumber\",\"columnshort\":\"invchead_ordernumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Sales Order#\"},{\"table\":\"invchead\",\"column\":\"invchead_orderdate\",\"columnshort\":\"invchead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"invchead\",\"column\":\"invchead_posted\",\"columnshort\":\"invchead_posted\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Posted\"},{\"table\":\"invchead\",\"column\":\"invchead_printed\",\"columnshort\":\"invchead_printed\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Printed?\"},{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Invoiced\"},{\"table\":\"invchead\",\"column\":\"invchead_billto_name\",\"columnshort\":\"invchead_billto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Bill To\"}],\"cols_ex\":[\"invchead_billto_name\"],\"table\":\"invchead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "invchead",
+            "title": "Invoices",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n \n     \n     var d =  this.getDataSource().getAt(rowIndex).data;\n     \n     if (d.cohead_id) {\n     \n        Pman.Dialog.XtupleSalesOrder.show( {\n            cohead_id : d.cohead_id\n        \n        }, function() {\n            _this.grid.footer.onClick('refresh');\n            // updated..\n            Pman.Tab.XtupleSales.grid.footer.onClick('first');\n        });  \n        return;\n    }\n    \n    // other wise not a sales order related..\n    \n         \n     Pman.Dialog.XtupleInvc.show( {\n            _id : d.invchead_id\n        \n        }, function() {\n            _this.grid.footer.onClick('refresh');\n            // updated..\n            Pman.Tab.XtupleSales.grid.footer.onClick('first');\n        });  \n    \n}\n"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "cust_name",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    if (_this.ordernumber.getValue().length) {\n        o.params['query[invchead_ordernumber]'] = _this.ordernumber.getValue();\n    }\n    \n    if (_this.invcnumber.getValue().length) {\n        o.params['query[invchead_invcnumber]'] = _this.invcnumber.getValue();\n    }\n    \n    \n    if (_this.customer.getValue()) {\n        o.params.invchead_cust_id = _this.customer.getValue();\n    }\n    if (_this.fromDate.getValue()) {\n        o.params['search[fromDate]'] = _this.fromDate.getValue().format('Y-m-d');\n    }\n    if (_this.toDate.getValue()) {\n        o.params['search[toDate]'] = _this.toDate.getValue().format('Y-m-d');\n    }\n    o.params._show_status = _this.status.getValue();\n    \n    o.params._with_salesorder = 1;\n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'invchead_invcdate', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/invchead.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"invchead\",\"column\":\"invchead_ordernumber\",\"columnshort\":\"invchead_ordernumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Sales Order#\"},{\"table\":\"invchead\",\"column\":\"invchead_orderdate\",\"columnshort\":\"invchead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"invchead\",\"column\":\"invchead_posted\",\"columnshort\":\"invchead_posted\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Posted\"},{\"table\":\"invchead\",\"column\":\"invchead_printed\",\"columnshort\":\"invchead_printed\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Printed?\"},{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Invoiced\"},{\"table\":\"invchead\",\"column\":\"invchead_billto_name\",\"columnshort\":\"invchead_billto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Bill To\"}],\"cols_ex\":[\"invchead_billto_name\"],\"table\":\"invchead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'invchead_ordernumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invchead_orderdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invchead_posted',\n        'type': 'boolean'\n    },\n    {\n        'name': 'invchead_printed',\n        'type': 'boolean'\n    },\n    {\n        'name': 'invchead_invcdate',\n        'type': 'date'\n    },\n    {\n        'name': 'invchead_billto_name',\n        'type': 'string'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying invchead{0} - {1} of {2}",
+                            "emptyMsg": "No invchead found",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid: _this.grid\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Download should start soon\");\n}"
+                                    },
+                                    "text": "Download",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.invcnumber = _self;\n}",
+                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "emptyText": "Invoice #",
+                                    "width": 70,
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.ordernumber = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "invchead_ordernumber",
+                                    "editable": true,
+                                    "emptyText": "Order",
+                                    "fieldLabel": "ordernumber",
+                                    "forceSelection": true,
+                                    "hiddenName": "invchead_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "invchead_ordernumber",
+                                    "pageSize": 20,
+                                    "qtip": "Select invchead",
+                                    "queryParam": "query[invchead_ordernumber]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{invchead_ordernumber}</b> </div>",
+                                    "triggerAction": "all",
+                                    "valueField": "invchead_ordernumber",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "|xns": "Roo.data",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'invchead_ordernumber' }",
+                                            "xtype": "Store",
+                                            "remoteSort": true,
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/invchead.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "invchead_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"invchead_id\",\"type\":\"int\"},\"invchead_ordernumber\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.customer = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "cust_name",
+                                    "editable": true,
+                                    "emptyText": "Select Customer",
+                                    "fieldLabel": "cust_name",
+                                    "forceSelection": true,
+                                    "hiddenName": "cust_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "cust_name",
+                                    "pageSize": 20,
+                                    "qtip": "Select custinfo",
+                                    "queryParam": "query[cust_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> </div>",
+                                    "triggerAction": "all",
+                                    "valueField": "cust_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "|xns": "Roo.data",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                            "xtype": "Store",
+                                            "remoteSort": true,
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.status = _self;\n}",
+                                        "beforeselect": "function (combo, record, index)\n{\n (function() {   _this.grid.footer.onClick('first'); }).defer(100);\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "fieldLabel": "Status",
+                                    "hiddenName": "status",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "status",
+                                    "triggerAction": "all",
+                                    "value": "A",
+                                    "valueField": "ftype",
+                                    "width": 100,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'U', \"Unpaid\"],\n    [ 'NV' , \"Not Void Only\"],\n    [ 'V' , \"Void Only\"],    \n    [ 'A', \"All\"] \n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "text": "From:",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}",
+                                        "render": "function (_self)\n{\n    _this.fromDate = _self;\n}"
+                                    },
+                                    "format": "Y-m-d",
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "text": " To:",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}",
+                                        "render": "function (_self)\n{\n    _this.toDate = _self;\n}"
+                                    },
+                                    "format": "Y-m-d",
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function ()\n{\n\n    if (!Pman.hasPerm('Xtuple.InvoiceAll', 'S')) {\n        Roo.MessageBox.alert(\"Error\", \"You do not have permissions to do that, please contact the administrator to void invoices, or edit the sales order.\");\n        return;\n    \n    }\n    \n    \n     var sel  = _this.grid.getSelectionModel().getSelected();\n    if (!sel) {\n        Roo.MessageBox.alert(\"Error\", \"Select a invoice\");\n        return;\n    }\n    // check current status of shipment..\n    \n    Roo.MessageBox.confirm(\"Are you sure\", \"Are you sure you want to VOID that invoice?\",\n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            new Pman.Request({\n                mask : 'Sending',\n                url : baseURL + '/Roo/invchead',\n                method : 'POST',\n                params : {\n                    invchead_id : sel.data.invchead_id,\n                    _void : 1\n                },\n                success : function() {\n                    _this.grid.footer.onClick('refresh');\n                }\n            })\n            \n        }\n    );\n            \n            \n   \n}"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Void Invoice",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invchead_ordernumber",
+                            "header": "Sales Order#",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invchead_invcnumber",
+                            "header": "Invoice#",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {\n    if (r.data.invchead_void) { \n        var vv = v.split('x-').shift();\n        return String.format('<s>{0}</s>', vv);    \n    }\n    return String.format('{0}', v);\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            ".builderCfg": "{\"table\":\"invchead\",\"column\":\"invchead_orderdate\",\"columnshort\":\"invchead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"}",
+                            "header": "Ordered",
+                            "width": 75,
+                            "dataIndex": "invchead_orderdate",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invchead_posted",
+                            "header": "Posted",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {     \n \n    if (r.data.invchead_void) { \n        return String.format('<s>VOID</s>', v);    \n    }\n    \n    return String.format('{0}', v); \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invchead_void",
+                            "header": "Void",
+                            "hidden": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {     \n \n    \n    return String.format('{0}', v); \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invchead_salesrep_id_salesrep_name",
+                            "header": "Sales Rep",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_salesrep_id_salesrep_name",
+                            "header": "Customer Rep",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"invchead\",\"column\":\"invchead_printed\",\"columnshort\":\"invchead_printed\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Printed?\"}",
+                            "dataIndex": "invchead_printed",
+                            "header": "Printed?",
+                            "hidden": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            ".builderCfg": "{\"table\":\"invchead\",\"column\":\"invchead_invcdate\",\"columnshort\":\"invchead_invcdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Invoiced\"}",
+                            "header": "Invoiced",
+                            "width": 75,
+                            "dataIndex": "invchead_invcdate",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_addr_id_addr_postalcode",
+                            "header": "Customer Postcode",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_addr_id_addr_state",
+                            "header": "Customer State",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "cust_name",
+                            "header": "Customer",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invchead_curr_id_curr_symbol",
+                            "header": "Currency",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v : '??'); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invchead_total",
+                            "header": "Value",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "aropen_amount",
+                            "header": "w/Tax",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "300"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSalesInvoice.js b/Pman.Tab.XtupleSalesInvoice.js
new file mode 100644 (file)
index 0000000..8cd4f39
--- /dev/null
@@ -0,0 +1,596 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSalesInvoice = new Roo.XComponent({
+    part     :  ["Xtuple","SalesInvoice"],
+    order    : '300-Pman.Tab.XtupleSalesInvoice',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'invchead',
+            title : "Invoices",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        //_this.dialog = Pman.Dialog.FILL_IN
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                     
+                         
+                         var d =  this.getDataSource().getAt(rowIndex).data;
+                         
+                         if (d.cohead_id) {
+                         
+                            Pman.Dialog.XtupleSalesOrder.show( {
+                                cohead_id : d.cohead_id
+                            
+                            }, function() {
+                                _this.grid.footer.onClick('refresh');
+                                // updated..
+                                Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                            });  
+                            return;
+                        }
+                        
+                        // other wise not a sales order related..
+                        
+                             
+                         Pman.Dialog.XtupleInvc.show( {
+                                _id : d.invchead_id
+                            
+                            }, function() {
+                                _this.grid.footer.onClick('refresh');
+                                // updated..
+                                Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                            });  
+                        
+                    }
+                },
+                autoExpandColumn : 'cust_name',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            if (_this.ordernumber.getValue().length) {
+                                o.params['query[invchead_ordernumber]'] = _this.ordernumber.getValue();
+                            }
+                            
+                            if (_this.invcnumber.getValue().length) {
+                                o.params['query[invchead_invcnumber]'] = _this.invcnumber.getValue();
+                            }
+                            
+                            
+                            if (_this.customer.getValue()) {
+                                o.params.invchead_cust_id = _this.customer.getValue();
+                            }
+                            if (_this.fromDate.getValue()) {
+                                o.params['search[fromDate]'] = _this.fromDate.getValue().format('Y-m-d');
+                            }
+                            if (_this.toDate.getValue()) {
+                                o.params['search[toDate]'] = _this.toDate.getValue().format('Y-m-d');
+                            }
+                            o.params._show_status = _this.status.getValue();
+                            
+                            o.params._with_salesorder = 1;
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'invchead_invcdate', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/invchead.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'invchead_ordernumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invchead_orderdate',
+                                'type': 'date'
+                            },
+                            {
+                                'name': 'invchead_posted',
+                                'type': 'boolean'
+                            },
+                            {
+                                'name': 'invchead_printed',
+                                'type': 'boolean'
+                            },
+                            {
+                                'name': 'invchead_invcdate',
+                                'type': 'date'
+                            },
+                            {
+                                'name': 'invchead_billto_name',
+                                'type': 'string'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying invchead{0} - {1} of {2}",
+                    emptyMsg : "No invchead found",
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    new Pman.Download({
+                                        grid: _this.grid
+                                    });
+                                    Roo.MessageBox.alert("Notice", "Download should start soon");
+                                }
+                            },
+                            text : "Download"
+                        }
+                    ]
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'TextField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.invcnumber = _self;
+                                },
+                                specialkey : function (_self, e)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            emptyText : "Invoice #",
+                            width : 70
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.ordernumber = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'invchead_ordernumber',
+                            editable : true,
+                            emptyText : "Order",
+                            fieldLabel : 'ordernumber',
+                            forceSelection : true,
+                            hiddenName : 'invchead_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'invchead_ordernumber',
+                            pageSize : 20,
+                            qtip : "Select invchead",
+                            queryParam : 'query[invchead_ordernumber]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{invchead_ordernumber}</b> </div>',
+                            triggerAction : 'all',
+                            valueField : 'invchead_ordernumber',
+                            width : 150,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                sortInfo : { direction : 'ASC', field: 'invchead_ordernumber' },
+                                remoteSort : true,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/invchead.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'invchead_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"invchead_id","type":"int"},"invchead_ordernumber"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.customer = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'cust_name',
+                            editable : true,
+                            emptyText : "Select Customer",
+                            fieldLabel : 'cust_name',
+                            forceSelection : true,
+                            hiddenName : 'cust_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'cust_name',
+                            pageSize : 20,
+                            qtip : "Select custinfo",
+                            queryParam : 'query[cust_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> </div>',
+                            triggerAction : 'all',
+                            valueField : 'cust_id',
+                            width : 200,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                remoteSort : true,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/custinfo.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'cust_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.status = _self;
+                                },
+                                beforeselect : function (combo, record, index)
+                                {
+                                 (function() {   _this.grid.footer.onClick('first'); }).defer(100);
+                                }
+                            },
+                            allowBlank : false,
+                            displayField : 'fname',
+                            editable : false,
+                            fieldLabel : 'Status',
+                            hiddenName : 'status',
+                            listWidth : 200,
+                            mode : 'local',
+                            name : 'status',
+                            triggerAction : 'all',
+                            value : "A",
+                            valueField : 'ftype',
+                            width : 100,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                data : [ 
+                                    [ 'U', "Unpaid"],
+                                    [ 'NV' , "Not Void Only"],
+                                    [ 'V' , "Void Only"],    
+                                    [ 'A', "All"] 
+                                ],
+                                fields : [  'ftype', 'fname']
+                            }
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "From:"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                    _this.fromDate = _self;
+                                }
+                            },
+                            format : 'Y-m-d'
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : " To:"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                    _this.toDate = _self;
+                                }
+                            },
+                            format : 'Y-m-d'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                
+                                    if (!Pman.hasPerm('Xtuple.InvoiceAll', 'S')) {
+                                        Roo.MessageBox.alert("Error", "You do not have permissions to do that, please contact the administrator to void invoices, or edit the sales order.");
+                                        return;
+                                    
+                                    }
+                                    
+                                    
+                                     var sel  = _this.grid.getSelectionModel().getSelected();
+                                    if (!sel) {
+                                        Roo.MessageBox.alert("Error", "Select a invoice");
+                                        return;
+                                    }
+                                    // check current status of shipment..
+                                    
+                                    Roo.MessageBox.confirm("Are you sure", "Are you sure you want to VOID that invoice?",
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            new Pman.Request({
+                                                mask : 'Sending',
+                                                url : baseURL + '/Roo/invchead',
+                                                method : 'POST',
+                                                params : {
+                                                    invchead_id : sel.data.invchead_id,
+                                                    _void : 1
+                                                },
+                                                success : function() {
+                                                    _this.grid.footer.onClick('refresh');
+                                                }
+                                            })
+                                            
+                                        }
+                                    );
+                                            
+                                            
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Void Invoice",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invchead_ordernumber',
+                        header : 'Sales Order#',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invchead_invcnumber',
+                        header : 'Invoice#',
+                        width : 100,
+                        renderer : function(v,x,r) {
+                            if (r.data.invchead_void) { 
+                                var vv = v.split('x-').shift();
+                                return String.format('<s>{0}</s>', vv);    
+                            }
+                            return String.format('{0}', v);
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Ordered',
+                        width : 75,
+                        dataIndex : 'invchead_orderdate',
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invchead_posted',
+                        header : 'Posted',
+                        width : 75,
+                        renderer : function(v,x,r) {     
+                         
+                            if (r.data.invchead_void) { 
+                                return String.format('<s>VOID</s>', v);    
+                            }
+                            
+                            return String.format('{0}', v); 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invchead_void',
+                        header : 'Void',
+                        hidden : true,
+                        width : 75,
+                        renderer : function(v,x,r) {     
+                         
+                            
+                            return String.format('{0}', v); 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invchead_salesrep_id_salesrep_name',
+                        header : 'Sales Rep',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_salesrep_id_salesrep_name',
+                        header : 'Customer Rep',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invchead_printed',
+                        header : 'Printed?',
+                        hidden : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Invoiced',
+                        width : 75,
+                        dataIndex : 'invchead_invcdate',
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_addr_id_addr_postalcode',
+                        header : 'Customer Postcode',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_addr_id_addr_state',
+                        header : 'Customer State',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'cust_name',
+                        header : 'Customer',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invchead_curr_id_curr_symbol',
+                        header : 'Currency',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v : '??'); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invchead_total',
+                        header : 'Value',
+                        width : 75,
+                        renderer : function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'aropen_amount',
+                        header : 'w/Tax',
+                        width : 75,
+                        renderer : function(v) { return v ? Roo.util.Format.usMoney( v) : ''; }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSalesOrder.bjs b/Pman.Tab.XtupleSalesOrder.bjs
new file mode 100644 (file)
index 0000000..d9e9fdc
--- /dev/null
@@ -0,0 +1,664 @@
+{
+    "id": "roo-file-360",
+    "name": "Pman.Tab.XtupleSalesOrder",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSalesOrder.bjs",
+    "items": [
+        {
+            "listeners": {
+                "activate": "function (_self)\n{\n    this.setTitle('Sales Orders (' + Pman.Login.authUser.dbname +')');\n}"
+            },
+            "region": "center",
+            "title": "Sales Orders",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "xtype": "BorderLayout",
+                    "|xns": "Roo",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo",
+                            "*prop": "west",
+                            "width": "200",
+                            "split": true,
+                            "title": "Search"
+                        },
+                        {
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo",
+                            "*prop": "center"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            ".builderCfg": "{\"cols\":[{\"table\":\"cohead\",\"column\":\"cohead_number\",\"columnshort\":\"cohead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#order\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"},{\"table\":\"cohead\",\"column\":\"cohead_custponumber\",\"columnshort\":\"cohead_custponumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust. PO#\"},{\"table\":\"cohead\",\"column\":\"cohead_type\",\"columnshort\":\"cohead_type\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Type\"},{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_name\",\"columnshort\":\"shipto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Currency\"}],\"cols_ex\":[\"cohead_cust_id_cust_name\"],\"table\":\"cohead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "cohead",
+                            "title": "cohead",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    try { \n        _this.dialog = Pman.Dialog.XtupleSalesOrder;\n    } catch(e) {}\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    if (!_this.dialog) return;\n    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('refresh');\n        Pman.Tab.XtupleSales.grid.footer.onClick('first');\n    }); \n}\n"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "cohead_cust_id_cust_name",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, options)\n{\n    var vl;\n    try { \n         vl = _this.form.getFieldValues();\n     } catch (e) {\n        vl = {};\n     }\n\n     \n     \n    for(var x in vl) {\n        if (!(new String(vl[x])).length) {\n            continue;\n        }\n        options.params[x] = vl[x];\n        \n    }\n    try {\n        if (options.params['query[cohead_number]'].length) {\n            options.params.viewtype = 'REALALL';\n        }\n    } catch (e) {}\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            ".builderCfg": "{\"cols\":[{\"table\":\"cohead\",\"column\":\"cohead_number\",\"columnshort\":\"cohead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#order\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"},{\"table\":\"cohead\",\"column\":\"cohead_custponumber\",\"columnshort\":\"cohead_custponumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust. PO#\"},{\"table\":\"cohead\",\"column\":\"cohead_type\",\"columnshort\":\"cohead_type\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Type\"},{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_name\",\"columnshort\":\"shipto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Currency\"}],\"cols_ex\":[\"cohead_cust_id_cust_name\"],\"table\":\"cohead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'cohead_orderdate', direction: 'DESC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "timeout": 60000,
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/cohead.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    ".builderCfg": "{\"cols\":[{\"table\":\"cohead\",\"column\":\"cohead_number\",\"columnshort\":\"cohead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#order\"},{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"},{\"table\":\"cohead\",\"column\":\"cohead_custponumber\",\"columnshort\":\"cohead_custponumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust. PO#\"},{\"table\":\"cohead\",\"column\":\"cohead_type\",\"columnshort\":\"cohead_type\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Type\"},{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"},{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_name\",\"columnshort\":\"shipto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to\"},{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\"},{\"table\":\"curr_symbol\",\"column\":\"cohead_curr_id_curr_name\",\"columnshort\":\"curr_name\",\"ctype\":\"varchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Currency\"}],\"cols_ex\":[\"cohead_cust_id_cust_name\"],\"table\":\"cohead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'cohead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'cohead_cust_id_cust_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohead_custponumber',\n        'type': 'string'\n    },\n    {\n        'name': 'cohead_type'\n    },\n    {\n        'name': 'cohead_orderdate',\n        'type': 'date'\n    },\n    {\n        'name': 'cohead_shipto_id_shipto_name',\n        'type': 'string'\n    },\n    {\n        'name': 'cohead_terms_id_terms_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'cohead_curr_id_curr_name',\n        'type': 'string'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying cohead{0} - {1} of {2}",
+                                            "emptyMsg": "No cohead found",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function ()\n{\n    new Pman.Download({\n        grid : _this.grid\n    });     \n   \n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Download Results",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n Pman.Dialog.XtupleInvHistory.show({\n \n \n    });\n}"
+                                                    },
+                                                    "text": "Quick Stock Check",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Magento',\n            timeout : 90000\n        \n       },\n       function (data) {\n            Roo.MessageBox.alert(\"Notice\", data); \n            _this.grid.footer.onClick('first');\n\n       }\n   );\n}"
+                                                    },
+                                                    "text": "Magento Upload",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "hidden": true,
+                                                    "text": "Magento Upload",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/MagentoOld',\n            timeout : 90000\n            \n        \n       },\n       function (data) {\n            Roo.MessageBox.alert(\"Notice\", data); \n            _this.grid.footer.onClick('first');\n          /*  var msg = [];\n           \n            if (data.updated) {\n                msg.push(\"Updated \" + data.updated + \" Products(s)\");\n            }            \n            if (data.inserted) {\n                msg.push(\"Added \" + data.inserted + \" Products(s)\");\n            }\n            if (data.skipped) {\n                msg.push(\"Skipped \" + data.skipped);\n            }\n            \n            if (!msg.length) {\n                msg.push(\"No data changed\");\n            }\n            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\")); */\n\n       }\n   );\n}"
+                                                                    },
+                                                                    "text": "Upload Magento File (Old Format)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Magento',\n            timeout : 90000\n        \n       },\n       function (data) {\n            Roo.MessageBox.alert(\"Notice\", data); \n            _this.grid.footer.onClick('first');\n\n       }\n   );\n}"
+                                                                    },
+                                                                    "text": "Upload Magento File (New Format)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Reports",
+                                                    "xtype": "Button",
+                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "text": "AR Aging",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n    if(!from || !to){\n        Roo.Msg.alert('Error', 'Please select a date range for the report');\n        return;\n    }\n    \n    var params  =   {\n        template: 'ARAging',\n        filename : 'ARAging-' + to.format('Y-m-d'),\n        'param[0]':   \"startDate:string='\" + from.format('Y-m-d') + \"'\",\n        'param[1]':   \"relDate:string='\" + to.format('Y-m-d') + \"'\",\n        'param[2]':   \"useDocDate:number=1\"\n    };\n    var cust_id =     _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 > 0) {\n        params['param[3]'] = 'cust_id:number=' + cust_id;\n    }\n \n    new Pman.Download({\n      url : baseURL + '/Xtuple/Print',\n      params :   params,\n      method : 'GET'\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as PDF",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n   \n    \n    var params = {\n        '_group' : 'arAging',\n        '_name' : 'bydate',\n        'limit' : 99999,\n        \n          'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,\n        'relDate:text' : to ? to.format('Y-m-d') : '2100-01-01',\n     \n        \n        \n        'useDocDate:text' : 'TRUE',\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n    \n    \n    var cust_id =     _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 > 0) {\n        params['cust_id:number'] = cust_id;\n    }\n    \n    new Pman.Download({\r\n      url : baseURL + '/Roo/Metasql',\r\n      params :   params,\r\n      method : 'GET'\r\n    });\r\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\r\n    \r\n}"
+                                                                                    },
+                                                                                    "text": "as Excel",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n   \n    \n    var params = {\n        '_group' : 'arAging',\n        '_name' : 'summary',\n        'limit' : 99999,\n        \n        \n      \n        'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,\n        'relDate:text' : to ? to.format('Y-m-d') : '2100-01-01',\n     \n        \n        'useDocDate:text' : 'TRUE',\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n    \n    var cust_id =     _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 > 0) {\n        params['cust_id:number'] = cust_id;\n    }\n    \n    new Pman.Download({\r\n      url : baseURL + '/Roo/Metasql',\r\n      params :   params,\r\n      method : 'GET'\r\n    });\r\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\r\n    \r\n}"
+                                                                                    },
+                                                                                    "text": "Summary Excel",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "text": "Customer History",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 < 1) {\n        Roo.Msg.alert('Error', 'Please select a customer');\n        return;\n    }\n    \n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n    if(!from || !to){\n        Roo.Msg.alert('Error', 'Please select a date range for the report');\n        return;\n    }\n    \n    var params  =   {\n        template: 'customer_ar_history',\n        filename : 'customer_ar_history-' + to.format('Y-m-d'),\n        'param[0]':   \"startDate:string='\" + from.format('Y-m-d') + \"'\",\n        'param[1]':   \"endDate:string='\" + to.format('Y-m-d') + \"'\",\n        'param[2]':   \"cust_id:number=\" + cust_id\n    };\n         \n    new Pman.Download({\n        url : baseURL + '/Xtuple/Print',\n        params :   params,\n        method : 'GET'\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as PDF",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 < 1) {\n        Roo.Msg.alert('Error', 'Please select a customer');\n        return;\n    }\n    \n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n  \n    \n    var params = {\n        '_group' : 'customerHistory',\n        '_name' : 'detail',\n        'limit' : 99999,\n        \n        'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,\n        'endDate:text' : to ? to.format('Y-m-d') : '2100-01-01',\n       \n        'cust_id:number' : cust_id,\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n    \n    \n    new Pman.Download({\r\n      url : baseURL + '/Roo/Metasql',\r\n      params :   params,\r\n      method : 'GET'\r\n    });\r\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as Excel",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "text": "Customer Statement",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu",
+                                                                    "items": [
+                                                                        {
+                                                                            "|xns": "Roo.menu",
+                                                                            "xtype": "Menu",
+                                                                            "*prop": "menu",
+                                                                            "items": [
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 < 1) {\n        Roo.Msg.alert('Error', 'Please select a customer');\n        return;\n    }\n    \n    var from = _this.form.findField('_fromdate').getValue();\n    var to = _this.form.findField('_todate').getValue();\n    \n \n     \n    var params  =   {\n        template: 'customer_ar_statement',\n        filename : 'customer_ar_statement-' +(to ? to.format('Y-m-d') : '2100-01-01'),\n        'param[0]':   \"startDate:string='\" + (from ? from.format('Y-m-d') : '2000-01-01') + \"'\",\n        'param[1]':   \"asofdate:string='\" + (to ? to.format('Y-m-d') : '2100-01-01')+ \"'\",\n        'param[2]':   \"cust_id:number=\" + cust_id\n    };\n    \n    new Pman.Download({\n        url : baseURL + '/Xtuple/Print',\n        params :   params,\n        method : 'GET'\n    });\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as PDF",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                },
+                                                                                {
+                                                                                    "listeners": {
+                                                                                        "click": "function (_self, e)\n{\n    var cust_id = _this.form.findField('cohead_cust_id').getValue();\n    if (cust_id * 1 < 1) {\n        Roo.Msg.alert('Error', 'Please select a customer');\n        return;\n    }\n    \n   var from = _this.form.findField('_fromdate').getValue();\n   var to = _this.form.findField('_todate').getValue();\n\n    //if(!from || !to){\n    //    Roo.Msg.alert('Error', 'Please select a date range for the report');\n    //    return;\n    //}\n    \n    var params = {\n        '_group' : 'customerStatement',\n        '_name' : 'detail',\n        'limit' : 99999,\n        'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,\n        'asofdate:text' : to ? to.format('Y-m-d') : '2100-01-01',\n        'cust_id:number' : cust_id,\n        'csvTitles' : '*',\n        'csvCols' : '*'\n    };\n\n    \n    new Pman.Download({\r\n      url : baseURL + '/Roo/Metasql',\r\n      params :   params,\r\n      method : 'GET'\r\n    });\r\n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                                    },
+                                                                                    "text": "as Excel",
+                                                                                    "xtype": "Item",
+                                                                                    "|xns": "Roo.menu"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "xtype": "Fill",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n   // check if the login in user have more than 25 open orders..\n   // if yes, warning...\n   new Pman.Request({\n        url : baseURL + '/Roo/cohead.php',\n        method :'GET',\n        params : {\n            viewtype : 'MYOPEN',\n            _count_order : 1 // make the search faster!\n        },\n        success : function(res) {\n            if(res.data[0].order_totals * 1 > 25){\n                Roo.MessageBox.alert(\"Warning\", \"Can you please close old orders before creating new ones\");\n            }\n        }\n    });\n   \n   Pman.Dialog.XtupleSalesOrderNew.show( { id : 0 } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Add",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n   var s = _this.grid.getSelectionModel().getSelected();\n   if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select an order to copy\");\n        return;\n   }\n   \n   \n   Pman.Dialog.XtupleSalesOrderCopy.show( { _copy_cohead_id : s.data.cohead_id } , function(data) {\n   \n        // get the id from the data, then \n   \n        _this.grid.footer.onClick('first');\n        Pman.Tab.XtupleSales.grid.footer.onClick('first');\n        // get the id from the data, then start editing it..\n        Roo.log(data);\n            _this.dialog.show(data,  function() {\n            _this.grid.footer.onClick('refresh');\n            Pman.Tab.XtupleSales.grid.footer.onClick('first');\n        }); \n        \n   }); \n}\n"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Copy",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"}",
+                                            "dataIndex": "cohead_orderdate",
+                                            "header": "Ordered",
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "cohead_targetdate",
+                                            "header": "Target Delivery",
+                                            "hidden": true,
+                                            "sortable": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"cohead\",\"column\":\"cohead_orderdate\",\"columnshort\":\"cohead_orderdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ordered\"}",
+                                            "dataIndex": "cohead_salesrep_id_salesrep_name",
+                                            "header": "Staff IC.",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n\n    if (r.data.cohead_display_salesrep_id) {\n        return String.format('{0} ({1})', v, r.data.cohead_display_salesrep_id_salesrep_name);\n    }\n    return String.format('{0}', v );\n    \n    \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"cohead\",\"column\":\"cohead_number\",\"columnshort\":\"cohead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"#order\"}",
+                                            "dataIndex": "cohead_number",
+                                            "header": "#order",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n\n     if (r.data.cohead_status == 'C') {\n          return String.format('<i qtip=\"closed\">{0}</i>', v); \n      }\n       if (r.data.cohead_status == 'X') {\n          return String.format('<s qtip=\"void\">{0}</s>', v); \n      }\n     return String.format('{0}', v); \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"}",
+                                            "dataIndex": "cohead_cust_id_cust_number",
+                                            "header": "Customer#",
+                                            "sortable": true,
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"custinfo\",\"column\":\"cohead_cust_id_cust_name\",\"columnshort\":\"cust_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"Customer\"}",
+                                            "dataIndex": "cohead_cust_id_cust_name",
+                                            "header": "Customer",
+                                            "sortable": true,
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"cohead\",\"column\":\"cohead_custponumber\",\"columnshort\":\"cohead_custponumber\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Cust. PO#\"}",
+                                            "dataIndex": "cohead_custponumber",
+                                            "header": "Cust. PO#",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"cohead\",\"column\":\"cohead_type\",\"columnshort\":\"cohead_type\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Type\"}",
+                                            "dataIndex": "cohead_type",
+                                            "header": "Type",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "cohead_src_locations",
+                                            "header": "From",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"shiptoinfo\",\"column\":\"cohead_shipto_id_shipto_name\",\"columnshort\":\"shipto_name\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Ship to\"}",
+                                            "dataIndex": "cohead_shiptoaddress1",
+                                            "header": "Ship to",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            ".builderCfg": "{\"table\":\"terms\",\"column\":\"cohead_terms_id_terms_descrip\",\"columnshort\":\"terms_descrip\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Terms\"}",
+                                            "dataIndex": "cohead_terms_id_terms_descrip",
+                                            "header": "Terms",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "cohead_total",
+                                            "header": "Total",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    var ret =  String.format('{0} {1}',\n         r.data.cohead_curr_id_curr_name, v ?   parseFloat(v).toFixed(3) : '---'\n     ); \n     \n     if (parseInt(r.data.cohead_qtyordered)  != 0 && \n        parseInt(r.data.cohead_unshipped) == 0 && \n         parseInt(r.data.cohead_qtyunshipped) == 0 &&\n         parseInt(r.data.cohead_qtyuninvoiced) == 0 &&         \n          parseInt(r.data.cohead_unshipped) == 0 &&\n         parseInt(r.data.cohead_uninvoiced) == 0 \n     ) {\n        return ret;\n    }\n     \n     return String.format('<b style=\"color:red\" ' + \n            'qtip=\"Products: {3} ({4}) &lt;BR/&gt;Unshipped: {1} ({5})&lt;BR&gt;Uninvoiced: {2} ({6})\">{0}</b>',\n         ret, \n            r.data.cohead_unshipped, r.data.cohead_uninvoiced, r.data.cohead_subtotal,\n            r.data.cohead_qtyordered, r.data.cohead_qtyunshipped, r.data.cohead_qtyuninvoiced\n         );\n     \n }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "background": false,
+                            "region": "west",
+                            "xtype": "ContentPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "Toolbar",
+                                    "*prop": "toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.Toolbar",
+                                            "xtype": "Fill"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "cls": "x-btn-icon",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|click": "function (_self, e)\n{\n    _this.form.reset('');\n\n    \n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "cls": "x-btn-icon",
+                                            "xtype": "Button",
+                                            "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                            "|xns": "Roo.Toolbar"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|rendered": "function (form)\n{\n    _this.form= form;\n}\n"
+                                    },
+                                    "labelAlign": "top",
+                                    "method": "POST",
+                                    "style": "margin:5px;",
+                                    "xtype": "Form",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|select": "function (combo, record, index)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                                "|render": "function (_self)\n{\n  _this.viewtypeSel = _self;\n}"
+                                            },
+                                            "allowBlank": false,
+                                            "displayField": "value",
+                                            "editable": false,
+                                            "emptyText": "View type",
+                                            "fieldLabel": "View",
+                                            "forceSelection": true,
+                                            "listWidth": 200,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "viewtype",
+                                            "pageSize": 20,
+                                            "qtip": "Select Action",
+                                            "queryParam": "query[action]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{value}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": true,
+                                            "value": "MYOPEN",
+                                            "valueField": "key",
+                                            "width": 150,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "id": 0,
+                                                    "xtype": "SimpleStore",
+                                                    "|data": "[\n  [ 'MYOPEN', 'My Open orders' ],\n  [ 'MYCLOSED', 'My Closed orders' ],\n  [ 'MYALL', 'My orders (all)' ],    \n  [ 'MYVOID', 'My Voided orders' ],      \n  [ 'OPEN', 'All Open orders' ],\n  [ 'CLOSED', 'All Closed orders' ],\n  [ 'ALL', 'All orders' ],\n  [ 'VOID', 'Voided orders' ],\n  [ 'INCOMPLETE', 'Incomplete orders' ],  \n  [ 'DRAFTSHIP', 'Have Un-confirmed Shipments' ],\n//  [ 'SHIPPOSTBUG', 'Bugs with Posted transactions' ],  \n//  [ 'SHIPQTYBUG', 'Bugs with Shipment Qty' ] ,\n  [ 'FIFOBUG', 'Problems with FIFO' ] \n    \n]",
+                                                    "|fields": "[ 'key', 'value' ]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n    (function() { _this.grid.footer.onClick('first'); }).defer(100);\n}",
+                                                "specialkey": "function (_self, e)\n{\n    //Roo.log(e.getKey());\n    if (e.getKey() == 13) {\n        (function() { _this.grid.footer.onClick('first'); }).defer(100);\n        e.stopEvent();\n        _this.rsearch = true;\n    }\n    \n}",
+                                                "beforequery": "function (combo, query, forceAll, cancel, e)\n{\n \n   if( _this.rsearch) {\n        _this.rsearch =false;\n        return false;\n    }\n \n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "cohead_number",
+                                            "editable": true,
+                                            "emptyText": "Select Order",
+                                            "fieldLabel": "Order #",
+                                            "forceSelection": false,
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "query[cohead_number]",
+                                            "pageSize": 20,
+                                            "qtip": "Select Order",
+                                            "queryParam": "query[cohead_number]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cohead_number}</b> </div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": false,
+                                            "valueField": "cohead_number",
+                                            "width": 180,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params['_columns'] = 'cohead_number';\n    // set more here\n}\n"
+                                                    },
+                                                    "*prop": "store",
+                                                    "remoteSort": true,
+                                                    "xtype": "Store",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'cohead_number' }",
+                                                    "|xns": "Roo.data",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "method": "GET",
+                                                            "xtype": "HttpProxy",
+                                                            "|url": "baseURL + '/Roo/cohead.php'",
+                                                            "|xns": "Roo.data"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "id": "cohead_number",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "xtype": "JsonReader",
+                                                            "|fields": "[\"cohead_number\"]",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, record, index)\n{\n       (function() { _this.grid.footer.onClick('first'); }).defer(100);\n}"
+                                            },
+                                            "allowBlank": true,
+                                            "displayField": "cust_name",
+                                            "editable": true,
+                                            "emptyText": "Select custinfo",
+                                            "fieldLabel": "Customer",
+                                            "forceSelection": true,
+                                            "hiddenName": "cohead_cust_id",
+                                            "listWidth": 400,
+                                            "loadingText": "Searching...",
+                                            "minChars": 2,
+                                            "name": "cohead_cust_id_cust_name",
+                                            "pageSize": 20,
+                                            "qtip": "Select custinfo",
+                                            "queryParam": "query[cust_name]",
+                                            "selectOnFocus": true,
+                                            "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b>  ({cust_number})</div>",
+                                            "triggerAction": "all",
+                                            "typeAhead": false,
+                                            "valueField": "cust_id",
+                                            "width": 180,
+                                            "xtype": "ComboBox",
+                                            "|xns": "Roo.form",
+                                            "items": [
+                                                {
+                                                    "*prop": "store",
+                                                    "|xns": "Roo.data",
+                                                    "|sortInfo": "{ direction : 'ASC', field: 'cust_name' }",
+                                                    "xtype": "Store",
+                                                    "remoteSort": true,
+                                                    "listeners": {
+                                                        "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                                    },
+                                                    "items": [
+                                                        {
+                                                            "*prop": "proxy",
+                                                            "xtype": "HttpProxy",
+                                                            "method": "GET",
+                                                            "|xns": "Roo.data",
+                                                            "|url": "baseURL + '/Roo/custinfo.php'"
+                                                        },
+                                                        {
+                                                            "*prop": "reader",
+                                                            "xtype": "JsonReader",
+                                                            "|xns": "Roo.data",
+                                                            "id": "cust_id",
+                                                            "root": "data",
+                                                            "totalProperty": "total",
+                                                            "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "fieldLabel": "From",
+                                            "format": "Y-m-d",
+                                            "name": "_fromdate",
+                                            "width": 100,
+                                            "xtype": "DateField",
+                                            "|xns": "Roo.form"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                            },
+                                            "fieldLabel": "To",
+                                            "format": "Y-m-d",
+                                            "name": "_todate",
+                                            "width": 100,
+                                            "xtype": "DateField",
+                                            "|xns": "Roo.form"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSalesOrder.js b/Pman.Tab.XtupleSalesOrder.js
new file mode 100644 (file)
index 0000000..40b59be
--- /dev/null
@@ -0,0 +1,1123 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSalesOrder = new Roo.XComponent({
+    part     :  ["Xtuple","SalesOrder"],
+    order    : '001-Pman.Tab.XtupleSalesOrder',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            listeners : {
+                activate : function (_self)
+                {
+                    this.setTitle('Sales Orders (' + Pman.Login.authUser.dbname +')');
+                }
+            },
+            region : 'center',
+            title : "Sales Orders",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'cohead',
+                        title : "cohead",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    try { 
+                                        _this.dialog = Pman.Dialog.XtupleSalesOrder;
+                                    } catch(e) {}
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                        _this.grid.footer.onClick('refresh');
+                                        Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                                    }); 
+                                }
+                            },
+                            autoExpandColumn : 'cohead_cust_id_cust_name',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, options)
+                                    {
+                                        var vl;
+                                        try { 
+                                             vl = _this.form.getFieldValues();
+                                         } catch (e) {
+                                            vl = {};
+                                         }
+                                    
+                                         
+                                         
+                                        for(var x in vl) {
+                                            if (!(new String(vl[x])).length) {
+                                                continue;
+                                            }
+                                            options.params[x] = vl[x];
+                                            
+                                        }
+                                        try {
+                                            if (options.params['query[cohead_number]'].length) {
+                                                options.params.viewtype = 'REALALL';
+                                            }
+                                        } catch (e) {}
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'cohead_orderdate', direction: 'DESC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    timeout : 60000,
+                                    url : baseURL + '/Roo/cohead.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'cohead_number',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'cohead_cust_id_cust_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'cohead_custponumber',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'cohead_type'
+                                        },
+                                        {
+                                            'name': 'cohead_orderdate',
+                                            'type': 'date'
+                                        },
+                                        {
+                                            'name': 'cohead_shipto_id_shipto_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'cohead_terms_id_terms_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'cohead_curr_id_curr_name',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying cohead{0} - {1} of {2}",
+                                emptyMsg : "No cohead found",
+                                items : [
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function ()
+                                            {
+                                                new Pman.Download({
+                                                    grid : _this.grid
+                                                });     
+                                               
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Download Results",
+                                        icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                                    }
+                                ]
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                             Pman.Dialog.XtupleInvHistory.show({
+                                             
+                                             
+                                                });
+                                            }
+                                        },
+                                        text : "Quick Stock Check"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/Magento',
+                                                        timeout : 90000
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        Roo.MessageBox.alert("Notice", data); 
+                                                        _this.grid.footer.onClick('first');
+                                            
+                                                   }
+                                               );
+                                            }
+                                        },
+                                        text : "Magento Upload"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        hidden : true,
+                                        text : "Magento Upload",
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                           Pman.Dialog.Image.show(
+                                                               {
+                                                                    _url : baseURL+'/Xtuple/Import/MagentoOld',
+                                                                    timeout : 90000
+                                                                    
+                                                                
+                                                               },
+                                                               function (data) {
+                                                                    Roo.MessageBox.alert("Notice", data); 
+                                                                    _this.grid.footer.onClick('first');
+                                                                  /*  var msg = [];
+                                                                   
+                                                                    if (data.updated) {
+                                                                        msg.push("Updated " + data.updated + " Products(s)");
+                                                                    }            
+                                                                    if (data.inserted) {
+                                                                        msg.push("Added " + data.inserted + " Products(s)");
+                                                                    }
+                                                                    if (data.skipped) {
+                                                                        msg.push("Skipped " + data.skipped);
+                                                                    }
+                                                                    
+                                                                    if (!msg.length) {
+                                                                        msg.push("No data changed");
+                                                                    }
+                                                                    Roo.MessageBox.alert("Notice", msg.join("\n")); */
+                                                        
+                                                               }
+                                                           );
+                                                        }
+                                                    },
+                                                    text : "Upload Magento File (Old Format)"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                           Pman.Dialog.Image.show(
+                                                               {
+                                                                    _url : baseURL+'/Xtuple/Import/Magento',
+                                                                    timeout : 90000
+                                                                
+                                                               },
+                                                               function (data) {
+                                                                    Roo.MessageBox.alert("Notice", data); 
+                                                                    _this.grid.footer.onClick('first');
+                                                        
+                                                               }
+                                                           );
+                                                        }
+                                                    },
+                                                    text : "Upload Magento File (New Format)"
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        cls : 'x-btn-text-icon',
+                                        text : "Reports",
+                                        icon : rootURL + '/Pman/templates/images/spreadsheet.gif',
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "AR Aging",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                        if(!from || !to){
+                                                                            Roo.Msg.alert('Error', 'Please select a date range for the report');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var params  =   {
+                                                                            template: 'ARAging',
+                                                                            filename : 'ARAging-' + to.format('Y-m-d'),
+                                                                            'param[0]':   "startDate:string='" + from.format('Y-m-d') + "'",
+                                                                            'param[1]':   "relDate:string='" + to.format('Y-m-d') + "'",
+                                                                            'param[2]':   "useDocDate:number=1"
+                                                                        };
+                                                                        var cust_id =     _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 > 0) {
+                                                                            params['param[3]'] = 'cust_id:number=' + cust_id;
+                                                                        }
+                                                                     
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Xtuple/Print',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as PDF"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                       
+                                                                        
+                                                                        var params = {
+                                                                            '_group' : 'arAging',
+                                                                            '_name' : 'bydate',
+                                                                            'limit' : 99999,
+                                                                            
+                                                                              'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,
+                                                                            'relDate:text' : to ? to.format('Y-m-d') : '2100-01-01',
+                                                                         
+                                                                            
+                                                                            
+                                                                            'useDocDate:text' : 'TRUE',
+                                                                            'csvTitles' : '*',
+                                                                            'csvCols' : '*'
+                                                                        };
+                                                                        
+                                                                        
+                                                                        var cust_id =     _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 > 0) {
+                                                                            params['cust_id:number'] = cust_id;
+                                                                        }
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Roo/Metasql',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                        
+                                                                    }
+                                                                },
+                                                                text : "as Excel"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                       
+                                                                        
+                                                                        var params = {
+                                                                            '_group' : 'arAging',
+                                                                            '_name' : 'summary',
+                                                                            'limit' : 99999,
+                                                                            
+                                                                            
+                                                                          
+                                                                            'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,
+                                                                            'relDate:text' : to ? to.format('Y-m-d') : '2100-01-01',
+                                                                         
+                                                                            
+                                                                            'useDocDate:text' : 'TRUE',
+                                                                            'csvTitles' : '*',
+                                                                            'csvCols' : '*'
+                                                                        };
+                                                                        
+                                                                        var cust_id =     _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 > 0) {
+                                                                            params['cust_id:number'] = cust_id;
+                                                                        }
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Roo/Metasql',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                        
+                                                                    }
+                                                                },
+                                                                text : "Summary Excel"
+                                                            }
+                                                        ]
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "Customer History",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 < 1) {
+                                                                            Roo.Msg.alert('Error', 'Please select a customer');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                        if(!from || !to){
+                                                                            Roo.Msg.alert('Error', 'Please select a date range for the report');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var params  =   {
+                                                                            template: 'customer_ar_history',
+                                                                            filename : 'customer_ar_history-' + to.format('Y-m-d'),
+                                                                            'param[0]':   "startDate:string='" + from.format('Y-m-d') + "'",
+                                                                            'param[1]':   "endDate:string='" + to.format('Y-m-d') + "'",
+                                                                            'param[2]':   "cust_id:number=" + cust_id
+                                                                        };
+                                                                             
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Xtuple/Print',
+                                                                            params :   params,
+                                                                            method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as PDF"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 < 1) {
+                                                                            Roo.Msg.alert('Error', 'Please select a customer');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                      
+                                                                        
+                                                                        var params = {
+                                                                            '_group' : 'customerHistory',
+                                                                            '_name' : 'detail',
+                                                                            'limit' : 99999,
+                                                                            
+                                                                            'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,
+                                                                            'endDate:text' : to ? to.format('Y-m-d') : '2100-01-01',
+                                                                           
+                                                                            'cust_id:number' : cust_id,
+                                                                            'csvTitles' : '*',
+                                                                            'csvCols' : '*'
+                                                                        };
+                                                                        
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Roo/Metasql',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as Excel"
+                                                            }
+                                                        ]
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    text : "Customer Statement",
+                                                    menu : {
+                                                        xtype: 'Menu',
+                                                        xns: Roo.menu,
+                                                        items : [
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 < 1) {
+                                                                            Roo.Msg.alert('Error', 'Please select a customer');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                        var from = _this.form.findField('_fromdate').getValue();
+                                                                        var to = _this.form.findField('_todate').getValue();
+                                                                        
+                                                                     
+                                                                         
+                                                                        var params  =   {
+                                                                            template: 'customer_ar_statement',
+                                                                            filename : 'customer_ar_statement-' +(to ? to.format('Y-m-d') : '2100-01-01'),
+                                                                            'param[0]':   "startDate:string='" + (from ? from.format('Y-m-d') : '2000-01-01') + "'",
+                                                                            'param[1]':   "asofdate:string='" + (to ? to.format('Y-m-d') : '2100-01-01')+ "'",
+                                                                            'param[2]':   "cust_id:number=" + cust_id
+                                                                        };
+                                                                        
+                                                                        new Pman.Download({
+                                                                            url : baseURL + '/Xtuple/Print',
+                                                                            params :   params,
+                                                                            method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as PDF"
+                                                            },
+                                                            {
+                                                                xtype: 'Item',
+                                                                xns: Roo.menu,
+                                                                listeners : {
+                                                                    click : function (_self, e)
+                                                                    {
+                                                                        var cust_id = _this.form.findField('cohead_cust_id').getValue();
+                                                                        if (cust_id * 1 < 1) {
+                                                                            Roo.Msg.alert('Error', 'Please select a customer');
+                                                                            return;
+                                                                        }
+                                                                        
+                                                                       var from = _this.form.findField('_fromdate').getValue();
+                                                                       var to = _this.form.findField('_todate').getValue();
+                                                                    
+                                                                        //if(!from || !to){
+                                                                        //    Roo.Msg.alert('Error', 'Please select a date range for the report');
+                                                                        //    return;
+                                                                        //}
+                                                                        
+                                                                        var params = {
+                                                                            '_group' : 'customerStatement',
+                                                                            '_name' : 'detail',
+                                                                            'limit' : 99999,
+                                                                            'startDate:text' : from ? from.format('Y-m-d') : '2000-01-01' ,
+                                                                            'asofdate:text' : to ? to.format('Y-m-d') : '2100-01-01',
+                                                                            'cust_id:number' : cust_id,
+                                                                            'csvTitles' : '*',
+                                                                            'csvCols' : '*'
+                                                                        };
+                                                                    
+                                                                        
+                                                                        new Pman.Download({
+                                                                          url : baseURL + '/Roo/Metasql',
+                                                                          params :   params,
+                                                                          method : 'GET'
+                                                                        });
+                                                                        Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                                    }
+                                                                },
+                                                                text : "as Excel"
+                                                            }
+                                                        ]
+                                                    }
+                                                }
+                                            ]
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                               // check if the login in user have more than 25 open orders..
+                                               // if yes, warning...
+                                               new Pman.Request({
+                                                    url : baseURL + '/Roo/cohead.php',
+                                                    method :'GET',
+                                                    params : {
+                                                        viewtype : 'MYOPEN',
+                                                        _count_order : 1 // make the search faster!
+                                                    },
+                                                    success : function(res) {
+                                                        if(res.data[0].order_totals * 1 > 25){
+                                                            Roo.MessageBox.alert("Warning", "Can you please close old orders before creating new ones");
+                                                        }
+                                                    }
+                                                });
+                                               
+                                               Pman.Dialog.XtupleSalesOrderNew.show( { id : 0 } , function() {
+                                                    _this.grid.footer.onClick('first');
+                                               }); 
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Add",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                               var s = _this.grid.getSelectionModel().getSelected();
+                                               if (!s) {
+                                                    Roo.MessageBox.alert("Error", "Select an order to copy");
+                                                    return;
+                                               }
+                                               
+                                               
+                                               Pman.Dialog.XtupleSalesOrderCopy.show( { _copy_cohead_id : s.data.cohead_id } , function(data) {
+                                               
+                                                    // get the id from the data, then 
+                                               
+                                                    _this.grid.footer.onClick('first');
+                                                    Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                                                    // get the id from the data, then start editing it..
+                                                    Roo.log(data);
+                                                        _this.dialog.show(data,  function() {
+                                                        _this.grid.footer.onClick('refresh');
+                                                        Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                                                    }); 
+                                                    
+                                               }); 
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Copy",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_orderdate',
+                                    header : 'Ordered',
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_targetdate',
+                                    header : 'Target Delivery',
+                                    hidden : true,
+                                    sortable : true,
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_salesrep_id_salesrep_name',
+                                    header : 'Staff IC.',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                    
+                                        if (r.data.cohead_display_salesrep_id) {
+                                            return String.format('{0} ({1})', v, r.data.cohead_display_salesrep_id_salesrep_name);
+                                        }
+                                        return String.format('{0}', v );
+                                        
+                                        
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_number',
+                                    header : '#order',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v,x,r) {
+                                    
+                                         if (r.data.cohead_status == 'C') {
+                                              return String.format('<i qtip="closed">{0}</i>', v); 
+                                          }
+                                           if (r.data.cohead_status == 'X') {
+                                              return String.format('<s qtip="void">{0}</s>', v); 
+                                          }
+                                         return String.format('{0}', v); 
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_cust_id_cust_number',
+                                    header : 'Customer#',
+                                    sortable : true,
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_cust_id_cust_name',
+                                    header : 'Customer',
+                                    sortable : true,
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_custponumber',
+                                    header : 'Cust. PO#',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_type',
+                                    header : 'Type',
+                                    width : 50,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_src_locations',
+                                    header : 'From',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_shiptoaddress1',
+                                    header : 'Ship to',
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'cohead_terms_id_terms_descrip',
+                                    header : 'Terms',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'cohead_total',
+                                    header : 'Total',
+                                    width : 100,
+                                    renderer : function(v,x,r) { 
+                                        var ret =  String.format('{0} {1}',
+                                             r.data.cohead_curr_id_curr_name, v ?   parseFloat(v).toFixed(3) : '---'
+                                         ); 
+                                         
+                                         if (parseInt(r.data.cohead_qtyordered)  != 0 && 
+                                            parseInt(r.data.cohead_unshipped) == 0 && 
+                                             parseInt(r.data.cohead_qtyunshipped) == 0 &&
+                                             parseInt(r.data.cohead_qtyuninvoiced) == 0 &&         
+                                              parseInt(r.data.cohead_unshipped) == 0 &&
+                                             parseInt(r.data.cohead_uninvoiced) == 0 
+                                         ) {
+                                            return ret;
+                                        }
+                                         
+                                         return String.format('<b style="color:red" ' + 
+                                                'qtip="Products: {3} ({4}) &lt;BR/&gt;Unshipped: {1} ({5})&lt;BR&gt;Uninvoiced: {2} ({6})">{0}</b>',
+                                             ret, 
+                                                r.data.cohead_unshipped, r.data.cohead_uninvoiced, r.data.cohead_subtotal,
+                                                r.data.cohead_qtyordered, r.data.cohead_qtyunshipped, r.data.cohead_qtyuninvoiced
+                                             );
+                                         
+                                     }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'ContentPanel',
+                        xns: Roo,
+                        background : false,
+                        region : 'west',
+                        items : [
+                            {
+                                xtype: 'Form',
+                                xns: Roo.form,
+                                listeners : {
+                                    rendered : function (form)
+                                    {
+                                        _this.form= form;
+                                    }
+                                },
+                                labelAlign : 'top',
+                                method : 'POST',
+                                style : 'margin:5px;',
+                                items : [
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            select : function (combo, record, index)
+                                            {
+                                              _this.grid.footer.onClick('first');
+                                            },
+                                            render : function (_self)
+                                            {
+                                              _this.viewtypeSel = _self;
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'value',
+                                        editable : false,
+                                        emptyText : "View type",
+                                        fieldLabel : 'View',
+                                        forceSelection : true,
+                                        listWidth : 200,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'viewtype',
+                                        pageSize : 20,
+                                        qtip : "Select Action",
+                                        queryParam : 'query[action]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{value}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : true,
+                                        value : "MYOPEN",
+                                        valueField : 'key',
+                                        width : 150,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            id : 0,
+                                            data : [
+                                              [ 'MYOPEN', 'My Open orders' ],
+                                              [ 'MYCLOSED', 'My Closed orders' ],
+                                              [ 'MYALL', 'My orders (all)' ],    
+                                              [ 'MYVOID', 'My Voided orders' ],      
+                                              [ 'OPEN', 'All Open orders' ],
+                                              [ 'CLOSED', 'All Closed orders' ],
+                                              [ 'ALL', 'All orders' ],
+                                              [ 'VOID', 'Voided orders' ],
+                                              [ 'INCOMPLETE', 'Incomplete orders' ],  
+                                              [ 'DRAFTSHIP', 'Have Un-confirmed Shipments' ],
+                                            //  [ 'SHIPPOSTBUG', 'Bugs with Posted transactions' ],  
+                                            //  [ 'SHIPQTYBUG', 'Bugs with Shipment Qty' ] ,
+                                              [ 'FIFOBUG', 'Problems with FIFO' ] 
+                                                
+                                            ],
+                                            fields : [ 'key', 'value' ]
+                                        }
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            select : function (combo, record, index)
+                                            {
+                                                (function() { _this.grid.footer.onClick('first'); }).defer(100);
+                                            },
+                                            specialkey : function (_self, e)
+                                            {
+                                                //Roo.log(e.getKey());
+                                                if (e.getKey() == 13) {
+                                                    (function() { _this.grid.footer.onClick('first'); }).defer(100);
+                                                    e.stopEvent();
+                                                    _this.rsearch = true;
+                                                }
+                                                
+                                            },
+                                            beforequery : function (combo, query, forceAll, cancel, e)
+                                            {
+                                             
+                                               if( _this.rsearch) {
+                                                    _this.rsearch =false;
+                                                    return false;
+                                                }
+                                             
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        displayField : 'cohead_number',
+                                        editable : true,
+                                        emptyText : "Select Order",
+                                        fieldLabel : 'Order #',
+                                        forceSelection : false,
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'query[cohead_number]',
+                                        pageSize : 20,
+                                        qtip : "Select Order",
+                                        queryParam : 'query[cohead_number]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{cohead_number}</b> </div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'cohead_number',
+                                        width : 180,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    o.params['_columns'] = 'cohead_number';
+                                                    // set more here
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { direction : 'ASC', field: 'cohead_number' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/cohead.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'cohead_number',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : ["cohead_number"]
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            select : function (combo, record, index)
+                                            {
+                                                   (function() { _this.grid.footer.onClick('first'); }).defer(100);
+                                            }
+                                        },
+                                        allowBlank : true,
+                                        displayField : 'cust_name',
+                                        editable : true,
+                                        emptyText : "Select custinfo",
+                                        fieldLabel : 'Customer',
+                                        forceSelection : true,
+                                        hiddenName : 'cohead_cust_id',
+                                        listWidth : 400,
+                                        loadingText : "Searching...",
+                                        minChars : 2,
+                                        name : 'cohead_cust_id_cust_name',
+                                        pageSize : 20,
+                                        qtip : "Select custinfo",
+                                        queryParam : 'query[cust_name]',
+                                        selectOnFocus : true,
+                                        tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b>  ({cust_number})</div>',
+                                        triggerAction : 'all',
+                                        typeAhead : false,
+                                        valueField : 'cust_id',
+                                        width : 180,
+                                        store : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            sortInfo : { direction : 'ASC', field: 'cust_name' },
+                                            remoteSort : true,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    // set more here
+                                                }
+                                            },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/custinfo.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'cust_id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                            }
+                                        }
+                                    },
+                                    {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            select : function (combo, date)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        fieldLabel : 'From',
+                                        format : 'Y-m-d',
+                                        name : '_fromdate',
+                                        width : 100
+                                    },
+                                    {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            select : function (combo, date)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        fieldLabel : 'To',
+                                        format : 'Y-m-d',
+                                        name : '_todate',
+                                        width : 100
+                                    }
+                                ]
+                            }
+                        ],
+                        toolbar : {
+                            xtype: 'Toolbar',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'Fill',
+                                    xns: Roo.Toolbar
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                        _this.grid.footer.onClick('first');
+                                        }
+                                    },
+                                    cls : 'x-btn-icon',
+                                    icon : rootURL + '/Pman/templates/images/search.gif'
+                                },
+                                {
+                                    xtype: 'Button',
+                                    xns: Roo.Toolbar,
+                                    listeners : {
+                                        click : function (_self, e)
+                                        {
+                                            _this.form.reset('');
+                                        
+                                            
+                                            _this.grid.footer.onClick('first');
+                                        }
+                                    },
+                                    cls : 'x-btn-icon',
+                                    icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                                }
+                            ]
+                        }
+                    }
+                ],
+                west : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    width : '200',
+                    split : true,
+                    title : "Search"
+                },
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSalesPlanning.bjs b/Pman.Tab.XtupleSalesPlanning.bjs
new file mode 100644 (file)
index 0000000..119f3e6
--- /dev/null
@@ -0,0 +1,840 @@
+{
+    "id": "roo-file-58",
+    "name": "Pman.Tab.XtupleSalesPlanning",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "Pman.Tab.XtupleSalesPlanning",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSalesPlanning.bjs",
+    "items": [
+        {
+            "listeners": {
+                "activate": "function (_self)\n{\n   // Roo.log(Pman.hasPerm('Xtuple.SalesPlanner', 'S'));\n   // Roo.log(Pman.Login.authUser);\n}"
+            },
+            "background": false,
+            "fitContainer": true,
+            "fitToFrame": true,
+            "title": "Sales Planning",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "south",
+                            "height": 400,
+                            "split": true,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "activate": "function (_self)\n{\n    _self.layout.getRegion('center').showPanel(0);\n}"
+                            },
+                            "background": false,
+                            "fitContainer": true,
+                            "fitToFrame": true,
+                            "region": "center",
+                            "xtype": "NestedLayoutPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo",
+                                    "xtype": "BorderLayout",
+                                    "*prop": "layout",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "LayoutRegion",
+                                            "*prop": "center"
+                                        },
+                                        {
+                                            "*prop": "west",
+                                            "split": true,
+                                            "tabPosition": "top",
+                                            "width": 300,
+                                            "xtype": "LayoutRegion",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|activate": "function() {\n    _this.panel = this;\n    \n  //  if (_this.grid) {\n  //      _this.grid.footer.onClick('first');\n  //  }\n}"
+                                            },
+                                            "background": false,
+                                            "fitContainer": true,
+                                            "fitToframe": true,
+                                            "region": "center",
+                                            "tableName": "item",
+                                            "title": "Item",
+                                            "xtype": "GridPanel",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n  //  if (_this.panel.active) {\n   //    this.footer.onClick('first');\n  //  }\n}"
+                                                    },
+                                                    "*prop": "grid",
+                                                    "autoExpandColumn": "item_descrip1",
+                                                    "loadMask": true,
+                                                    "xtype": "Grid",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "afterselectionchange": "function (_self)\n{\n    if (_this.sgrid) {\n        _this.sgrid.footer.onClick('first');\n    }\n}"
+                                                            },
+                                                            "*prop": "sm",
+                                                            "singleSelect": true,
+                                                            "xtype": "RowSelectionModel",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "listeners": {
+                                                                "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    \n    var s = _this.wgrid.getSelectionModel().getSelected();\n    if(!s.data.cust_id){\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    _this.sgrid.ds.removeAll();\n    \n    o.params._with_year_total = 1;\n    \n    o.params._charass_brand_value = _this.brandSel.getValue();\n    o.params._charass_group_value = _this.groupSel.getValue();\n    \n    o.params._with_itemsrc_active = 1;\n    o.params._in_cust_id = s.data.cust_id;\n    \n    var date = new Date();\n    var year = date.getFullYear(); // four digits\n    var month = date.getMonth(); // 0-11\n    \n    var cm = _this.grid.getColumnModel();\n    function cid(str) {\r\n        return cm.getIndexByDataIndex(str);\r\n    }\r    \n    \n    cm.setColumnHeader(cid('total_before_last_year'),'Total ' + (year - 2));\n    cm.setColumnHeader(cid('total_last_year'),'Total ' + (year - 1));\n    cm.setColumnHeader(cid('forecast_this_year'),'Forecast ' + year);\n    cm.setColumnHeader(cid('total_this_year'),'Total ' + year);\n    \n    if(month > 5){\n        cm.setColumnHeader(cid('forecast_next_year'),'Total ' + (year + 1));\n        cm.setHidden(cid('forecast_next_year'),false);\n    }\n    // it make the grid slow, change it later!\n    if(s.data.cust_name == 'All Companies'){\n        cm.setHidden(cid('forecast_this_year'),true);\n        cm.setHidden(cid('company_estimates'),false);\n    }else{\n        cm.setHidden(cid('forecast_this_year'),false);\n        cm.setHidden(cid('company_estimates'),true);\n    }\n    \n\n}",
+                                                                "load": "function (_self, records, options)\n{\n    var sm = _this.grid.getSelectionModel();\n    Roo.each(records, function(record){\n        if(record.data.item_id == _this.grid.lastSelectedId){\n            sm.selectRow(_this.grid.ds.indexOf(record));\n            if (_this.sgrid) {\n                _this.sgrid.footer.onClick('first');\n            }\n        }\n    })\n}"
+                                                            },
+                                                            "*prop": "dataSource",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ field : 'item_number', direction: 'ASC' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/Item.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[\n    {\n        'name': 'item_number',\n        'type': 'string'\n    },\n    {\n        'name': 'item_descrip1',\n        'type': 'string'\n    },\n    {\n        'name': 'total_before_last_year',\n        'type': 'int'\n    },\n    {\n        'name': 'total_last_year',\n        'type': 'int'\n    },\n    {\n        'name': 'forecast_this_year',\n        'type': 'int'\n    },\n    {\n        'name': 'total_this_year',\n        'type': 'int'\n    },\n    {\n        'name': 'total_next_year',\n        'type': 'int'\n    },\n    {\n        'name': 'forecast_next_year',\n        'type': 'int'\n    },\n    {\n        'name': 'last_forecast_entered',\n        'type': 'string'\n    }\n]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "footer",
+                                                            "displayInfo": true,
+                                                            "displayMsg": "Displaying Item{0} - {1} of {2}",
+                                                            "emptyMsg": "No Item found",
+                                                            "pageSize": 25,
+                                                            "xtype": "PagingToolbar",
+                                                            "|xns": "Roo"
+                                                        },
+                                                        {
+                                                            "|xns": "Roo",
+                                                            "xtype": "Toolbar",
+                                                            "*prop": "toolbar",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "render": "function (_self)\n{\n  _this.brandSel = _self;\n  \n}",
+                                                                        "select": "function (combo, record, index)\n{\n    _this.wgrid.ds.load({});}"
+                                                                    },
+                                                                    "allowBlank": true,
+                                                                    "alwaysQuery": true,
+                                                                    "displayField": "charass_value",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select Brand",
+                                                                    "forceSelection": true,
+                                                                    "listWidth": 300,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select Brand",
+                                                                    "queryParam": "query[charass_value]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charass_value}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "width": 200,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n    // look for all of the charass 's with the same type= eg. brand.\n    \n    o.params.charass_char_id_char_name = 'BRAND';\n    o.params.charass_target_type ='I';\n    o.params._distinct = 'charass_value';\n    o.params._columns = 'charass_value';\n\n}"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ field : 'charass_value' , direction : 'ASC' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/Charass.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_name',\n        'type': 'string'\n    },\n    {\n        'name': 'event_when',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'on_id',\n        'type': 'int'\n    },\n    {\n        'name': 'on_table',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id',\n        'type': 'int'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_email',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_role',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_active',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_dt',\n        'type': 'date'\n    }\n]",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "render": "function (_self)\n{\n  _this.groupSel = _self;\n}",
+                                                                        "select": "function (combo, record, index)\n{\n    _this.wgrid.ds.load({});\n}"
+                                                                    },
+                                                                    "allowBlank": true,
+                                                                    "alwaysQuery": true,
+                                                                    "displayField": "charass_value",
+                                                                    "editable": true,
+                                                                    "emptyText": "Select Product Group",
+                                                                    "forceSelection": true,
+                                                                    "listWidth": 300,
+                                                                    "loadingText": "Searching...",
+                                                                    "minChars": 2,
+                                                                    "pageSize": 20,
+                                                                    "qtip": "Select Product Group",
+                                                                    "queryParam": "query[charass_value]",
+                                                                    "selectOnFocus": true,
+                                                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{charass_value}</b> </div>",
+                                                                    "triggerAction": "all",
+                                                                    "width": 200,
+                                                                    "xtype": "ComboBox",
+                                                                    "|xns": "Roo.form",
+                                                                    "items": [
+                                                                        {
+                                                                            "listeners": {
+                                                                                "|beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    // staff can see all logs, other companies can only see their own.\n    // look for all of the charass 's with the same type= eg. brand.\n    \n    o.params.charass_char_id_char_name = 'PRODUCTGROUP';\n    o.params.charass_target_type ='I';\n    o.params._distinct = 'charass_value';\n        o.params._columns = 'charass_value';\n\n}"
+                                                                            },
+                                                                            "*prop": "store",
+                                                                            "remoteSort": true,
+                                                                            "xtype": "Store",
+                                                                            "|sortInfo": "{ field : 'charass_value' , direction : 'ASC' }",
+                                                                            "|xns": "Roo.data",
+                                                                            "items": [
+                                                                                {
+                                                                                    "*prop": "proxy",
+                                                                                    "method": "GET",
+                                                                                    "xtype": "HttpProxy",
+                                                                                    "|url": "baseURL + '/Roo/Charass.php'",
+                                                                                    "|xns": "Roo.data"
+                                                                                },
+                                                                                {
+                                                                                    "*prop": "reader",
+                                                                                    "id": "id",
+                                                                                    "root": "data",
+                                                                                    "totalProperty": "total",
+                                                                                    "xtype": "JsonReader",
+                                                                                    "|fields": "[\n    {\n        'name': 'id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_name',\n        'type': 'string'\n    },\n    {\n        'name': 'event_when',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'action',\n        'type': 'string'\n    },\n    {\n        'name': 'ipaddr',\n        'type': 'string'\n    },\n    {\n        'name': 'on_id',\n        'type': 'int'\n    },\n    {\n        'name': 'on_table',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id',\n        'type': 'int'\n    },\n    {\n        'name': 'remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_office_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_name',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_phone',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_fax',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_email',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_company_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_role',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_active',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_remarks',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_passwd',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_owner_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_lang',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_no_reset_sent',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_action_type',\n        'type': 'string'\n    },\n    {\n        'name': 'person_id_project_id',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_by',\n        'type': 'int'\n    },\n    {\n        'name': 'person_id_deleted_dt',\n        'type': 'date'\n    }\n]",
+                                                                                    "|xns": "Roo.data"
+                                                                                }
+                                                                            ]
+                                                                        }
+                                                                    ]
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.Toolbar",
+                                                                    "xtype": "Fill"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function ()\n{\n    var brand = _this.brandSel.getValue();\n    var group = _this.groupSel.getValue();\n    \n    if(!brand && !group){\n        Roo.MessageBox.alert('Error','Please select the brand or group');\n        return;\n    }\n    \n    Roo.MessageBox.alert(\"Notice\",\"Your report should be downloading now\");\n    \n    new Pman.download({\n        url : baseURL + '/Roo/Salesforecast',\n        method : 'GET',\n        timeout: 900000,\n        params : {\n            '_download' : 1,\n            'brand' : brand,\n            'group' : group\n        }\n    });  \n   \n}"
+                                                                    },
+                                                                    "cls": "x-btn-text-icon",
+                                                                    "text": "Download Report",
+                                                                    "xtype": "Button",
+                                                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                                                    "|xns": "Roo.Toolbar"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "itemsrc_active",
+                                                            "header": "is Active?",
+                                                            "width": 50,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "item_number",
+                                                            "header": "Item code",
+                                                            "width": 200,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "item_descrip1",
+                                                            "header": "Item name",
+                                                            "width": 200,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "total_before_last_year",
+                                                            "header": "Total",
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "total_last_year",
+                                                            "header": "Total",
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "forecast_this_year",
+                                                            "header": "Forecast",
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) { \n    \n    if (v*1 == 0) {\n    \n        return '<span style=\"color:red\">' + v + '</span>';\n    }\n    \n    return String.format('{0}', v);\n    \n    \n}",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "total_this_year",
+                                                            "header": "Total",
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "forecast_next_year",
+                                                            "header": "Forecast",
+                                                            "hidden": true,
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) { \n    \n    if (v*1 == 0) {\n    \n        return '<span style=\"color:red\">' + v + '</span>';\n    }\n    \n    return String.format('{0}', v);\n    \n    \n}",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "last_forecast_entered",
+                                                            "header": "Last forcast entered",
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n    if(!v){\n        return;\n    }\n    var last_forecast = new Date(v);\n    \n    var date = new Date();\n    var y = date.getFullYear();\n    var m = date.getMonth() + 3;\n    var d = date.getDate();\n    if(m >= 11){\n        y = y + 1;\n        m = m - 11;\n    }\n    var c = new Date(y,m,d);\n    if (last_forecast < c) {\n        return '<span style=\"color:red\">' + last_forecast.format('M Y') + '</span>';\n    }\n    \n    return String.format('{0}', last_forecast.format('M Y'));\n    \n    \n}",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "company_estimates",
+                                                            "header": "Estimates",
+                                                            "hidden": true,
+                                                            "width": 150,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) {\n    return String.format('{0}', v);\n    \n    \n}",
+                                                            "|xns": "Roo.grid"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "listeners": {
+                                                "|activate": "function() {\n    _this.wpanel = this;\n    if (_this.wgrid) {\n        _this.wgrid.ds.load({});\n    }\n}"
+                                            },
+                                            "background": true,
+                                            "fitContainer": true,
+                                            "fitToframe": true,
+                                            "region": "west",
+                                            "tableName": "custinfo",
+                                            "title": "Customer",
+                                            "xtype": "GridPanel",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "|render": "function() \n{\n    _this.wgrid = this; \n    if (_this.wpanel.active) {\n        _this.wgrid.ds.load({});\n    }\n}",
+                                                        "rowclick": "function (_self, rowIndex, e)\n{\n    var sm = _this.grid.getSelectionModel();\n   if(sm.getSelections().length){\n         _this.grid.lastSelectedId = sm.getSelections()[0].data.item_id;\n     }\n    _this.grid.footer.onClick('refresh');\n}"
+                                                    },
+                                                    "*prop": "grid",
+                                                    "autoExpandColumn": "cust_name_with_pcs",
+                                                    "loadMask": true,
+                                                    "xtype": "Grid",
+                                                    "|xns": "Roo.grid",
+                                                    "items": [
+                                                        {
+                                                            "listeners": {
+                                                                "beforeload": "function (_self, o){\n    o.params = o.params || {};\n    \n    o.params._with_lastyear_total = 1;\n    o.params._columns = 'cust_id,cust_name,lastyear_total';\n    \n    var brand = _this.brandSel.getValue();\n    if(!brand.length){\n        _this.wgrid.ds.removeAll();\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    \n    o.params._charass_brand_value = _this.brandSel.getValue();\n    o.params._charass_group_value = _this.groupSel.getValue();\n    \n    o.params.limit = 9999;\n    \n}\n",
+                                                                "load": "function (_self, records, options)\n{\n    var sm = _this.wgrid.getSelectionModel();\n    if (!sm.getSelections().length) {\n        sm.selectFirstRow();\n    }\n    \n    _this.grid.footer.onClick('first');\n}"
+                                                            },
+                                                            "*prop": "dataSource",
+                                                            "remoteSort": true,
+                                                            "xtype": "Store",
+                                                            "|sortInfo": "{ field : 'lastyear_total', direction: 'DESC' }",
+                                                            "|xns": "Roo.data",
+                                                            "items": [
+                                                                {
+                                                                    "*prop": "proxy",
+                                                                    "method": "GET",
+                                                                    "xtype": "HttpProxy",
+                                                                    "|url": "baseURL + '/Roo/Custinfo.php'",
+                                                                    "|xns": "Roo.data"
+                                                                },
+                                                                {
+                                                                    "*prop": "reader",
+                                                                    "id": "id",
+                                                                    "root": "data",
+                                                                    "totalProperty": "total",
+                                                                    "xtype": "JsonReader",
+                                                                    "|fields": "[\n    {\n        'name': 'cust_id',\n        'type': 'int'\n    },\n    {\n        'name': 'cust_name_with_pcs',\n        'type': 'string'\n    },\n    {\n        'name': 'lastyear_total',\n        'type': 'int'\n    }\n]",
+                                                                    "|xns": "Roo.data"
+                                                                }
+                                                            ]
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "cust_name",
+                                                            "header": "Company Name",
+                                                            "width": 200,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                                            "|xns": "Roo.grid"
+                                                        },
+                                                        {
+                                                            "*prop": "colModel[]",
+                                                            "dataIndex": "lastyear_total",
+                                                            "header": "",
+                                                            "width": 75,
+                                                            "xtype": "ColumnModel",
+                                                            "|renderer": "function(v,x,r) \n{\n    return String.format('{0}', v + ' pcs'); \n}",
+                                                            "|xns": "Roo.grid"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.spanel = this;\n  /*  if (_this.sgrid) {\n        _this.sgrid.footer.onClick('first');\n    } */\n}"
+                            },
+                            "background": false,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "south",
+                            "tableName": "Groups",
+                            "title": "Details",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.sgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n   /* if (_this.spanel.active) {\n       this.footer.onClick('first');\n    } */\n}",
+                                        "afteredit": "function (e)\n{\n    _this.grid.loadMask.el.unmask();\n    _this.wgrid.loadMask.el.unmask();\n    if(e.value == e.originalValue){\n        return;\n    }\n    var field = e.field;\n    var salesforecast_id = e.record.json[field + '_salesforecast_id'];\n    var rec = _this.grid.getSelectionModel().getSelected();\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!rec || !s){\n        Roo.Msg.alert(\"Error\",\"Please select a item\");\n        return;\n    }\n    \n    var params = {\n            salesforecast_id : (salesforecast_id * 1 > 0) ? salesforecast_id : 0,\n            salesforecast_cust_id : (s.data.cust_id < 0) ? 0 : s.data.cust_id,\n            salesforecast_is_all_buyers : (s.data.view_type) == 'All' ? 1 : 0,\n            _item_id : rec.data.item_id,\n            month : e.column,\n            year : e.record.data['year']\n        }\n    \n    if(s.data.cust_id > 0){ // company level confirm and request editable!\n        if(e.record.data['type'] == 'confirm'){\n            params.salesforecast_qty = e.value;\n        }\n        if(e.record.data['type'] == 'request'){\n            params.salesforecast_requests = e.value;\n        }\n    } else { // item level estimated and total forecast editable!\n        if(e.record.data['type'] == 'estimated'){\n            params.salesforecast_qty = e.value;\n        }\n        if(e.record.data['type'] == 'forecast'){\n            params.salesforecast_sum = e.value;\n        }\n    }\n    \n    \n    new Pman.Request({\n        url : baseURL + '/Roo/Salesforecast.php',\n        method :'POST',\n        params : params,\n        success : function() {\n           \n            _this.sgrid.footer.onClick('first');\n            \n        }\n    });\n    \n}",
+                                        "beforeedit": "function (e)\n{   \n    var rec = e.record;\n    var y = new Date().getFullYear();\n    var m = new Date().getMonth(); // 0-11\n    var s = _this.grid.getSelectionModel().getSelected();\n    var ss = _this.wgrid.getSelectionModel().getSelected();\n   \n   /*\r\n    if(rec.data.type != 'forecast' || rec.data.year != y || !s.data.itemsrc_active || e.column < m + 3){\r\n        return false;\r\n    }\n    */\n\n    if(s.data.itemsrc_active * 1 < 1 || (rec.data.year == y && e.column < m + 3) || (rec.data.year != y && e.column + 12 < m + 3)){\n        return false;\n    }\n    if(ss.data.cust_id > 0){ // companies level, confirm and request editable!\n        if(rec.data.type != 'confirm' && rec.data.type != 'request'){\n            return false;\n        }\n    }else{ // item level, estimated and total forecast  editable!\n        if(rec.data.type != 'estimated' && rec.data.type != 'forecast'){\n            return false;\n        }\n    }\n    \n    _this.grid.loadMask.el.mask('Cancel edit forecast first!');\n    _this.wgrid.loadMask.el.mask('Cancel edit forecast first!');\r\n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "year_text",
+                                    "clicksToEdit": 1,
+                                    "loadMask": true,
+                                    "xtype": "EditorGrid",
+                                    "|calcest": "function(colname) \n{\n\n    var before = _this.sgrid.ds.getAt(0).data[colname];\n    var last = _this.sgrid.ds.getAt(1).data[colname];\n    var est = last * 2;\n    if(before < last * 2){\n       est = last * 2 - before;\n    }\n    return est;\n}\n",
+                                    "|formatcol": "function(v,r,n) \n{\n   var d = new Date();\n   var y = d.getFullYear();\n   var m = d.getMonth();\n   var month = n.split(\"_\");\n //  var est =  _this.sgrid.calcest(n);\n /*  if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 0){\n        if(month[1] < m + 3)\n        { // fill in blank if the month less than next month\n            return String.format('{0}',''); \n        }\n        if(est > v || v > est * 2 || v * 1 == 0)\n        { //red if forcast is less than estimate or double estimate\n            return '<span style=\"color:red\">' + v + ' ( ' + est + ' )</span>';\n        }\n        return String.format('{0}',v + ' ( ' + est + ' )'); \n    }\n    if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 1){\n        var t = '';\n        if((typeof(v) != undefined && v > 0)){\n            t += v + ' ';\n        }\n        if(typeof(r.json[n + '_sum']) != undefined && r.json[n + '_sum'] > 0){\n            t += 'sum( ' + r.json[n + '_sum'] + ' )';\n        }\n        if(month[1] > m + 2 && month[1] < m + 7 && !t){\n            return '<span style=\"color:red\">MUST FILL IN (' + est + ')</span>';\n        }\n        return String.format('{0}',t); \n    }\n    */\n    \n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    // forecast - item level \n    \n    \n    if(r.data.type == 'confirm' && s.data.cust_id < 0 && v){\n        return String.format('SUM ( {0} )',v); \n    } \n    \n    if(r.data.type == 'percentage' && v){\n        return  String.format('<span style=\"color:green\">{0}%</span>', Roo.util.Format.number(v,2));\n    } \n    \n    if(r.data.type == 'predicted' && v < 0){\n        return  String.format('<span style=\"color:red\">{0}</span>', 'BAD GUESS');\n    }\n    \n    \n    return String.format('{0}',v); \n\n}\n",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    o.params = o.params || {};\n    \n    var rec = _this.grid.getSelectionModel().getSelected();\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    \n    if(!_this.grid || !rec || !s){\n        this.removeAll();\n        return;\n    }\n    \n    o.params._detailView = 1;\n    o.params._item_id = rec.data.item_id;\n    o.params._in_cust_id = (s.data.cust_id < 0) ? 0 : s.data.cust_id;\r\n    o.params._is_all_buyers = (s.data.view_type) == 'All' ? 1 : 0;\n    \r\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/Salesforecast.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "xtype": "JsonReader",
+                                                    "|fields": "[\n    {\n        'name': 'total_1',\n        'type': 'int'\n    },\n    {\n        'name': 'total_2',\n        'type': 'int'\n    },\n    {\n        'name': 'total_3',\n        'type': 'int'\n    },\n    {\n        'name': 'total_4',\n        'type': 'int'\n    },\n    {\n        'name': 'total_5',\n        'type': 'int'\n    },\n    {\n        'name': 'total_6',\n        'type': 'int'\n    },\n    {\n        'name': 'total_7',\n        'type': 'int'\n    },\n    {\n        'name': 'total_8',\n        'type': 'int'\n    },\n    {\n        'name': 'total_9',\n        'type': 'int'\n    },\n    {\n        'name': 'total_10',\n        'type': 'int'\n    },\n    {\n        'name': 'total_11',\n        'type': 'int'\n    },\n    {\n        'name': 'total_12',\n        'type': 'int'\n    },\n    {\n        'name': 'type',\n        'type': 'string'\n    },\n    {\n        'name': 'year_text',\n        'type': 'string'\n    },\n    {\n        'name': 'year',\n        'type': 'int'\n    }\n]",
+                                                    "|xns": "Roo.data"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "|xns": "Roo",
+                                            "xtype": "Toolbar",
+                                            "*prop": "toolbar",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var d = new Date();\n    var m = d.getMonth(); // getMonth -> 0-11\n    var y = new Date().getFullYear();\n    \n    var salesforecasts = [];\n    var est = 0;\n    var salesforecast_id = 0;\n    var qty = 0;\n    var rec = _this.grid.getSelectionModel().getSelected();\r\n    var s = _this.wgrid.getSelectionModel().getSelected();\n    if(!rec || !s){\n        Roo.Msg.alert(\"Error\",\"Please select a item\");\n        return;\n    }\n    if(rec.data.itemsrc_active * 1 < 1 ){\n        Roo.Msg.alert(\"Error\",\"The itemsrc is not active!\");\n        return;\n    }\n    if(s.data.cust_id < 0){\n        Roo.Msg.alert(\"Error\",\"Auto Fill Just happen on company level, please select a company!\");\n        return;\n    }\n\n    for(var i = 3; i < 13 - m; i++){ //  current month and the next month are not able to edit.\n    \n        var salesforecast = {};\n        \n        salesforecast_id = _this.sgrid.ds.getAt(3).json['total_' + (m + i) + '_salesforecast_id']; // check existing or not ???\n        est = _this.sgrid.ds.getAt(2).json['total_' + (m + i)]; // estimated qty!\n        qty = _this.sgrid.ds.getAt(3).json['total_' + (m + i)]; // existing qty!\n        \n        salesforecast['month'] = m + i; // period month\n        salesforecast['year'] = y; // period year\n        \n        salesforecast['salesforecast_id'] = (salesforecast_id * 1 > 0) ? salesforecast_id : 0; // update or insert ???\n        salesforecast['salesforecast_qty'] = (qty != 0) ? qty : est; // if we have entried in this period. do not use the estimated\n        \n        salesforecast['_item_id'] = rec.data.item_id;\n        \n        salesforecast['salesforecast_cust_id'] = s.data.cust_id;\n        \n        salesforecast['salesforecast_is_all_buyers'] = 0;\n        \n        salesforecasts.push((salesforecast)); \n    }\n    \n    if(!salesforecasts.length){\n        return;\n    }\n    new Pman.Request({\n        url : baseURL + '/Roo/Salesforecast.php',\n        method :'POST',\n        params : {\n            _group_data : Roo.encode(salesforecasts)\n            \n        },\n        success : function() {\n           \n            _this.sgrid.footer.onClick('first');\n            \n        }\n    });\n    \n \n}"
+                                                    },
+                                                    "text": "Auto Fill  (This Year)",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "xtype": "PagingToolbar",
+                                            "pageSize": 25,
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying Groups{0} - {1} of {2}",
+                                            "emptyMsg": "No Groups found",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "year_text",
+                                            "header": "Scenario / Month",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_1",
+                                            "header": "Jan",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_2",
+                                            "header": "Feb",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_3",
+                                            "header": "Mar",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_4",
+                                            "header": "Apr",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_5",
+                                            "header": "May",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_6",
+                                            "header": "Jun",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_7",
+                                            "header": "Jul",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_8",
+                                            "header": "Aug",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_9",
+                                            "header": "Sep",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_10",
+                                            "header": "Oct",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_11",
+                                            "header": "Nov",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_12",
+                                            "header": "Dec",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) \n{\n   return _this.sgrid.formatcol(v,r,this.name);\n}",
+                                            "|xns": "Roo.grid",
+                                            "items": [
+                                                {
+                                                    "|xns": "Roo.grid",
+                                                    "xtype": "GridEditor",
+                                                    "*prop": "editor",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "field",
+                                                            "allowDecimals": false,
+                                                            "xtype": "NumberField",
+                                                            "|xns": "Roo.form"
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "total_year",
+                                            "header": "Total",
+                                            "width": 100,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "600"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSalesPlanning.js b/Pman.Tab.XtupleSalesPlanning.js
new file mode 100644 (file)
index 0000000..cd12856
--- /dev/null
@@ -0,0 +1,1542 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSalesPlanning = new Roo.XComponent({
+    part     :  ["Xtuple","SalesPlanning"],
+    order    : '600-Pman.Tab.XtupleSalesPlanning',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "Pman.Tab.XtupleSalesPlanning",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            listeners : {
+                activate : function (_self)
+                {
+                   // Roo.log(Pman.hasPerm('Xtuple.SalesPlanner', 'S'));
+                   // Roo.log(Pman.Login.authUser);
+                }
+            },
+            background : false,
+            fitContainer : true,
+            fitToFrame : true,
+            title : "Sales Planning",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'NestedLayoutPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function (_self)
+                            {
+                                _self.layout.getRegion('center').showPanel(0);
+                            }
+                        },
+                        background : false,
+                        fitContainer : true,
+                        fitToFrame : true,
+                        region : 'center',
+                        layout : {
+                            xtype: 'BorderLayout',
+                            xns: Roo,
+                            items : [
+                                {
+                                    xtype: 'GridPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        activate : function() {
+                                            _this.panel = this;
+                                            
+                                          //  if (_this.grid) {
+                                          //      _this.grid.footer.onClick('first');
+                                          //  }
+                                        }
+                                    },
+                                    background : false,
+                                    fitContainer : true,
+                                    fitToframe : true,
+                                    region : 'center',
+                                    tableName : 'item',
+                                    title : "Item",
+                                    grid : {
+                                        xtype: 'Grid',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            render : function() 
+                                            {
+                                                _this.grid = this; 
+                                                //_this.dialog = Pman.Dialog.FILL_IN
+                                              //  if (_this.panel.active) {
+                                               //    this.footer.onClick('first');
+                                              //  }
+                                            }
+                                        },
+                                        autoExpandColumn : 'item_descrip1',
+                                        loadMask : true,
+                                        sm : {
+                                            xtype: 'RowSelectionModel',
+                                            xns: Roo.grid,
+                                            listeners : {
+                                                afterselectionchange : function (_self)
+                                                {
+                                                    if (_this.sgrid) {
+                                                        _this.sgrid.footer.onClick('first');
+                                                    }
+                                                }
+                                            },
+                                            singleSelect : true
+                                        },
+                                        dataSource : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o)
+                                                {
+                                                    o.params = o.params || {};
+                                                    
+                                                    var s = _this.wgrid.getSelectionModel().getSelected();
+                                                    if(!s.data.cust_id){
+                                                        _this.grid.ds.removeAll();
+                                                        return false;
+                                                    }
+                                                    _this.sgrid.ds.removeAll();
+                                                    
+                                                    o.params._with_year_total = 1;
+                                                    
+                                                    o.params._charass_brand_value = _this.brandSel.getValue();
+                                                    o.params._charass_group_value = _this.groupSel.getValue();
+                                                    
+                                                    o.params._with_itemsrc_active = 1;
+                                                    o.params._in_cust_id = s.data.cust_id;
+                                                    
+                                                    var date = new Date();
+                                                    var year = date.getFullYear(); // four digits
+                                                    var month = date.getMonth(); // 0-11
+                                                    
+                                                    var cm = _this.grid.getColumnModel();
+                                                    function cid(str) {\r
+                                                        return cm.getIndexByDataIndex(str);\r
+                                                    }\r    
+                                                    
+                                                    cm.setColumnHeader(cid('total_before_last_year'),'Total ' + (year - 2));
+                                                    cm.setColumnHeader(cid('total_last_year'),'Total ' + (year - 1));
+                                                    cm.setColumnHeader(cid('forecast_this_year'),'Forecast ' + year);
+                                                    cm.setColumnHeader(cid('total_this_year'),'Total ' + year);
+                                                    
+                                                    if(month > 5){
+                                                        cm.setColumnHeader(cid('forecast_next_year'),'Total ' + (year + 1));
+                                                        cm.setHidden(cid('forecast_next_year'),false);
+                                                    }
+                                                    // it make the grid slow, change it later!
+                                                    if(s.data.cust_name == 'All Companies'){
+                                                        cm.setHidden(cid('forecast_this_year'),true);
+                                                        cm.setHidden(cid('company_estimates'),false);
+                                                    }else{
+                                                        cm.setHidden(cid('forecast_this_year'),false);
+                                                        cm.setHidden(cid('company_estimates'),true);
+                                                    }
+                                                    
+                                                
+                                                },
+                                                load : function (_self, records, options)
+                                                {
+                                                    var sm = _this.grid.getSelectionModel();
+                                                    Roo.each(records, function(record){
+                                                        if(record.data.item_id == _this.grid.lastSelectedId){
+                                                            sm.selectRow(_this.grid.ds.indexOf(record));
+                                                            if (_this.sgrid) {
+                                                                _this.sgrid.footer.onClick('first');
+                                                            }
+                                                        }
+                                                    })
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { field : 'item_number', direction: 'ASC' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/Item.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [
+                                                    {
+                                                        'name': 'item_number',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'item_descrip1',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'total_before_last_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'total_last_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'forecast_this_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'total_this_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'total_next_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'forecast_next_year',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'last_forecast_entered',
+                                                        'type': 'string'
+                                                    }
+                                                ]
+                                            }
+                                        },
+                                        footer : {
+                                            xtype: 'PagingToolbar',
+                                            xns: Roo,
+                                            displayInfo : true,
+                                            displayMsg : "Displaying Item{0} - {1} of {2}",
+                                            emptyMsg : "No Item found",
+                                            pageSize : 25
+                                        },
+                                        toolbar : {
+                                            xtype: 'Toolbar',
+                                            xns: Roo,
+                                            items : [
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        render : function (_self)
+                                                        {
+                                                          _this.brandSel = _self;
+                                                          
+                                                        },
+                                                        select : function (combo, record, index)
+                                                        {
+                                                            _this.wgrid.ds.load({});}
+                                                    },
+                                                    allowBlank : true,
+                                                    alwaysQuery : true,
+                                                    displayField : 'charass_value',
+                                                    editable : true,
+                                                    emptyText : "Select Brand",
+                                                    forceSelection : true,
+                                                    listWidth : 300,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    pageSize : 20,
+                                                    qtip : "Select Brand",
+                                                    queryParam : 'query[charass_value]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
+                                                    triggerAction : 'all',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o)
+                                                            {
+                                                                o.params = o.params || {};
+                                                                // staff can see all logs, other companies can only see their own.
+                                                                // look for all of the charass 's with the same type= eg. brand.
+                                                                
+                                                                o.params.charass_char_id_char_name = 'BRAND';
+                                                                o.params.charass_target_type ='I';
+                                                                o.params._distinct = 'charass_value';
+                                                                o.params._columns = 'charass_value';
+                                                            
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { field : 'charass_value' , direction : 'ASC' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/Charass.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [
+                                                                {
+                                                                    'name': 'id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_name',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'event_when',
+                                                                    'type': 'date',
+                                                                    'dateFormat': 'Y-m-d'
+                                                                },
+                                                                {
+                                                                    'name': 'action',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'ipaddr',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'on_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'on_table',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'remarks',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_office_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_name',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_phone',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_fax',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_email',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_company_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_role',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_active',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_remarks',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_passwd',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_owner_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_lang',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_no_reset_sent',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_action_type',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_project_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_deleted_by',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_deleted_dt',
+                                                                    'type': 'date'
+                                                                }
+                                                            ]
+                                                        }
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'ComboBox',
+                                                    xns: Roo.form,
+                                                    listeners : {
+                                                        render : function (_self)
+                                                        {
+                                                          _this.groupSel = _self;
+                                                        },
+                                                        select : function (combo, record, index)
+                                                        {
+                                                            _this.wgrid.ds.load({});
+                                                        }
+                                                    },
+                                                    allowBlank : true,
+                                                    alwaysQuery : true,
+                                                    displayField : 'charass_value',
+                                                    editable : true,
+                                                    emptyText : "Select Product Group",
+                                                    forceSelection : true,
+                                                    listWidth : 300,
+                                                    loadingText : "Searching...",
+                                                    minChars : 2,
+                                                    pageSize : 20,
+                                                    qtip : "Select Product Group",
+                                                    queryParam : 'query[charass_value]',
+                                                    selectOnFocus : true,
+                                                    tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
+                                                    triggerAction : 'all',
+                                                    width : 200,
+                                                    store : {
+                                                        xtype: 'Store',
+                                                        xns: Roo.data,
+                                                        listeners : {
+                                                            beforeload : function (_self, o)
+                                                            {
+                                                                o.params = o.params || {};
+                                                                // staff can see all logs, other companies can only see their own.
+                                                                // look for all of the charass 's with the same type= eg. brand.
+                                                                
+                                                                o.params.charass_char_id_char_name = 'PRODUCTGROUP';
+                                                                o.params.charass_target_type ='I';
+                                                                o.params._distinct = 'charass_value';
+                                                                    o.params._columns = 'charass_value';
+                                                            
+                                                            }
+                                                        },
+                                                        remoteSort : true,
+                                                        sortInfo : { field : 'charass_value' , direction : 'ASC' },
+                                                        proxy : {
+                                                            xtype: 'HttpProxy',
+                                                            xns: Roo.data,
+                                                            method : 'GET',
+                                                            url : baseURL + '/Roo/Charass.php'
+                                                        },
+                                                        reader : {
+                                                            xtype: 'JsonReader',
+                                                            xns: Roo.data,
+                                                            id : 'id',
+                                                            root : 'data',
+                                                            totalProperty : 'total',
+                                                            fields : [
+                                                                {
+                                                                    'name': 'id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_name',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'event_when',
+                                                                    'type': 'date',
+                                                                    'dateFormat': 'Y-m-d'
+                                                                },
+                                                                {
+                                                                    'name': 'action',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'ipaddr',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'on_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'on_table',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'remarks',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_office_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_name',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_phone',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_fax',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_email',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_company_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_role',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_active',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_remarks',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_passwd',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_owner_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_lang',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_no_reset_sent',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_action_type',
+                                                                    'type': 'string'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_project_id',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_deleted_by',
+                                                                    'type': 'int'
+                                                                },
+                                                                {
+                                                                    'name': 'person_id_deleted_dt',
+                                                                    'type': 'date'
+                                                                }
+                                                            ]
+                                                        }
+                                                    }
+                                                },
+                                                {
+                                                    xtype: 'Fill',
+                                                    xns: Roo.Toolbar
+                                                },
+                                                {
+                                                    xtype: 'Button',
+                                                    xns: Roo.Toolbar,
+                                                    listeners : {
+                                                        click : function ()
+                                                        {
+                                                            var brand = _this.brandSel.getValue();
+                                                            var group = _this.groupSel.getValue();
+                                                            
+                                                            if(!brand && !group){
+                                                                Roo.MessageBox.alert('Error','Please select the brand or group');
+                                                                return;
+                                                            }
+                                                            
+                                                            Roo.MessageBox.alert("Notice","Your report should be downloading now");
+                                                            
+                                                            new Pman.download({
+                                                                url : baseURL + '/Roo/Salesforecast',
+                                                                method : 'GET',
+                                                                timeout: 900000,
+                                                                params : {
+                                                                    '_download' : 1,
+                                                                    'brand' : brand,
+                                                                    'group' : group
+                                                                }
+                                                            });  
+                                                           
+                                                        }
+                                                    },
+                                                    cls : 'x-btn-text-icon',
+                                                    text : "Download Report",
+                                                    icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
+                                                }
+                                            ]
+                                        },
+                                        colModel : [
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'itemsrc_active',
+                                                header : 'is Active?',
+                                                width : 50,
+                                                renderer : function(v) {  
+                                                    var state = v * 1 > 0 ?  '-checked' : '';
+                                                
+                                                    return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                                
+                                                 }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'item_number',
+                                                header : 'Item code',
+                                                width : 200,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'item_descrip1',
+                                                header : 'Item name',
+                                                width : 200,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'total_before_last_year',
+                                                header : 'Total',
+                                                width : 150,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'total_last_year',
+                                                header : 'Total',
+                                                width : 150,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'forecast_this_year',
+                                                header : 'Forecast',
+                                                width : 150,
+                                                renderer : function(v,x,r) { 
+                                                    
+                                                    if (v*1 == 0) {
+                                                    
+                                                        return '<span style="color:red">' + v + '</span>';
+                                                    }
+                                                    
+                                                    return String.format('{0}', v);
+                                                    
+                                                    
+                                                }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'total_this_year',
+                                                header : 'Total',
+                                                width : 150,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'forecast_next_year',
+                                                header : 'Forecast',
+                                                hidden : true,
+                                                width : 150,
+                                                renderer : function(v,x,r) { 
+                                                    
+                                                    if (v*1 == 0) {
+                                                    
+                                                        return '<span style="color:red">' + v + '</span>';
+                                                    }
+                                                    
+                                                    return String.format('{0}', v);
+                                                    
+                                                    
+                                                }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'last_forecast_entered',
+                                                header : 'Last forcast entered',
+                                                width : 150,
+                                                renderer : function(v,x,r) {
+                                                    if(!v){
+                                                        return;
+                                                    }
+                                                    var last_forecast = new Date(v);
+                                                    
+                                                    var date = new Date();
+                                                    var y = date.getFullYear();
+                                                    var m = date.getMonth() + 3;
+                                                    var d = date.getDate();
+                                                    if(m >= 11){
+                                                        y = y + 1;
+                                                        m = m - 11;
+                                                    }
+                                                    var c = new Date(y,m,d);
+                                                    if (last_forecast < c) {
+                                                        return '<span style="color:red">' + last_forecast.format('M Y') + '</span>';
+                                                    }
+                                                    
+                                                    return String.format('{0}', last_forecast.format('M Y'));
+                                                    
+                                                    
+                                                }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'company_estimates',
+                                                header : 'Estimates',
+                                                hidden : true,
+                                                width : 150,
+                                                renderer : function(v,x,r) {
+                                                    return String.format('{0}', v);
+                                                    
+                                                    
+                                                }
+                                            }
+                                        ]
+                                    }
+                                },
+                                {
+                                    xtype: 'GridPanel',
+                                    xns: Roo,
+                                    listeners : {
+                                        activate : function() {
+                                            _this.wpanel = this;
+                                            if (_this.wgrid) {
+                                                _this.wgrid.ds.load({});
+                                            }
+                                        }
+                                    },
+                                    background : true,
+                                    fitContainer : true,
+                                    fitToframe : true,
+                                    region : 'west',
+                                    tableName : 'custinfo',
+                                    title : "Customer",
+                                    grid : {
+                                        xtype: 'Grid',
+                                        xns: Roo.grid,
+                                        listeners : {
+                                            render : function() 
+                                            {
+                                                _this.wgrid = this; 
+                                                if (_this.wpanel.active) {
+                                                    _this.wgrid.ds.load({});
+                                                }
+                                            },
+                                            rowclick : function (_self, rowIndex, e)
+                                            {
+                                                var sm = _this.grid.getSelectionModel();
+                                               if(sm.getSelections().length){
+                                                     _this.grid.lastSelectedId = sm.getSelections()[0].data.item_id;
+                                                 }
+                                                _this.grid.footer.onClick('refresh');
+                                            }
+                                        },
+                                        autoExpandColumn : 'cust_name_with_pcs',
+                                        loadMask : true,
+                                        dataSource : {
+                                            xtype: 'Store',
+                                            xns: Roo.data,
+                                            listeners : {
+                                                beforeload : function (_self, o){
+                                                    o.params = o.params || {};
+                                                    
+                                                    o.params._with_lastyear_total = 1;
+                                                    o.params._columns = 'cust_id,cust_name,lastyear_total';
+                                                    
+                                                    var brand = _this.brandSel.getValue();
+                                                    if(!brand.length){
+                                                        _this.wgrid.ds.removeAll();
+                                                        _this.grid.ds.removeAll();
+                                                        return false;
+                                                    }
+                                                    
+                                                    o.params._charass_brand_value = _this.brandSel.getValue();
+                                                    o.params._charass_group_value = _this.groupSel.getValue();
+                                                    
+                                                    o.params.limit = 9999;
+                                                    
+                                                },
+                                                load : function (_self, records, options)
+                                                {
+                                                    var sm = _this.wgrid.getSelectionModel();
+                                                    if (!sm.getSelections().length) {
+                                                        sm.selectFirstRow();
+                                                    }
+                                                    
+                                                    _this.grid.footer.onClick('first');
+                                                }
+                                            },
+                                            remoteSort : true,
+                                            sortInfo : { field : 'lastyear_total', direction: 'DESC' },
+                                            proxy : {
+                                                xtype: 'HttpProxy',
+                                                xns: Roo.data,
+                                                method : 'GET',
+                                                url : baseURL + '/Roo/Custinfo.php'
+                                            },
+                                            reader : {
+                                                xtype: 'JsonReader',
+                                                xns: Roo.data,
+                                                id : 'id',
+                                                root : 'data',
+                                                totalProperty : 'total',
+                                                fields : [
+                                                    {
+                                                        'name': 'cust_id',
+                                                        'type': 'int'
+                                                    },
+                                                    {
+                                                        'name': 'cust_name_with_pcs',
+                                                        'type': 'string'
+                                                    },
+                                                    {
+                                                        'name': 'lastyear_total',
+                                                        'type': 'int'
+                                                    }
+                                                ]
+                                            }
+                                        },
+                                        colModel : [
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'cust_name',
+                                                header : 'Company Name',
+                                                width : 200,
+                                                renderer : function(v) { return String.format('{0}', v); }
+                                            },
+                                            {
+                                                xtype: 'ColumnModel',
+                                                xns: Roo.grid,
+                                                dataIndex : 'lastyear_total',
+                                                header : '',
+                                                width : 75,
+                                                renderer : function(v,x,r) 
+                                                {
+                                                    return String.format('{0}', v + ' pcs'); 
+                                                }
+                                            }
+                                        ]
+                                    }
+                                }
+                            ],
+                            center : {
+                                xtype: 'LayoutRegion',
+                                xns: Roo
+                            },
+                            west : {
+                                xtype: 'LayoutRegion',
+                                xns: Roo,
+                                split : true,
+                                tabPosition : 'top',
+                                width : 300
+                            }
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.spanel = this;
+                              /*  if (_this.sgrid) {
+                                    _this.sgrid.footer.onClick('first');
+                                } */
+                            }
+                        },
+                        background : false,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'south',
+                        tableName : 'Groups',
+                        title : "Details",
+                        grid : {
+                            xtype: 'EditorGrid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.sgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                   /* if (_this.spanel.active) {
+                                       this.footer.onClick('first');
+                                    } */
+                                },
+                                afteredit : function (e)
+                                {
+                                    _this.grid.loadMask.el.unmask();
+                                    _this.wgrid.loadMask.el.unmask();
+                                    if(e.value == e.originalValue){
+                                        return;
+                                    }
+                                    var field = e.field;
+                                    var salesforecast_id = e.record.json[field + '_salesforecast_id'];
+                                    var rec = _this.grid.getSelectionModel().getSelected();
+                                    var s = _this.wgrid.getSelectionModel().getSelected();
+                                    
+                                    if(!rec || !s){
+                                        Roo.Msg.alert("Error","Please select a item");
+                                        return;
+                                    }
+                                    
+                                    var params = {
+                                            salesforecast_id : (salesforecast_id * 1 > 0) ? salesforecast_id : 0,
+                                            salesforecast_cust_id : (s.data.cust_id < 0) ? 0 : s.data.cust_id,
+                                            salesforecast_is_all_buyers : (s.data.view_type) == 'All' ? 1 : 0,
+                                            _item_id : rec.data.item_id,
+                                            month : e.column,
+                                            year : e.record.data['year']
+                                        }
+                                    
+                                    if(s.data.cust_id > 0){ // company level confirm and request editable!
+                                        if(e.record.data['type'] == 'confirm'){
+                                            params.salesforecast_qty = e.value;
+                                        }
+                                        if(e.record.data['type'] == 'request'){
+                                            params.salesforecast_requests = e.value;
+                                        }
+                                    } else { // item level estimated and total forecast editable!
+                                        if(e.record.data['type'] == 'estimated'){
+                                            params.salesforecast_qty = e.value;
+                                        }
+                                        if(e.record.data['type'] == 'forecast'){
+                                            params.salesforecast_sum = e.value;
+                                        }
+                                    }
+                                    
+                                    
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/Salesforecast.php',
+                                        method :'POST',
+                                        params : params,
+                                        success : function() {
+                                           
+                                            _this.sgrid.footer.onClick('first');
+                                            
+                                        }
+                                    });
+                                    
+                                },
+                                beforeedit : function (e)
+                                {   
+                                    var rec = e.record;
+                                    var y = new Date().getFullYear();
+                                    var m = new Date().getMonth(); // 0-11
+                                    var s = _this.grid.getSelectionModel().getSelected();
+                                    var ss = _this.wgrid.getSelectionModel().getSelected();
+                                   
+                                   /*\r
+                                    if(rec.data.type != 'forecast' || rec.data.year != y || !s.data.itemsrc_active || e.column < m + 3){\r
+                                        return false;\r
+                                    }
+                                    */
+                                
+                                    if(s.data.itemsrc_active * 1 < 1 || (rec.data.year == y && e.column < m + 3) || (rec.data.year != y && e.column + 12 < m + 3)){
+                                        return false;
+                                    }
+                                    if(ss.data.cust_id > 0){ // companies level, confirm and request editable!
+                                        if(rec.data.type != 'confirm' && rec.data.type != 'request'){
+                                            return false;
+                                        }
+                                    }else{ // item level, estimated and total forecast  editable!
+                                        if(rec.data.type != 'estimated' && rec.data.type != 'forecast'){
+                                            return false;
+                                        }
+                                    }
+                                    
+                                    _this.grid.loadMask.el.mask('Cancel edit forecast first!');
+                                    _this.wgrid.loadMask.el.mask('Cancel edit forecast first!');\r
+                                }
+                            },
+                            autoExpandColumn : 'year_text',
+                            clicksToEdit : 1,
+                            loadMask : true,
+                            calcest : function(colname) 
+                            {
+                            
+                                var before = _this.sgrid.ds.getAt(0).data[colname];
+                                var last = _this.sgrid.ds.getAt(1).data[colname];
+                                var est = last * 2;
+                                if(before < last * 2){
+                                   est = last * 2 - before;
+                                }
+                                return est;
+                            },
+                            formatcol : function(v,r,n) 
+                            {
+                               var d = new Date();
+                               var y = d.getFullYear();
+                               var m = d.getMonth();
+                               var month = n.split("_");
+                             //  var est =  _this.sgrid.calcest(n);
+                             /*  if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 0){
+                                    if(month[1] < m + 3)
+                                    { // fill in blank if the month less than next month
+                                        return String.format('{0}',''); 
+                                    }
+                                    if(est > v || v > est * 2 || v * 1 == 0)
+                                    { //red if forcast is less than estimate or double estimate
+                                        return '<span style="color:red">' + v + ' ( ' + est + ' )</span>';
+                                    }
+                                    return String.format('{0}',v + ' ( ' + est + ' )'); 
+                                }
+                                if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 1){
+                                    var t = '';
+                                    if((typeof(v) != undefined && v > 0)){
+                                        t += v + ' ';
+                                    }
+                                    if(typeof(r.json[n + '_sum']) != undefined && r.json[n + '_sum'] > 0){
+                                        t += 'sum( ' + r.json[n + '_sum'] + ' )';
+                                    }
+                                    if(month[1] > m + 2 && month[1] < m + 7 && !t){
+                                        return '<span style="color:red">MUST FILL IN (' + est + ')</span>';
+                                    }
+                                    return String.format('{0}',t); 
+                                }
+                                */
+                                
+                                var s = _this.wgrid.getSelectionModel().getSelected();
+                                
+                                // forecast - item level 
+                                
+                                
+                                if(r.data.type == 'confirm' && s.data.cust_id < 0 && v){
+                                    return String.format('SUM ( {0} )',v); 
+                                } 
+                                
+                                if(r.data.type == 'percentage' && v){
+                                    return  String.format('<span style="color:green">{0}%</span>', Roo.util.Format.number(v,2));
+                                } 
+                                
+                                if(r.data.type == 'predicted' && v < 0){
+                                    return  String.format('<span style="color:red">{0}</span>', 'BAD GUESS');
+                                }
+                                
+                                
+                                return String.format('{0}',v); 
+                            
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        o.params = o.params || {};
+                                        
+                                        var rec = _this.grid.getSelectionModel().getSelected();
+                                        var s = _this.wgrid.getSelectionModel().getSelected();
+                                        
+                                        if(!_this.grid || !rec || !s){
+                                            this.removeAll();
+                                            return;
+                                        }
+                                        
+                                        o.params._detailView = 1;
+                                        o.params._item_id = rec.data.item_id;
+                                        o.params._in_cust_id = (s.data.cust_id < 0) ? 0 : s.data.cust_id;\r
+                                        o.params._is_all_buyers = (s.data.view_type) == 'All' ? 1 : 0;
+                                        \r
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/Salesforecast.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [
+                                        {
+                                            'name': 'total_1',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_2',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_3',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_4',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_5',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_6',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_7',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_8',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_9',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_10',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_11',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'total_12',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'type',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'year_text',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'year',
+                                            'type': 'int'
+                                        }
+                                    ]
+                                }
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var d = new Date();
+                                                var m = d.getMonth(); // getMonth -> 0-11
+                                                var y = new Date().getFullYear();
+                                                
+                                                var salesforecasts = [];
+                                                var est = 0;
+                                                var salesforecast_id = 0;
+                                                var qty = 0;
+                                                var rec = _this.grid.getSelectionModel().getSelected();\r
+                                                var s = _this.wgrid.getSelectionModel().getSelected();
+                                                if(!rec || !s){
+                                                    Roo.Msg.alert("Error","Please select a item");
+                                                    return;
+                                                }
+                                                if(rec.data.itemsrc_active * 1 < 1 ){
+                                                    Roo.Msg.alert("Error","The itemsrc is not active!");
+                                                    return;
+                                                }
+                                                if(s.data.cust_id < 0){
+                                                    Roo.Msg.alert("Error","Auto Fill Just happen on company level, please select a company!");
+                                                    return;
+                                                }
+                                            
+                                                for(var i = 3; i < 13 - m; i++){ //  current month and the next month are not able to edit.
+                                                
+                                                    var salesforecast = {};
+                                                    
+                                                    salesforecast_id = _this.sgrid.ds.getAt(3).json['total_' + (m + i) + '_salesforecast_id']; // check existing or not ???
+                                                    est = _this.sgrid.ds.getAt(2).json['total_' + (m + i)]; // estimated qty!
+                                                    qty = _this.sgrid.ds.getAt(3).json['total_' + (m + i)]; // existing qty!
+                                                    
+                                                    salesforecast['month'] = m + i; // period month
+                                                    salesforecast['year'] = y; // period year
+                                                    
+                                                    salesforecast['salesforecast_id'] = (salesforecast_id * 1 > 0) ? salesforecast_id : 0; // update or insert ???
+                                                    salesforecast['salesforecast_qty'] = (qty != 0) ? qty : est; // if we have entried in this period. do not use the estimated
+                                                    
+                                                    salesforecast['_item_id'] = rec.data.item_id;
+                                                    
+                                                    salesforecast['salesforecast_cust_id'] = s.data.cust_id;
+                                                    
+                                                    salesforecast['salesforecast_is_all_buyers'] = 0;
+                                                    
+                                                    salesforecasts.push((salesforecast)); 
+                                                }
+                                                
+                                                if(!salesforecasts.length){
+                                                    return;
+                                                }
+                                                new Pman.Request({
+                                                    url : baseURL + '/Roo/Salesforecast.php',
+                                                    method :'POST',
+                                                    params : {
+                                                        _group_data : Roo.encode(salesforecasts)
+                                                        
+                                                    },
+                                                    success : function() {
+                                                       
+                                                        _this.sgrid.footer.onClick('first');
+                                                        
+                                                    }
+                                                });
+                                                
+                                             
+                                            }
+                                        },
+                                        text : "Auto Fill  (This Year)"
+                                    }
+                                ]
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                pageSize : 25,
+                                displayInfo : true,
+                                displayMsg : "Displaying Groups{0} - {1} of {2}",
+                                emptyMsg : "No Groups found"
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'year_text',
+                                    header : 'Scenario / Month',
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_1',
+                                    header : 'Jan',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_2',
+                                    header : 'Feb',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_3',
+                                    header : 'Mar',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_4',
+                                    header : 'Apr',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_5',
+                                    header : 'May',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_6',
+                                    header : 'Jun',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_7',
+                                    header : 'Jul',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_8',
+                                    header : 'Aug',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_9',
+                                    header : 'Sep',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_10',
+                                    header : 'Oct',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_11',
+                                    header : 'Nov',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_12',
+                                    header : 'Dec',
+                                    width : 100,
+                                    renderer : function(v,x,r) 
+                                    {
+                                       return _this.sgrid.formatcol(v,r,this.name);
+                                    },
+                                    editor : {
+                                        xtype: 'GridEditor',
+                                        xns: Roo.grid,
+                                        field : {
+                                            xtype: 'NumberField',
+                                            xns: Roo.form,
+                                            allowDecimals : false
+                                        }
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'total_year',
+                                    header : 'Total',
+                                    width : 100,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                south : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    height : 400,
+                    split : true
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleSalesShipment.bjs b/Pman.Tab.XtupleSalesShipment.bjs
new file mode 100644 (file)
index 0000000..41b20ac
--- /dev/null
@@ -0,0 +1,200 @@
+{
+    "id": "roo-file-44",
+    "name": "Pman.Tab.XtupleSalesShipment",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleSalesShipment.bjs",
+    "items": [
+        {
+            "|xns": "Roo",
+            "xtype": "GridPanel",
+            ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_order_id\",\"columnshort\":\"shiphead_order_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Shipment#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_notes\",\"columnshort\":\"shiphead_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipped\",\"columnshort\":\"shiphead_shipped\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_notes\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+            "title": "Fullfillments",
+            "fitToframe": true,
+            "fitContainer": true,
+            "tableName": "shiphead",
+            "background": true,
+            "region": "center",
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    try { \n        _this.dialog = Pman.Dialog.XtupleSalesOrder;\n    } catch(e) {}\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n     if (!_this.dialog) return;\n     \n     var d =  this.getDataSource().getAt(rowIndex).data;\n    _this.dialog.show( {\n        cohead_id : d.shiphead_order_id\n    \n    }, function() {\n        _this.grid.footer.onClick('refresh');\n        Pman.Tab.XtupleSales.grid.footer.onClick('first');\n    }); \n}\n"
+                    },
+                    "*prop": "grid",
+                    ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_order_id\",\"columnshort\":\"shiphead_order_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Shipment#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_notes\",\"columnshort\":\"shiphead_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipped\",\"columnshort\":\"shiphead_shipped\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_notes\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                    "autoExpandColumn": "shiphead_notes",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "xtype": "Store",
+                            "|xns": "Roo.data",
+                            ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_order_id\",\"columnshort\":\"shiphead_order_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Shipment#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_notes\",\"columnshort\":\"shiphead_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipped\",\"columnshort\":\"shiphead_shipped\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_notes\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                            "remoteSort": true,
+                            "|sortInfo": "{ field : 'shiphead_notes', direction: 'ASC' }",
+                            "*prop": "dataSource",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "xtype": "HttpProxy",
+                                    "method": "GET",
+                                    "|url": "baseURL + '/Roo/shiphead.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    ".builderCfg": "{\"cols\":[{\"table\":\"shiphead\",\"column\":\"shiphead_order_id\",\"columnshort\":\"shiphead_order_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Shipment#\"},{\"table\":\"shiphead\",\"column\":\"shiphead_notes\",\"columnshort\":\"shiphead_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipped\",\"columnshort\":\"shiphead_shipped\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"},{\"table\":\"shiphead\",\"column\":\"shiphead_sfstatus\",\"columnshort\":\"shiphead_sfstatus\",\"ctype\":\"bpchar\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}],\"cols_ex\":[\"shiphead_notes\"],\"table\":\"shiphead\",\"xtype\":\"GridPanel\",\"|xns\":\"Roo\"}",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'shiphead_order_id',\n        'type': 'int'\n    },\n    {\n        'name': 'shiphead_number',\n        'type': 'string'\n    },\n    {\n        'name': 'shiphead_notes',\n        'type': 'string'\n    },\n    {\n        'name': 'shiphead_shipped',\n        'type': 'boolean'\n    },\n    {\n        'name': 'shiphead_shipdate',\n        'type': 'date'\n    },\n    {\n        'name': 'shiphead_sfstatus'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying shiphead{0} - {1} of {2}",
+                            "emptyMsg": "No shiphead found",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "|xns": "Roo.form",
+                                    "xtype": "ComboBox",
+                                    "allowBlank": false,
+                                    "editable": true,
+                                    "emptyText": "Select custinfo",
+                                    "forceSelection": true,
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "pageSize": 20,
+                                    "qtip": "Select Customer",
+                                    "selectOnFocus": true,
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "width": 300,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{cust_name}</b> </div>",
+                                    "queryParam": "query[cust_name]",
+                                    "fieldLabel": "cust_name",
+                                    "valueField": "cust_id",
+                                    "displayField": "cust_name",
+                                    "hiddenName": "cust_id",
+                                    "name": "cust_name",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'shiphead_shipdate' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "xtype": "HttpProxy",
+                                                    "method": "GET",
+                                                    "|xns": "Roo.data",
+                                                    "|url": "baseURL + '/Roo/custinfo.php'"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "cust_id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"cust_id\",\"type\":\"int\"},\"cust_name\"]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_order_id\",\"columnshort\":\"shiphead_order_id\",\"ctype\":\"int4\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"Order#\"}",
+                            "dataIndex": "shiphead_order_id_cohead_number",
+                            "header": "Order#",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "shiphead_custinfo_cust_name",
+                            "header": "Customer",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_number\",\"columnshort\":\"shiphead_number\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":0,\"title\":\"Shipment#\"}",
+                            "dataIndex": "shiphead_number",
+                            "header": "Shipment#",
+                            "sortable": true,
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_notes\",\"columnshort\":\"shiphead_notes\",\"ctype\":\"text\",\"desc\":\"\",\"use\":1,\"use_ex\":1,\"title\":\"\"}",
+                            "header": "notes",
+                            "width": 200,
+                            "dataIndex": "shiphead_notes",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_shipped\",\"columnshort\":\"shiphead_shipped\",\"ctype\":\"bool\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                            "dataIndex": "shiphead_shipped",
+                            "header": "shipped",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n\n\n  \n    if (r.json.shiphead_shipdate.length) {\n    \n        if (r.json.shiphead_shipped) {\n            return \"Confirmed\";\n        }\n    \n         return 'Draft';\n    }\n     \n    return 'VOID';\n   \n\n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            ".builderCfg": "{\"table\":\"shiphead\",\"column\":\"shiphead_shipdate\",\"columnshort\":\"shiphead_shipdate\",\"ctype\":\"date\",\"desc\":\"\",\"use\":1,\"use_ex\":\"\",\"title\":\"\"}",
+                            "dataIndex": "shiphead_shipdate",
+                            "header": "shipdate",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "100"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleSalesShipment.js b/Pman.Tab.XtupleSalesShipment.js
new file mode 100644 (file)
index 0000000..f58b9c0
--- /dev/null
@@ -0,0 +1,245 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleSalesShipment = new Roo.XComponent({
+    part     :  ["Xtuple","SalesShipment"],
+    order    : '100-Pman.Tab.XtupleSalesShipment',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            title : "Fullfillments",
+            fitToframe : true,
+            fitContainer : true,
+            tableName : 'shiphead',
+            background : true,
+            region : 'center',
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        try { 
+                            _this.dialog = Pman.Dialog.XtupleSalesOrder;
+                        } catch(e) {}
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                         if (!_this.dialog) return;
+                         
+                         var d =  this.getDataSource().getAt(rowIndex).data;
+                        _this.dialog.show( {
+                            cohead_id : d.shiphead_order_id
+                        
+                        }, function() {
+                            _this.grid.footer.onClick('refresh');
+                            Pman.Tab.XtupleSales.grid.footer.onClick('first');
+                        }); 
+                    }
+                },
+                autoExpandColumn : 'shiphead_notes',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    remoteSort : true,
+                    sortInfo : { field : 'shiphead_notes', direction: 'ASC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/shiphead.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'shiphead_order_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'shiphead_number',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'shiphead_notes',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'shiphead_shipped',
+                                'type': 'boolean'
+                            },
+                            {
+                                'name': 'shiphead_shipdate',
+                                'type': 'date'
+                            },
+                            {
+                                'name': 'shiphead_sfstatus'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying shiphead{0} - {1} of {2}",
+                    emptyMsg : "No shiphead found"
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            allowBlank : false,
+                            editable : true,
+                            emptyText : "Select custinfo",
+                            forceSelection : true,
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            pageSize : 20,
+                            qtip : "Select Customer",
+                            selectOnFocus : true,
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            width : 300,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{cust_name}</b> </div>',
+                            queryParam : 'query[cust_name]',
+                            fieldLabel : 'cust_name',
+                            valueField : 'cust_id',
+                            displayField : 'cust_name',
+                            hiddenName : 'cust_id',
+                            name : 'cust_name',
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'shiphead_shipdate' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/custinfo.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'cust_id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"cust_id","type":"int"},"cust_name"]
+                                }
+                            }
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'shiphead_order_id_cohead_number',
+                        header : 'Order#',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'shiphead_custinfo_cust_name',
+                        header : 'Customer',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'shiphead_number',
+                        header : 'Shipment#',
+                        sortable : true,
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'notes',
+                        width : 200,
+                        dataIndex : 'shiphead_notes',
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'shiphead_shipped',
+                        header : 'shipped',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                        
+                        
+                        
+                          
+                            if (r.json.shiphead_shipdate.length) {
+                            
+                                if (r.json.shiphead_shipped) {
+                                    return "Confirmed";
+                                }
+                            
+                                 return 'Draft';
+                            }
+                             
+                            return 'VOID';
+                           
+                        
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'shiphead_shipdate',
+                        header : 'shipdate',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', v ? v.format('d/M/Y') : ''); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleStock.bjs b/Pman.Tab.XtupleStock.bjs
new file mode 100644 (file)
index 0000000..84f21b8
--- /dev/null
@@ -0,0 +1,489 @@
+{
+    "id": "roo-file-333",
+    "name": "Pman.Tab.XtupleStock",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "Pman.Tab.XtupleStock",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleStock.bjs",
+    "items": [
+        {
+            "listeners": {
+                "render": "function (_self)\n{\n _this.toppanel = _self;\n}"
+            },
+            "background": true,
+            "region": "center",
+            "title": "Locations /Stock ",
+            "xtype": "NestedLayoutPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "|xns": "Roo",
+                    "xtype": "BorderLayout",
+                    "*prop": "layout",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "LayoutRegion",
+                            "*prop": "center"
+                        },
+                        {
+                            "*prop": "east",
+                            "split": true,
+                            "title": "Stock",
+                            "width": 250,
+                            "xtype": "LayoutRegion",
+                            "|xns": "Roo"
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "center",
+                            "tableName": "location",
+                            "title": "location",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n    \n    Pman.Dialog.XtupleLocation.show( this.getDataSource().getAt(rowIndex).data, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                                        "cellclick": "function (_self, rowIndex, col, e)\n{\n   \n    var ix = this.colModel.getDataIndex(col);\n    var rec = _this.grid.ds.getAt(rowIndex);\n  \n  \n     \n     if (ix == 'location_restrict') {\n     \n        var nv = rec.data.location_restrict  ? 0 : 1;\n        new Pman.Request({\n            mask : 'Saving',\n            url : baseURL + '/Roo/Location',\n            params : {\n                location_id : rec.data.location_id,\n                location_restrict : nv\n            },\n            success : function() {\n                rec.set('location_restrict', nv);\n            }\n        });\n        return;\n        \n     \n     }\n  \n  \n  \n  \n     _this.itemgrid.viewtype = 1;\n    \n    \n     if ('location_qty_neg' == ix || 'location_netsuite_stock_neg' == ix ) {\n             _this.itemgrid.viewtype = -1;\n     }\n     if ('location_netsuite_stock' == ix || 'location_netsuite_stock_neg' == ix ) {\n             _this.itemgrid.viewtype *= 2;\n     }\n        \n        (function() { _this.itemgrid.footer.onClick('first'); }).defer(100);\n        \n        \n        \n        \n          \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "location_name",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "selectionchange": "function (_self)\n{\n   \n   // _this.toppanel.layout.getRegion('east').expand();\n}"
+                                            },
+                                            "*prop": "sm",
+                                            "xtype": "RowSelectionModel",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n  \n    o.params._as_of = _this.dateTo.getValue();\n    if (!o.params._as_of.length) {\n        return false;\n    }\n    o.params._with_stock_and_value = 1;\n    \n    o.params._viewType = _this.viewType.getValue();\n}",
+                                                "load": "function (_self, records, options)\n{\n    // build index.\n    \n    var dt = Date.parseDate(_this.dateTo.getValue(), 'Y-m-d');\n    var maxd = Date.parseDate('2012-11-01', 'Y-m-d');\n    \n    if (!records.length) {\n        return;\n    }\n    \n    var map = {};\n    \n    Roo.each(records, function(r) {\n        map[r.data.location_id] = r;\n        r.set('location_qty',undefined);\n        r.set('location_qty_neg', undefined);\n        r.set('location_value', undefined);\n    \n    });\n    var pqty = 0;\n    var nqty = 0;\n    var tval = 0.0;\n     var overlaydata  =  function (type, data) {\n            Roo.each(data, function(r) {\n                var rec= map[r.location_id];\n                \n                //switch(type) { \n                    //case 'netsuite':\n                        rec.set('location_netsuite_stock', r.location_netsuite_stock);\n                        rec.set('location_netsuite_stock_neg', r.location_netsuite_stock_neg);                        \n                   //     break;\n                 //   case 'dragon':\n                        rec.set('location_qty', r.location_qty);\n                        pqty += r.location_qty *1;                        \n                        rec.set('location_qty_neg', r.location_qty_neg);\n                        nqty += r.location_qty_neg  *1;\n                        rec.set('location_value', r.location_value);\n                        tval += r.location_value * 1.0;\n                  //      break;\n                    \n                    \n                //}\n            })\n                \n                \n \n     };\n    \n    var i = 0; \n    \n    var loadoverlay = function(type) {\n    \n         \n        new Pman.Request({\n            method : 'GET',\n            //mask : 'Loading ' + type + ' stock levels (takes around 30s)',\n            timeout: 60000,\n            url : baseURL + '/Roo/Location',\n            params  : {\n                _as_of : _this.dateTo.getValue(),\n                _with_stock_and_value : 'both',\n                location_id : records[i++].data.location_id \n            },\n            success : function( res ) {\n                \n                overlaydata(type, res.data);\n            \n                if (i >=  records.length) {\n                     _this.grid.footer.displayEl.update(String.format(\"Total: pos={0} neg={1} eq={2} val={3}\", \n                        Roo.util.Format.number(pqty,0), \n                        Roo.util.Format.number(nqty,0), \n                        Roo.util.Format.number(pqty+nqty,0), \n                        Roo.util.Format.number(tval,0)\n                        ));\n                    return;\n                }                \n               loadoverlay(type);\n                //if (type == 'dragon' && dt < maxd  ) {\n                //    loadoverlay('netsuite');\n               // } else {\n                //\n               // }\n                \n            \n            },\n            failure : function( ) {\n                Roo.MessageBox.alert('Error' , 'Loading data failed, try again');\n            }\n        });\n    \n    };\n    \n     loadoverlay('dragon');\n    \n    \n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'location_name', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'location_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'location_name',\n        'type': 'string'\n    },\n    {\n        'name': 'location_descrip',\n        'type': 'string'\n    },\n    {\n        'name': 'location_restrict',\n        'type': 'int'\n    },\n    {\n        'name': 'location_netable',\n        'type': 'int'\n    },\n    {\n        'name': 'location_whsezone_id',\n        'type': 'int'\n    },\n    {\n        'name': 'location_aisle',\n        'type': 'string'\n    },\n    {\n        'name': 'location_rack',\n        'type': 'string'\n    },\n    {\n        'name': 'location_bin',\n        'type': 'string'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": "Displaying location{0} - {1} of {2}",
+                                            "emptyMsg": "No location found",
+                                            "pageSize": 999,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n  Roo.MessageBox.progress (\"Syncing Balances\", \"Sending\");\n  \n  var offset = 0;\n  \n   function runSync() {\n       \n       new Pman.Request( {\n            url : baseURL+'/Roo/Locbal',\n            method : 'GET',\n            params : {\n                _sync : 1,\n                offset : offset\n            },\n            success : function(res) {\n               // Roo.log(res);\n                if (!res.data.total) {\n                    Roo.MessageBox.hide();\n                    return;\n                }\n                offset += res.data.limit;\n                Roo.MessageBox.updateProgress ( offset  / res.data.total, \"Done \" + offset + '/' + res.data.total);\n                runSync();\n            }\n             \n       });\n   }\n   runSync();\n}"
+                                                    },
+                                                    "hidden": true,
+                                                    "text": "Sync Stock Balances",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n   Pman.Dialog.Image.show(\n       {\n            _url : baseURL+'/Xtuple/Import/Products'\n        \n       },\n       function (data) {\n            var msg = [];\n           \n            if (data.updated) {\n                msg.push(\"Updated \" + data.updated + \" Products(s)\");\n            }            \n            if (data.inserted) {\n                msg.push(\"Added \" + data.inserted + \" Products(s)\");\n            }\n            if (data.skipped) {\n                msg.push(\"Skipped \" + data.skipped);\n            }\n            \n            if (!msg.length) {\n                msg.push(\"No data changed\");\n            }\n            Roo.MessageBox.alert(\"Notice\", msg.join(\"\\n\"));\n\n       }\n   );\n}"
+                                                    },
+                                                    "hidden": true,
+                                                    "text": "Upload new products and costs",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;\n    if (!l) {\n        Roo.MessageBox.alert(\"Error\", \"Select location\");\n        return;\n    }\n    \n    Pman.Dialog.XtupleTransfer.show({\n        id : 0,\n        _ns_autofill : 1,\n        invhist_transfer_to : l.data.location_id,\n        invhist_transfer_to_location_descrip : l.data.location_descrip,\n        \n        invhist_transfer_transdate : _this.dateTo.getValue(),\n        invhist_transfer_arrivaldate  : _this.dateTo.getValue()\n    \n        \n    }, function() { _this.grid.ds.load({}); }\n    );\n    \n    \n}"
+                                                                    },
+                                                                    "text": "Transfer to Fix +ve number",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;\n    if (!l) {\n        Roo.MessageBox.alert(\"Error\", \"Select location\");\n        return;\n    }\n    \n    Pman.Dialog.XtupleTransfer.show({\n        id : 0,\n        _ns_autofill : -1,\n        invhist_transfer_from : l.data.location_id,\n        invhist_transfer_from_location_descrip : l.data.location_descrip,\n        \n        invhist_transfer_transdate : _this.dateTo.getValue(),\n        invhist_transfer_arrivaldate  : _this.dateTo.getValue()\n    \n        \n    }, function() { _this.grid.ds.load({}); }\n    );\n    \n    \n}\n "
+                                                                    },
+                                                                    "text": "Transfer to Fix -ve number",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "toolbar",
+                                            "xtype": "Toolbar",
+                                            "|xns": "Roo",
+                                            "items": [
+                                                {
+                                                    "text": "As of:",
+                                                    "xtype": "TextItem",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.dateTo = _self;\n}",
+                                                        "select": "function (combo, date)\n{\n  _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "format": "d/M/Y",
+                                                    "useIso": 1,
+                                                    "width": 120,
+                                                    "xtype": "DateField",
+                                                    "|xns": "Roo.form"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "render": "function (_self)\n{\n    _this.viewType = _self;\n}",
+                                                        "select": "function (combo, record, index)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                                    },
+                                                    "allowBlank": false,
+                                                    "displayField": "fname",
+                                                    "editable": false,
+                                                    "fieldLabel": "Status",
+                                                    "hiddenName": "loctype",
+                                                    "listWidth": 200,
+                                                    "mode": "local",
+                                                    "name": "loctype_name",
+                                                    "triggerAction": "all",
+                                                    "value": "local",
+                                                    "valueField": "ftype",
+                                                    "width": 100,
+                                                    "xtype": "ComboBox",
+                                                    "|xns": "Roo.form",
+                                                    "items": [
+                                                        {
+                                                            "*prop": "store",
+                                                            "xtype": "SimpleStore",
+                                                            "|data": "[ ['local', \"Local\"],[ 'remote' , \"Remote\"],[ 'disabled', \"Disabled\"] ]\n",
+                                                            "|fields": "[  'ftype', 'fname']",
+                                                            "|xns": "Roo.data"
+                                                        }
+                                                    ]
+                                                },
+                                                {
+                                                    "|xns": "Roo.Toolbar",
+                                                    "xtype": "Fill"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "|click": "function()\n{\n    // work out last \n    Pman.Dialog.XtupleLocation.show( { }, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                                                        "render": "function (_self)\n{\n    _this.addItemBtn = _self;\n}"
+                                                    },
+                                                    "cls": "x-btn-text-icon",
+                                                    "text": "Add",
+                                                    "xtype": "Button",
+                                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                                    "|xns": "Roo.Toolbar"
+                                                },
+                                                {
+                                                    "text": "Download Reports",
+                                                    "xtype": "Button",
+                                                    "|xns": "Roo.Toolbar",
+                                                    "items": [
+                                                        {
+                                                            "|xns": "Roo.menu",
+                                                            "xtype": "Menu",
+                                                            "*prop": "menu",
+                                                            "items": [
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n\n    var ret= [];\n    var hr = [];\n    var cols = [];\n    Roo.each( _this.grid.colModel.config, function(h) {\n        hr.push(h.header);\n        cols.push(h.dataIndex);\n    });\n    ret.push(hr);\n    _this.grid.ds.each(function(rec) {\n        hr = [];\n        for(var i =0;i<cols.length;i++) {\n            hr.push(rec.get(cols[i]));\n        }\n        ret.push(hr);\n    });\n   \n       new Pman.Download({\n            url : baseURL + '/Core/JsonToExcel',\n            method : 'POST',\n            params : {\n                _json : Roo.encode(ret) \n            }\n        });\n     \n}"
+                                                                    },
+                                                                    "text": "Summary of Stock in all Locatoins",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n \n    \n\n       new Pman.Download({\n            url : baseURL + '/Roo/Invdetail',\n            method : 'GET',\n            timeout: 60000,\n            params : {\n                _summary_at_date : _this.dateTo.getValue(),\n                'csvCols[0]' : 'location_name',               \n                'csvCols[1]' :  'item_number',\n                'csvCols[2]' :  'item_descrip1',                \n                'csvCols[3]' : 'stock_qty',\n                'csvCols[4]' : 'stdcost_value',\n                'csvCols[5]' : 'fifo_value',                                \n                'csvTitles[0]' :'Location',                \n                'csvTitles[1]' :  'Item Number',\n                'csvTitles[2]' :  'Item Description',                \n                'csvTitles[3]' : 'Qty', \n                'csvTitles[4]' : 'Std Cost Valued',\n                'csvTitles[5]' : 'FIFO Value',                                \n                'sort' : 'location_name,item_number',\n                'dir' : 'ASC',  \n                _with_empty_stock : 1,      \n                limit : 99999\n                           \n            }\n        });\n        Roo.MessageBox.alert(\"Notice\", \"Report will download shortly (around 30s)\");\n     \n}\n"
+                                                                    },
+                                                                    "text": "All Stock in all locations (active)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n    var p = {\n            'csvCols[0]' : 'itemsite_item_id_item_number',\n            'csvCols[1]' : 'item_brand_name',\n            'csvCols[2]' : 'itemsite_item_id_item_descrip1',\n            'csvCols[3]' : 'itemsite_qty_before',\n            'csvCols[4]' : 'itemsite_sold_atdate'  ,\n            'csvCols[5]' : 'itemsite_qty',          \n            'csvCols[6]' : 'itemsite_sold_after',   \n            'csvCols[7]' : 'last_transaction',\n            'csvCols[8]' : 'customer_price_each',                           \n            'csvCols[9]' : 'customer_total_value',                                    \n            'csvCols[10]' : 'itemsite_value',\n            'csvCols[11]' : 'item_last_purchase_price',\n            \n            'csvTitles[0]' : 'SKU',\n            'csvTitles[1]' : 'Brand'  ,\n            'csvTitles[2]' : 'Description',            \n            'csvTitles[3]' : 'Qty Before'  , \n            'csvTitles[4]' : 'Total Sold'  , \n            'csvTitles[5]' : 'Qty'  , \n            'csvTitles[6]' : 'Sold After'  , \n            'csvTitles[7]' : 'Last Transaction'  ,\n            'csvTitles[8]' : 'Customer unit price'  ,\n            'csvTitles[9]' : 'Customer Total Value'  ,\n            'csvTitles[10]' : 'FIFO value'  ,\n            'csvTitles[11]' : 'Last Purchase Price'  ,       \n\n\n            \n            \n            'sort' : 'itemsite_item_id_item_number',\n            'dir' : 'ASC',        \n            limit : 9999\n    };\n     var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;\n    if (!l) {\n        Roo.MessageBox.alert(\"Error\", \"Select location\");\n        return;\n    }\n    p.location_id = l.data.location_id;\n    p._as_of = _this.dateTo.getValue();\n    p._with_stock_and_value = 1;\n    p._viewtype = 1;\n    p._with_brand = 1;\n    p._with_last_purchase_price = 1;\n    p._with_qty_detail = 1;\n    \n        new Pman.Download({\n            url : baseURL + '/Roo/itemsite',\n            timeout : 60000,\n            \n            method : 'GET',\n            params : p\n\n        \n        });\n        Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                    },
+                                                                    "text": "Stock at Selected Location (inc. empty)",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                },
+                                                                {
+                                                                    "|xns": "Roo.menu",
+                                                                    "xtype": "Separator"
+                                                                },
+                                                                {
+                                                                    "listeners": {
+                                                                        "click": "function (_self, e)\n{\n     \n     var p = {\n        _group : 'itemsite',\n        _name : 'stockatlocation',\n        csvCols : '*',\n        limit : 99999\n     };\n     var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;\n    if (!l) {\n        Roo.MessageBox.alert(\"Error\", \"Select location\");\n        return;\n    }\n    p['location_id:number'] = l.data.location_id;\n    p['as_of:text'] = _this.dateTo.getValue();\n    \n        new Pman.Download({\n            url : baseURL + '/Roo/Metasql',\n            newWindow : 1,\n            timeout : 60000,\n            \n            method : 'GET',\n            params : p\n\n        \n        });\n        Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                                    },
+                                                                    "text": "Stock at Selected Location (inc. empty) with Adjustment details",
+                                                                    "xtype": "Item",
+                                                                    "|xns": "Roo.menu"
+                                                                }
+                                                            ]
+                                                        }
+                                                    ]
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "location_restrict",
+                                            "header": "Active",
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '' :  '-checked' ;\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "location_name",
+                                            "header": "Name",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "location_descrip",
+                                            "header": "Description",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "location_cust_id_cust_name",
+                                            "header": "Customer",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n\n    if (!r.data.location_cust_id_char_internalcompany.length) {\n       return String.format('{0}', v); \n    }\n   return String.format('<span style=\"color:red\">[Internal Company : {0}] {1} </span>', \n        r.data.location_cust_id_char_internalcompany,        v); \n    \n}\n",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_qty",
+                                            "header": "Qty",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { return  typeof(v) == 'undefined' ? '...' : String.format('{0} ', (v*1).toFixed(0) ); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_qty_neg",
+                                            "header": "Missing TX",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    if ( typeof(v) == 'undefined') {\n        return '';\n    }\n    if (v == 0) {\n        return '';\n    }\n    \n    return String.format('<span style=\"color:red;\">{0}</span>', (v*1).toFixed(0) ); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_qty",
+                                            "header": "Est. Net Qty",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) { \n    \n    return typeof(v) == 'undefined' ? '...' : \n        String.format('{0}', ((v*1) + (r.data.location_qty_neg*1)).toFixed(0) ); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_netsuite_stock",
+                                            "header": "NS Qty",
+                                            "hidden": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {\n    var f= '{0}';\n    if ((r.data.location_qty) *1 != (v*1)) {\n        f = '<span style=\"color:red;font-weight:bold\">{0}</span>';\n    }\n     return typeof(v) == 'undefined' ? '...' : String.format(f, (v*1).toFixed(0) );\n     \n  }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_netsuite_stock_neg",
+                                            "header": "NS -ve Qty",
+                                            "hidden": true,
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {     \n    var f= '{0}';\n    if ((r.data.location_qty_neg) *1 != (v*1)) {\n        f = '<span style=\"color:red;font-weight:bold\">{0}</span>';\n    }\n     return typeof(v) == 'undefined' ? '...' : String.format(f, (v*1).toFixed(0) ); \n }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "location_value",
+                                            "header": "Value",
+                                            "width": 200,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return typeof(v) == 'undefined' ? '...' :  Roo.util.Format.usMoney(  v); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "|activate": "function() {\n    _this.itempanel = this;\n    if (_this.itemgrid) {\n       // _this.itemgrid.footer.onClick('first');\n    }\n}"
+                            },
+                            "background": true,
+                            "fitContainer": true,
+                            "fitToframe": true,
+                            "region": "east",
+                            "tableName": "itemloc",
+                            "title": "itemloc",
+                            "xtype": "GridPanel",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "|render": "function() \n{\n    _this.itemgrid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.itempanel.active) {\n      // this.footer.onClick('first');\n    }\n}",
+                                        "|rowdblclick": "function (_self, rowIndex, e)\n{  \n    var rec =this.getDataSource().getAt(rowIndex);\n\n    var loc = _this.grid.selModel.getSelected();\n  \n    var dt = _this.dateTo.getValue();\n    \n  Pman.Dialog.XtupleInvHistory.show({\n        itemsite_item_id_item_number   : rec.data.itemsite_item_id_item_number,\n  \n        location_name : loc.data.location_name,\n        location_descrip : loc.data.location_descrip,\n        \n        invhist_transdate :  typeof(dt) == 'string' ? dt : dt.format('Y-m-d')\n    }); \n    \n   \n\n}\n",
+                                        "cellclick": "function (_self, row, col, e)\n{\n\n   if ('netsuite_qty' == this.colModel.getDataIndex(col)) {\n        var d = this.ds.getAt(row); \n        var loc = _this.grid.selModel.getSelected();\n \n       new Pman.Download({\n            url: baseURL + '/Xtuple/NetsuiteFix/StockCheck',\n            params : {\n                item_id : d.data.itemsite_item_id,\n                location_id : loc.data.location_id\n            }\n           \n        \n        });\n    }\n}"
+                                    },
+                                    "*prop": "grid",
+                                    "autoExpandColumn": "itemsite_item_id_item_number",
+                                    "loadMask": true,
+                                    "xtype": "Grid",
+                                    "|xns": "Roo.grid",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "beforeload": "function (_self, o)\n{\n    var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;\n    if (!l) {\n        return false;\n    }\n    o.params.location_id = l.data.location_id;\n    o.params._as_of = _this.dateTo.getValue();\n    o.params._with_stock_and_value = 1;\n    o.params._viewtype =  _this.itemgrid.viewtype;\n}"
+                                            },
+                                            "*prop": "dataSource",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ field : 'itemsite_item_id_item_number', direction: 'ASC' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "timeout": 120000,
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "|xns": "Roo.data",
+                                                    "xtype": "JsonReader",
+                                                    "totalProperty": "total",
+                                                    "root": "data",
+                                                    "*prop": "reader",
+                                                    "id": "id",
+                                                    "|fields": "[\n    {\n        'name': 'itemloc_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_location_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_qty',\n        'type': 'float'\n    },\n    {\n        'name': 'itemloc_expiration',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'itemloc_consolflag',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_ls_id',\n        'type': 'int'\n    },\n    {\n        'name': 'itemloc_warrpurc',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    }\n]"
+                                                }
+                                            ]
+                                        },
+                                        {
+                                            "*prop": "footer",
+                                            "displayInfo": true,
+                                            "displayMsg": "{0} - {1} of {2}",
+                                            "emptyMsg": "No itemloc found",
+                                            "pageSize": 25,
+                                            "xtype": "PagingToolbar",
+                                            "|xns": "Roo"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "dataIndex": "itemsite_item_id_item_number",
+                                            "header": "Item",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "itemsite_qty",
+                                            "header": "Qty",
+                                            "width": 55,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return String.format('{0}', (v*1).toFixed(0)); }",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "netsuite_qty",
+                                            "header": "NS Qty",
+                                            "hidden": true,
+                                            "width": 50,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v,x,r) {     \n    var f= '<span style=\"color:blue;text-decoration:underline;cursor:pointer;\">{0}</span>';\n    if ((r.data.itemsite_qty) *1 != (v*1)) {\n        f = '<span style=\"color:red;font-weight:bold;text-decoration:underline;cursor:pointer;\">{0}</span>';\n    }\n    return String.format(f, (v*1).toFixed(0) ); \n}",
+                                            "|xns": "Roo.grid"
+                                        },
+                                        {
+                                            "*prop": "colModel[]",
+                                            "align": "right",
+                                            "dataIndex": "itemsite_value",
+                                            "header": "Value",
+                                            "width": 75,
+                                            "xtype": "ColumnModel",
+                                            "|renderer": "function(v) { return Roo.util.Format.usMoney(v); }",
+                                            "|xns": "Roo.grid"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "001"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleStock.js b/Pman.Tab.XtupleStock.js
new file mode 100644 (file)
index 0000000..97eb6f4
--- /dev/null
@@ -0,0 +1,1082 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleStock = new Roo.XComponent({
+    part     :  ["Xtuple","Stock"],
+    order    : '001-Pman.Tab.XtupleStock',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "Pman.Tab.XtupleStock",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'NestedLayoutPanel',
+            xns: Roo,
+            listeners : {
+                render : function (_self)
+                {
+                 _this.toppanel = _self;
+                }
+            },
+            background : true,
+            region : 'center',
+            title : "Locations /Stock ",
+            layout : {
+                xtype: 'BorderLayout',
+                xns: Roo,
+                items : [
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.panel = this;
+                                if (_this.grid) {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'center',
+                        tableName : 'location',
+                        title : "location",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.grid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.panel.active) {
+                                       this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {
+                                    
+                                    Pman.Dialog.XtupleLocation.show( this.getDataSource().getAt(rowIndex).data, function() {
+                                        _this.grid.footer.onClick('first');
+                                    }); 
+                                },
+                                cellclick : function (_self, rowIndex, col, e)
+                                {
+                                   
+                                    var ix = this.colModel.getDataIndex(col);
+                                    var rec = _this.grid.ds.getAt(rowIndex);
+                                  
+                                  
+                                     
+                                     if (ix == 'location_restrict') {
+                                     
+                                        var nv = rec.data.location_restrict  ? 0 : 1;
+                                        new Pman.Request({
+                                            mask : 'Saving',
+                                            url : baseURL + '/Roo/Location',
+                                            params : {
+                                                location_id : rec.data.location_id,
+                                                location_restrict : nv
+                                            },
+                                            success : function() {
+                                                rec.set('location_restrict', nv);
+                                            }
+                                        });
+                                        return;
+                                        
+                                     
+                                     }
+                                  
+                                  
+                                  
+                                  
+                                     _this.itemgrid.viewtype = 1;
+                                    
+                                    
+                                     if ('location_qty_neg' == ix || 'location_netsuite_stock_neg' == ix ) {
+                                             _this.itemgrid.viewtype = -1;
+                                     }
+                                     if ('location_netsuite_stock' == ix || 'location_netsuite_stock_neg' == ix ) {
+                                             _this.itemgrid.viewtype *= 2;
+                                     }
+                                        
+                                        (function() { _this.itemgrid.footer.onClick('first'); }).defer(100);
+                                        
+                                        
+                                        
+                                        
+                                          
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                        
+                                }
+                            },
+                            autoExpandColumn : 'location_name',
+                            loadMask : true,
+                            sm : {
+                                xtype: 'RowSelectionModel',
+                                xns: Roo.grid,
+                                listeners : {
+                                    selectionchange : function (_self)
+                                    {
+                                       
+                                       // _this.toppanel.layout.getRegion('east').expand();
+                                    }
+                                }
+                            },
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                      
+                                        o.params._as_of = _this.dateTo.getValue();
+                                        if (!o.params._as_of.length) {
+                                            return false;
+                                        }
+                                        o.params._with_stock_and_value = 1;
+                                        
+                                        o.params._viewType = _this.viewType.getValue();
+                                    },
+                                    load : function (_self, records, options)
+                                    {
+                                        // build index.
+                                        
+                                        var dt = Date.parseDate(_this.dateTo.getValue(), 'Y-m-d');
+                                        var maxd = Date.parseDate('2012-11-01', 'Y-m-d');
+                                        
+                                        if (!records.length) {
+                                            return;
+                                        }
+                                        
+                                        var map = {};
+                                        
+                                        Roo.each(records, function(r) {
+                                            map[r.data.location_id] = r;
+                                            r.set('location_qty',undefined);
+                                            r.set('location_qty_neg', undefined);
+                                            r.set('location_value', undefined);
+                                        
+                                        });
+                                        var pqty = 0;
+                                        var nqty = 0;
+                                        var tval = 0.0;
+                                         var overlaydata  =  function (type, data) {
+                                                Roo.each(data, function(r) {
+                                                    var rec= map[r.location_id];
+                                                    
+                                                    //switch(type) { 
+                                                        //case 'netsuite':
+                                                            rec.set('location_netsuite_stock', r.location_netsuite_stock);
+                                                            rec.set('location_netsuite_stock_neg', r.location_netsuite_stock_neg);                        
+                                                       //     break;
+                                                     //   case 'dragon':
+                                                            rec.set('location_qty', r.location_qty);
+                                                            pqty += r.location_qty *1;                        
+                                                            rec.set('location_qty_neg', r.location_qty_neg);
+                                                            nqty += r.location_qty_neg  *1;
+                                                            rec.set('location_value', r.location_value);
+                                                            tval += r.location_value * 1.0;
+                                                      //      break;
+                                                        
+                                                        
+                                                    //}
+                                                })
+                                                    
+                                                    
+                                     
+                                         };
+                                        
+                                        var i = 0; 
+                                        
+                                        var loadoverlay = function(type) {
+                                        
+                                             
+                                            new Pman.Request({
+                                                method : 'GET',
+                                                //mask : 'Loading ' + type + ' stock levels (takes around 30s)',
+                                                timeout: 60000,
+                                                url : baseURL + '/Roo/Location',
+                                                params  : {
+                                                    _as_of : _this.dateTo.getValue(),
+                                                    _with_stock_and_value : 'both',
+                                                    location_id : records[i++].data.location_id 
+                                                },
+                                                success : function( res ) {
+                                                    
+                                                    overlaydata(type, res.data);
+                                                
+                                                    if (i >=  records.length) {
+                                                         _this.grid.footer.displayEl.update(String.format("Total: pos={0} neg={1} eq={2} val={3}", 
+                                                            Roo.util.Format.number(pqty,0), 
+                                                            Roo.util.Format.number(nqty,0), 
+                                                            Roo.util.Format.number(pqty+nqty,0), 
+                                                            Roo.util.Format.number(tval,0)
+                                                            ));
+                                                        return;
+                                                    }                
+                                                   loadoverlay(type);
+                                                    //if (type == 'dragon' && dt < maxd  ) {
+                                                    //    loadoverlay('netsuite');
+                                                   // } else {
+                                                    //
+                                                   // }
+                                                    
+                                                
+                                                },
+                                                failure : function( ) {
+                                                    Roo.MessageBox.alert('Error' , 'Loading data failed, try again');
+                                                }
+                                            });
+                                        
+                                        };
+                                        
+                                         loadoverlay('dragon');
+                                        
+                                        
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'location_name', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/location.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'location_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'location_warehous_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'location_name',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'location_descrip',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'location_restrict',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'location_netable',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'location_whsezone_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'location_aisle',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'location_rack',
+                                            'type': 'string'
+                                        },
+                                        {
+                                            'name': 'location_bin',
+                                            'type': 'string'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : "Displaying location{0} - {1} of {2}",
+                                emptyMsg : "No location found",
+                                pageSize : 999,
+                                items : [
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                              Roo.MessageBox.progress ("Syncing Balances", "Sending");
+                                              
+                                              var offset = 0;
+                                              
+                                               function runSync() {
+                                                   
+                                                   new Pman.Request( {
+                                                        url : baseURL+'/Roo/Locbal',
+                                                        method : 'GET',
+                                                        params : {
+                                                            _sync : 1,
+                                                            offset : offset
+                                                        },
+                                                        success : function(res) {
+                                                           // Roo.log(res);
+                                                            if (!res.data.total) {
+                                                                Roo.MessageBox.hide();
+                                                                return;
+                                                            }
+                                                            offset += res.data.limit;
+                                                            Roo.MessageBox.updateProgress ( offset  / res.data.total, "Done " + offset + '/' + res.data.total);
+                                                            runSync();
+                                                        }
+                                                         
+                                                   });
+                                               }
+                                               runSync();
+                                            }
+                                        },
+                                        hidden : true,
+                                        text : "Sync Stock Balances"
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                               Pman.Dialog.Image.show(
+                                                   {
+                                                        _url : baseURL+'/Xtuple/Import/Products'
+                                                    
+                                                   },
+                                                   function (data) {
+                                                        var msg = [];
+                                                       
+                                                        if (data.updated) {
+                                                            msg.push("Updated " + data.updated + " Products(s)");
+                                                        }            
+                                                        if (data.inserted) {
+                                                            msg.push("Added " + data.inserted + " Products(s)");
+                                                        }
+                                                        if (data.skipped) {
+                                                            msg.push("Skipped " + data.skipped);
+                                                        }
+                                                        
+                                                        if (!msg.length) {
+                                                            msg.push("No data changed");
+                                                        }
+                                                        Roo.MessageBox.alert("Notice", msg.join("\n"));
+                                            
+                                                   }
+                                               );
+                                            }
+                                        },
+                                        hidden : true,
+                                        text : "Upload new products and costs",
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;
+                                                            if (!l) {
+                                                                Roo.MessageBox.alert("Error", "Select location");
+                                                                return;
+                                                            }
+                                                            
+                                                            Pman.Dialog.XtupleTransfer.show({
+                                                                id : 0,
+                                                                _ns_autofill : 1,
+                                                                invhist_transfer_to : l.data.location_id,
+                                                                invhist_transfer_to_location_descrip : l.data.location_descrip,
+                                                                
+                                                                invhist_transfer_transdate : _this.dateTo.getValue(),
+                                                                invhist_transfer_arrivaldate  : _this.dateTo.getValue()
+                                                            
+                                                                
+                                                            }, function() { _this.grid.ds.load({}); }
+                                                            );
+                                                            
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Transfer to Fix +ve number"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;
+                                                            if (!l) {
+                                                                Roo.MessageBox.alert("Error", "Select location");
+                                                                return;
+                                                            }
+                                                            
+                                                            Pman.Dialog.XtupleTransfer.show({
+                                                                id : 0,
+                                                                _ns_autofill : -1,
+                                                                invhist_transfer_from : l.data.location_id,
+                                                                invhist_transfer_from_location_descrip : l.data.location_descrip,
+                                                                
+                                                                invhist_transfer_transdate : _this.dateTo.getValue(),
+                                                                invhist_transfer_arrivaldate  : _this.dateTo.getValue()
+                                                            
+                                                                
+                                                            }, function() { _this.grid.ds.load({}); }
+                                                            );
+                                                            
+                                                            
+                                                        }
+                                                    },
+                                                    text : "Transfer to Fix -ve number"
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            toolbar : {
+                                xtype: 'Toolbar',
+                                xns: Roo,
+                                items : [
+                                    {
+                                        xtype: 'TextItem',
+                                        xns: Roo.Toolbar,
+                                        text : "As of:"
+                                    },
+                                    {
+                                        xtype: 'DateField',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.dateTo = _self;
+                                            },
+                                            select : function (combo, date)
+                                            {
+                                              _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        format : 'd/M/Y',
+                                        useIso : 1,
+                                        width : 120
+                                    },
+                                    {
+                                        xtype: 'ComboBox',
+                                        xns: Roo.form,
+                                        listeners : {
+                                            render : function (_self)
+                                            {
+                                                _this.viewType = _self;
+                                            },
+                                            select : function (combo, record, index)
+                                            {
+                                                _this.grid.footer.onClick('first');
+                                            }
+                                        },
+                                        allowBlank : false,
+                                        displayField : 'fname',
+                                        editable : false,
+                                        fieldLabel : 'Status',
+                                        hiddenName : 'loctype',
+                                        listWidth : 200,
+                                        mode : 'local',
+                                        name : 'loctype_name',
+                                        triggerAction : 'all',
+                                        value : "local",
+                                        valueField : 'ftype',
+                                        width : 100,
+                                        store : {
+                                            xtype: 'SimpleStore',
+                                            xns: Roo.data,
+                                            data : [ ['local', "Local"],[ 'remote' , "Remote"],[ 'disabled', "Disabled"] ],
+                                            fields : [  'ftype', 'fname']
+                                        }
+                                    },
+                                    {
+                                        xtype: 'Fill',
+                                        xns: Roo.Toolbar
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        listeners : {
+                                            click : function()
+                                            {
+                                                // work out last 
+                                                Pman.Dialog.XtupleLocation.show( { }, function() {
+                                                    _this.grid.footer.onClick('first');
+                                                }); 
+                                            },
+                                            render : function (_self)
+                                            {
+                                                _this.addItemBtn = _self;
+                                            }
+                                        },
+                                        cls : 'x-btn-text-icon',
+                                        text : "Add",
+                                        icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                                    },
+                                    {
+                                        xtype: 'Button',
+                                        xns: Roo.Toolbar,
+                                        text : "Download Reports",
+                                        menu : {
+                                            xtype: 'Menu',
+                                            xns: Roo.menu,
+                                            items : [
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                        
+                                                            var ret= [];
+                                                            var hr = [];
+                                                            var cols = [];
+                                                            Roo.each( _this.grid.colModel.config, function(h) {
+                                                                hr.push(h.header);
+                                                                cols.push(h.dataIndex);
+                                                            });
+                                                            ret.push(hr);
+                                                            _this.grid.ds.each(function(rec) {
+                                                                hr = [];
+                                                                for(var i =0;i<cols.length;i++) {
+                                                                    hr.push(rec.get(cols[i]));
+                                                                }
+                                                                ret.push(hr);
+                                                            });
+                                                           
+                                                               new Pman.Download({
+                                                                    url : baseURL + '/Core/JsonToExcel',
+                                                                    method : 'POST',
+                                                                    params : {
+                                                                        _json : Roo.encode(ret) 
+                                                                    }
+                                                                });
+                                                             
+                                                        }
+                                                    },
+                                                    text : "Summary of Stock in all Locatoins"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                         
+                                                            
+                                                        
+                                                               new Pman.Download({
+                                                                    url : baseURL + '/Roo/Invdetail',
+                                                                    method : 'GET',
+                                                                    timeout: 60000,
+                                                                    params : {
+                                                                        _summary_at_date : _this.dateTo.getValue(),
+                                                                        'csvCols[0]' : 'location_name',               
+                                                                        'csvCols[1]' :  'item_number',
+                                                                        'csvCols[2]' :  'item_descrip1',                
+                                                                        'csvCols[3]' : 'stock_qty',
+                                                                        'csvCols[4]' : 'stdcost_value',
+                                                                        'csvCols[5]' : 'fifo_value',                                
+                                                                        'csvTitles[0]' :'Location',                
+                                                                        'csvTitles[1]' :  'Item Number',
+                                                                        'csvTitles[2]' :  'Item Description',                
+                                                                        'csvTitles[3]' : 'Qty', 
+                                                                        'csvTitles[4]' : 'Std Cost Valued',
+                                                                        'csvTitles[5]' : 'FIFO Value',                                
+                                                                        'sort' : 'location_name,item_number',
+                                                                        'dir' : 'ASC',  
+                                                                        _with_empty_stock : 1,      
+                                                                        limit : 99999
+                                                                                   
+                                                                    }
+                                                                });
+                                                                Roo.MessageBox.alert("Notice", "Report will download shortly (around 30s)");
+                                                             
+                                                        }
+                                                    },
+                                                    text : "All Stock in all locations (active)"
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                            var p = {
+                                                                    'csvCols[0]' : 'itemsite_item_id_item_number',
+                                                                    'csvCols[1]' : 'item_brand_name',
+                                                                    'csvCols[2]' : 'itemsite_item_id_item_descrip1',
+                                                                    'csvCols[3]' : 'itemsite_qty_before',
+                                                                    'csvCols[4]' : 'itemsite_sold_atdate'  ,
+                                                                    'csvCols[5]' : 'itemsite_qty',          
+                                                                    'csvCols[6]' : 'itemsite_sold_after',   
+                                                                    'csvCols[7]' : 'last_transaction',
+                                                                    'csvCols[8]' : 'customer_price_each',                           
+                                                                    'csvCols[9]' : 'customer_total_value',                                    
+                                                                    'csvCols[10]' : 'itemsite_value',
+                                                                    'csvCols[11]' : 'item_last_purchase_price',
+                                                                    
+                                                                    'csvTitles[0]' : 'SKU',
+                                                                    'csvTitles[1]' : 'Brand'  ,
+                                                                    'csvTitles[2]' : 'Description',            
+                                                                    'csvTitles[3]' : 'Qty Before'  , 
+                                                                    'csvTitles[4]' : 'Total Sold'  , 
+                                                                    'csvTitles[5]' : 'Qty'  , 
+                                                                    'csvTitles[6]' : 'Sold After'  , 
+                                                                    'csvTitles[7]' : 'Last Transaction'  ,
+                                                                    'csvTitles[8]' : 'Customer unit price'  ,
+                                                                    'csvTitles[9]' : 'Customer Total Value'  ,
+                                                                    'csvTitles[10]' : 'FIFO value'  ,
+                                                                    'csvTitles[11]' : 'Last Purchase Price'  ,       
+                                                        
+                                                        
+                                                                    
+                                                                    
+                                                                    'sort' : 'itemsite_item_id_item_number',
+                                                                    'dir' : 'ASC',        
+                                                                    limit : 9999
+                                                            };
+                                                             var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;
+                                                            if (!l) {
+                                                                Roo.MessageBox.alert("Error", "Select location");
+                                                                return;
+                                                            }
+                                                            p.location_id = l.data.location_id;
+                                                            p._as_of = _this.dateTo.getValue();
+                                                            p._with_stock_and_value = 1;
+                                                            p._viewtype = 1;
+                                                            p._with_brand = 1;
+                                                            p._with_last_purchase_price = 1;
+                                                            p._with_qty_detail = 1;
+                                                            
+                                                                new Pman.Download({
+                                                                    url : baseURL + '/Roo/itemsite',
+                                                                    timeout : 60000,
+                                                                    
+                                                                    method : 'GET',
+                                                                    params : p
+                                                        
+                                                                
+                                                                });
+                                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                        }
+                                                    },
+                                                    text : "Stock at Selected Location (inc. empty)"
+                                                },
+                                                {
+                                                    xtype: 'Separator',
+                                                    xns: Roo.menu
+                                                },
+                                                {
+                                                    xtype: 'Item',
+                                                    xns: Roo.menu,
+                                                    listeners : {
+                                                        click : function (_self, e)
+                                                        {
+                                                             
+                                                             var p = {
+                                                                _group : 'itemsite',
+                                                                _name : 'stockatlocation',
+                                                                csvCols : '*',
+                                                                limit : 99999
+                                                             };
+                                                             var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;
+                                                            if (!l) {
+                                                                Roo.MessageBox.alert("Error", "Select location");
+                                                                return;
+                                                            }
+                                                            p['location_id:number'] = l.data.location_id;
+                                                            p['as_of:text'] = _this.dateTo.getValue();
+                                                            
+                                                                new Pman.Download({
+                                                                    url : baseURL + '/Roo/Metasql',
+                                                                    newWindow : 1,
+                                                                    timeout : 60000,
+                                                                    
+                                                                    method : 'GET',
+                                                                    params : p
+                                                        
+                                                                
+                                                                });
+                                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                                        }
+                                                    },
+                                                    text : "Stock at Selected Location (inc. empty) with Adjustment details"
+                                                }
+                                            ]
+                                        }
+                                    }
+                                ]
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'location_restrict',
+                                    header : 'Active',
+                                    width : 50,
+                                    renderer : function(v) {  
+                                        var state = v * 1 > 0 ?  '' :  '-checked' ;
+                                    
+                                        return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                                    
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'location_name',
+                                    header : 'Name',
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'location_descrip',
+                                    header : 'Description',
+                                    width : 200,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'location_cust_id_cust_name',
+                                    header : 'Customer',
+                                    width : 200,
+                                    renderer : function(v,x,r) { 
+                                    
+                                        if (!r.data.location_cust_id_char_internalcompany.length) {
+                                           return String.format('{0}', v); 
+                                        }
+                                       return String.format('<span style="color:red">[Internal Company : {0}] {1} </span>', 
+                                            r.data.location_cust_id_char_internalcompany,        v); 
+                                        
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_qty',
+                                    header : 'Qty',
+                                    width : 75,
+                                    renderer : function(v,x,r) { return  typeof(v) == 'undefined' ? '...' : String.format('{0} ', (v*1).toFixed(0) ); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_qty_neg',
+                                    header : 'Missing TX',
+                                    width : 75,
+                                    renderer : function(v,x,r) { 
+                                        if ( typeof(v) == 'undefined') {
+                                            return '';
+                                        }
+                                        if (v == 0) {
+                                            return '';
+                                        }
+                                        
+                                        return String.format('<span style="color:red;">{0}</span>', (v*1).toFixed(0) ); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_qty',
+                                    header : 'Est. Net Qty',
+                                    width : 75,
+                                    renderer : function(v,x,r) { 
+                                        
+                                        return typeof(v) == 'undefined' ? '...' : 
+                                            String.format('{0}', ((v*1) + (r.data.location_qty_neg*1)).toFixed(0) ); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_netsuite_stock',
+                                    header : 'NS Qty',
+                                    hidden : true,
+                                    width : 75,
+                                    renderer : function(v,x,r) {
+                                        var f= '{0}';
+                                        if ((r.data.location_qty) *1 != (v*1)) {
+                                            f = '<span style="color:red;font-weight:bold">{0}</span>';
+                                        }
+                                         return typeof(v) == 'undefined' ? '...' : String.format(f, (v*1).toFixed(0) );
+                                         
+                                      }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_netsuite_stock_neg',
+                                    header : 'NS -ve Qty',
+                                    hidden : true,
+                                    width : 75,
+                                    renderer : function(v,x,r) {     
+                                        var f= '{0}';
+                                        if ((r.data.location_qty_neg) *1 != (v*1)) {
+                                            f = '<span style="color:red;font-weight:bold">{0}</span>';
+                                        }
+                                         return typeof(v) == 'undefined' ? '...' : String.format(f, (v*1).toFixed(0) ); 
+                                     }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'location_value',
+                                    header : 'Value',
+                                    width : 200,
+                                    renderer : function(v) { return typeof(v) == 'undefined' ? '...' :  Roo.util.Format.usMoney(  v); }
+                                }
+                            ]
+                        }
+                    },
+                    {
+                        xtype: 'GridPanel',
+                        xns: Roo,
+                        listeners : {
+                            activate : function() {
+                                _this.itempanel = this;
+                                if (_this.itemgrid) {
+                                   // _this.itemgrid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        background : true,
+                        fitContainer : true,
+                        fitToframe : true,
+                        region : 'east',
+                        tableName : 'itemloc',
+                        title : "itemloc",
+                        grid : {
+                            xtype: 'Grid',
+                            xns: Roo.grid,
+                            listeners : {
+                                render : function() 
+                                {
+                                    _this.itemgrid = this; 
+                                    //_this.dialog = Pman.Dialog.FILL_IN
+                                    if (_this.itempanel.active) {
+                                      // this.footer.onClick('first');
+                                    }
+                                },
+                                rowdblclick : function (_self, rowIndex, e)
+                                {  
+                                    var rec =this.getDataSource().getAt(rowIndex);
+                                
+                                    var loc = _this.grid.selModel.getSelected();
+                                  
+                                    var dt = _this.dateTo.getValue();
+                                    
+                                  Pman.Dialog.XtupleInvHistory.show({
+                                        itemsite_item_id_item_number   : rec.data.itemsite_item_id_item_number,
+                                  
+                                        location_name : loc.data.location_name,
+                                        location_descrip : loc.data.location_descrip,
+                                        
+                                        invhist_transdate :  typeof(dt) == 'string' ? dt : dt.format('Y-m-d')
+                                    }); 
+                                    
+                                   
+                                
+                                },
+                                cellclick : function (_self, row, col, e)
+                                {
+                                
+                                   if ('netsuite_qty' == this.colModel.getDataIndex(col)) {
+                                        var d = this.ds.getAt(row); 
+                                        var loc = _this.grid.selModel.getSelected();
+                                 
+                                       new Pman.Download({
+                                            url: baseURL + '/Xtuple/NetsuiteFix/StockCheck',
+                                            params : {
+                                                item_id : d.data.itemsite_item_id,
+                                                location_id : loc.data.location_id
+                                            }
+                                           
+                                        
+                                        });
+                                    }
+                                }
+                            },
+                            autoExpandColumn : 'itemsite_item_id_item_number',
+                            loadMask : true,
+                            dataSource : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o)
+                                    {
+                                        var l = _this.grid.selModel ? _this.grid.selModel.getSelected() : false;
+                                        if (!l) {
+                                            return false;
+                                        }
+                                        o.params.location_id = l.data.location_id;
+                                        o.params._as_of = _this.dateTo.getValue();
+                                        o.params._with_stock_and_value = 1;
+                                        o.params._viewtype =  _this.itemgrid.viewtype;
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { field : 'itemsite_item_id_item_number', direction: 'ASC' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    timeout : 120000,
+                                    url : baseURL + '/Roo/itemsite.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    totalProperty : 'total',
+                                    root : 'data',
+                                    id : 'id',
+                                    fields : [
+                                        {
+                                            'name': 'itemloc_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_itemsite_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_location_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_qty',
+                                            'type': 'float'
+                                        },
+                                        {
+                                            'name': 'itemloc_expiration',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        },
+                                        {
+                                            'name': 'itemloc_consolflag',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_ls_id',
+                                            'type': 'int'
+                                        },
+                                        {
+                                            'name': 'itemloc_warrpurc',
+                                            'type': 'date',
+                                            'dateFormat': 'Y-m-d'
+                                        }
+                                    ]
+                                }
+                            },
+                            footer : {
+                                xtype: 'PagingToolbar',
+                                xns: Roo,
+                                displayInfo : true,
+                                displayMsg : "{0} - {1} of {2}",
+                                emptyMsg : "No itemloc found",
+                                pageSize : 25
+                            },
+                            colModel : [
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    dataIndex : 'itemsite_item_id_item_number',
+                                    header : 'Item',
+                                    width : 75,
+                                    renderer : function(v) { return String.format('{0}', v); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'itemsite_qty',
+                                    header : 'Qty',
+                                    width : 55,
+                                    renderer : function(v) { return String.format('{0}', (v*1).toFixed(0)); }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'netsuite_qty',
+                                    header : 'NS Qty',
+                                    hidden : true,
+                                    width : 50,
+                                    renderer : function(v,x,r) {     
+                                        var f= '<span style="color:blue;text-decoration:underline;cursor:pointer;">{0}</span>';
+                                        if ((r.data.itemsite_qty) *1 != (v*1)) {
+                                            f = '<span style="color:red;font-weight:bold;text-decoration:underline;cursor:pointer;">{0}</span>';
+                                        }
+                                        return String.format(f, (v*1).toFixed(0) ); 
+                                    }
+                                },
+                                {
+                                    xtype: 'ColumnModel',
+                                    xns: Roo.grid,
+                                    align : 'right',
+                                    dataIndex : 'itemsite_value',
+                                    header : 'Value',
+                                    width : 75,
+                                    renderer : function(v) { return Roo.util.Format.usMoney(v); }
+                                }
+                            ]
+                        }
+                    }
+                ],
+                center : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo
+                },
+                east : {
+                    xtype: 'LayoutRegion',
+                    xns: Roo,
+                    split : true,
+                    title : "Stock",
+                    width : 250
+                }
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleStockHistory.bjs b/Pman.Tab.XtupleStockHistory.bjs
new file mode 100644 (file)
index 0000000..e81d021
--- /dev/null
@@ -0,0 +1,569 @@
+{
+    "id": "roo-file-374",
+    "name": "Pman.Tab.XtupleStockHistory",
+    "parent": "Pman.Tab.XtupleManage",
+    "title": "Pman.Tab.XtupleStockHistory",
+    "path": "/home/alan/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleStockHistory.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "invhist",
+            "title": "Inventory History",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    //_this.dialog = Pman.Dialog.FILL_IN\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "celldblclick": "function (_self, rowIndex, colIndex, e)\n{\n    var col = _this.grid.colModel.config[colIndex].dataIndex;\n    \n    if (col !='item_number') {\n        return;\n    }\n    var r = _this.grid.ds.getAt(rowIndex).data;\n    \n    _this.itemsiteCombo.setValue(r.item_number);\n    _this.grid.footer.onClick('first');\n    \n    \n}"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "invhist_comments",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "|xns": "Roo",
+                            "xtype": "Toolbar",
+                            "*prop": "toolbar",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}",
+                                        "render": "function (_self)\n{\n    _this.itemsiteCombo = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "itemsite_item_id_item_number",
+                                    "editable": true,
+                                    "emptyText": "Select itemsite",
+                                    "fieldLabel": "Item",
+                                    "forceSelection": true,
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "itemsite_item_id_item_number",
+                                    "pageSize": 20,
+                                    "qtip": "Select itemsite",
+                                    "queryParam": "query[number]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "itemsite_item_id_item_number",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    var l = _this.locationCombo.getValue();\n    if (l ) { \n        o.params._has_invdetail_location_id = l;\n    }\n\n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'id' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/itemsite.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"itemsite_abcclass\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, record, index)\n{\n  \n \n   (function() { \n     if (_this.grid) {\n        _this.grid.footer.onClick('first'); \n    }\n     }).defer(100);\n}",
+                                        "render": "function (_self)\n{\n    _this.locationCombo = _self;\n} "
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "location_descrip",
+                                    "editable": true,
+                                    "emptyText": "Select location",
+                                    "fieldLabel": "location",
+                                    "forceSelection": true,
+                                    "hiddenName": "location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "location_descrip",
+                                    "pageSize": 200,
+                                    "qtip": "Select location",
+                                    "queryParam": "query[location_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_descrip}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "location_id",
+                                    "width": 200,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    o.params._has_invdetail = 1;\n    // set more here\n     var item_num =  _this.itemsiteCombo.getValue();\n     if (item_num.length) {\n        o.params._has_invdetail_item = item_num;\n    }\n    \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.viewtype = _self;\n}",
+                                        "select": "function (combo, record, index)\n{\n    Roo.log('select');\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "fname",
+                                    "editable": false,
+                                    "hiddenName": "status",
+                                    "listWidth": 200,
+                                    "mode": "local",
+                                    "name": "status_name",
+                                    "triggerAction": "all",
+                                    "value": "BOTH",
+                                    "valueField": "ftype",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "xtype": "SimpleStore",
+                                            "|data": "[ \n    [ 'BOTH', \"All Transactions\"],\n    [ 'IN' , \"Incomming\"],\n    [ 'OUT', \"Outgoing\"] ,\n    [ 'BOTHALL', \"All Transactions (with voided)\"]\n\n]\n",
+                                            "|fields": "[  'ftype', 'fname']",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "text": "From",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.dateSel = _self;\n}",
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "fieldLabel": "Date",
+                                    "format": "Y-m-d",
+                                    "useIso": true,
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "text": "To",
+                                    "xtype": "TextItem",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.endDateSel = _self;\n}",
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "fieldLabel": "Date",
+                                    "format": "Y-m-d",
+                                    "useIso": true,
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function ()\n{\n    var id = 1* _this.form.findField('cohead_id').getValue();\n    if (!id) {\n        Roo.MessageBox.alert(\"Error\", \"Save Sales order first\");\n        return;\n    \n    }\n    // check current status of shipment..\n\n        new Pman.Download({\n            url : baseURL + '/Roo/cohead',\n            method : 'GET',\n            params : {\n                cohead_id :  id,\n                _excel : 1\n            },\n            success : function() {\n\n            }\n        })\n            \n            \n   \n}"
+                                    },
+                                    "text": "Download Reports",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/spreadsheet.gif'",
+                                    "|xns": "Roo.Toolbar",
+                                    "items": [
+                                        {
+                                            "|xns": "Roo.menu",
+                                            "xtype": "Menu",
+                                            "*prop": "menu",
+                                            "items": [
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    if (!_this.itemsiteCombo.getValue().length  && \n        !_this.locationCombo.getValue() && \n        !_this.dateSel.getValue() && \n        !_this.endDateSel.getValue()) {\n        _this.grid.ds.removeAll();\n        Roo.MessageBox.alert(\"Error\", \"Nothing to download!\");\n        return false;\n    }\n    \n    new Pman.Download({\n        params : {_asExcel : 1,  limit : 99999},\n        grid : _this.grid,\n        newWindow : 1\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                    },
+                                                    "text": "History",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    \n    var dt = _this.dateSel.getValue();\n    var end_dt =           _this.endDateSel.getValue();\n   \n    \n    if(!dt){\n        Roo.Msg.alert('Error', 'Please select a FROM date to download');\n        return;\n    }\n    if(!end_dt){\n        Roo.Msg.alert('Error', 'Please select a TO date to download');\n        return;\n    }\n    \n    var    params = {\n        _group : 'invhist',\n        _name : 'summary',\n        'from_dt:text' : dt,\n        'to_dt:text' : end_dt,\n                \n        csvCols : '*',\n        csvTitles : '*',    \n        limit : 9999   \n        \n    }\n    if (  _this.locationCombo.getValue() * 1) {\n              params['invdetail_location_id:number']  =  _this.locationCombo.getValue() ;\n    }\n    \n    \n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params :  params\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                    },
+                                                    "text": "Summary of Orders/Transfers",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "|xns": "Roo.menu",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n\n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'inventory',\n            _name : 'asset',\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                    },
+                                                    "text": "Day by Day - GL to stock comparison",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var dt = _this.dateSel.getValue();\n    \n    if(!dt){\n        Roo.Msg.alert('Error', 'Please select a FROM date to download');\n        return;\n    }\n    \n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'inventory',\n            _name : 'bydate',\n            '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                    },
+                                                    "text": "Inventory Transactions on From date",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var dt = _this.dateSel.getValue();\n    \n    if(!dt){\n        Roo.Msg.alert('Error', 'Please select a FROM date to download');\n        return;\n    }\n    \n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        method : 'GET',\n        params : {\n            _group : 'gltrans',\n            _name : 'bydate',\n            '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            csvCols : '*',\n            csvTitles : '*', \n            limit : 9999         \n            \n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}"
+                                                    },
+                                                    "text": "GL Stock Transactions on From date",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                },
+                                                {
+                                                    "|xns": "Roo.menu",
+                                                    "xtype": "Separator"
+                                                },
+                                                {
+                                                    "listeners": {
+                                                        "click": "function (_self, e)\n{\n    var dt = _this.dateSel.getValue();\n    var end_dt =           _this.endDateSel.getValue();\n    var location_id =           _this.locationCombo.getValue() *1;\n    \n    if(!dt){\n        Roo.Msg.alert('Error', 'Please select a FROM date to download');\n        return;\n    }\n    if(!end_dt){\n        Roo.Msg.alert('Error', 'Please select a TO date to download');\n        return;\n    }\n     if(!location_id){\n        Roo.Msg.alert('Error', 'Please select a Location to download');\n        return;\n    }\n    new Pman.Download({\n        url : baseURL + '/Roo/Metasql',\n        newWindow : 1,\n        method : 'GET',\n        params : {\n            _group : 'invdetail',\n            '_name[0]' : 'opening',\n            '_name[1]' : 'closing',                        \n            '_name[2]' : 'byitem',\n            '_name[3]' : 'bydate',     \n            'location_id:number' : location_id,\n            'from_dt:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),\n            'to_dt:text' : typeof(end_dt) == 'string' ? end_dt : end_dt.format('Y-m-d'),            \n            limit : 9999         \n            \n        }\n    });\n    \n    Roo.MessageBox.alert(\"Notice\", \"Report will download shortly\");\n}\n"
+                                                    },
+                                                    "text": "Consignment Detail Report",
+                                                    "xtype": "Item",
+                                                    "|xns": "Roo.menu"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    if (!_this.itemsiteCombo.getValue().length  && \n        !_this.locationCombo.getValue() && \n        !_this.dateSel.getValue() && \n        !_this.endDateSel.getValue()) {\n        _this.grid.ds.removeAll();\n        return false;\n    }\n    o.params['query[item_number]'] = _this.itemsiteCombo.getValue();\n    o.params.invdetail_location_id   = _this.locationCombo.getValue();\n    o.params['query[viewtype]']   = _this.viewtype.getValue();    \n    o.params._with_item =1;\n    \n    var start = _this.dateSel.getValue();\n    var end = _this.endDateSel.getValue();\n   \n    o.params['query[dateSel]'] = typeof(start) == 'string' ? start : start.format('Y-m-d');\n    o.params['query[endDateSel]'] = typeof(end) == 'string' ? end : end.format('Y-m-d');\n    \n    o.params._with_balance = 1;\n    \n   \n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'invhist_transdate,invdetail_id', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "method": "GET",
+                                    "xtype": "HttpProxy",
+                                    "|url": "baseURL + '/Roo/invdetail.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'invhist_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_itemsite_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_transtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_invqty',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_invuom',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_ordnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_docnumber',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_qoh_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_qoh_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_unitcost',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_acct_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_xfer_warehous_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_comments',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_posted',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_imported',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_hasdetail',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_ordtype',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_analyze',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_user',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_created',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_costmethod',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_value_before',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_value_after',\n        'type': 'float'\n    },\n    {\n        'name': 'invhist_series',\n        'type': 'int'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "displayInfo": true,
+                            "displayMsg": "Displaying invhist{0} - {1} of {2}",
+                            "emptyMsg": "No invhist found",
+                            "pageSize": 25,
+                            "xtype": "PagingToolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n   Roo.MessageBox.progress (\"Syncing Fifo fill\", \"Sending\");\n  \n   var offset = 0;\n   var st = new Date();\n   \n   // for a single location.\n   \n   \n  \n   var runSync=  function() {\n       \n\n       \n       \n       new Pman.Request( {\n            url : baseURL+'/Roo/Invdetail',\n            method : 'GET',\n            timeout : 60000,\n            params : {\n                _fifo_fill : 1,\n                offset : offset,\n                location_id : _this.locationCombo.getValue(),\n                item_number : _this.itemsiteCombo.getValue()\n            },\n            success : function(res) {\n                Roo.log(res);\n                if (!res.data.total) {\n                    Roo.MessageBox.hide();\n                    return;\n                }\n                var el = new Date();\n       \n                var elapsed = el - st;\n                \n                var total_time = (elapsed / offset) * res.data.total ;\n                var remaining = (total_time - elapsed) / (1000 * 60);\n                \n                \n                offset = res.data.offset + res.data.limit;\n                Roo.MessageBox.updateProgress ( offset  / res.data.total, \"Done \" + offset + '/' + res.data.total + \n                    \" Est. complete in \" + remaining.toFixed(1) + \"mins\");\n                runSync();\n            }, \n            failure : function() {\n                Roo.MessageBox.alert(\"Error\", \"Sending failed - probably a timeout\");\n            }\n            \n        \n       });\n   }\n   runSync();\n}\n"
+                                    },
+                                    "text": "Fifo Fill",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n   Roo.MessageBox.progress (\"Syncing Fifo fill values\", \"Sending\");\n  \n   var offset = 0;\n   var st = new Date();\n   \n   // for a single location.\n   \n   \n  \n   var runSync=  function() {\n       \n\n       \n       \n       new Pman.Request( {\n            url : baseURL+'/Roo/Invdetail',\n            method : 'GET',\n            timeout : 60000,\n            params : {\n                _fifo_fill : 2,\n                offset : offset,\n                location_id : _this.locationCombo.getValue(),\n                item_number : _this.itemsiteCombo.getValue()\n            },\n            success : function(res) {\n                Roo.log(res);\n                if (!res.data.total) {\n                    Roo.MessageBox.hide();\n                    return;\n                }\n                var el = new Date();\n       \n                var elapsed = el - st;\n                \n                var total_time = (elapsed / offset) * res.data.total ;\n                var remaining = (total_time - elapsed) / (1000 * 60);\n                \n                \n                offset = res.data.offset + res.data.limit;\n                Roo.MessageBox.updateProgress ( offset  / res.data.total, \"Done \" + offset + '/' + res.data.total + \n                    \" Est. complete in \" + remaining.toFixed(1) + \"mins\");\n                runSync();\n            }, \n            failure : function() {\n                Roo.MessageBox.alert(\"Error\", \"Sending failed - probably a timeout\");\n            }\n            \n        \n       });\n   }\n   runSync();\n}\n"
+                                    },
+                                    "text": "Fifo Fill Values",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "click": "\nfunction (_self, e)\n{\n   Roo.MessageBox.progress (\"Syncing shipvoid fill\", \"Sending\");\n  \n   var offset = 0;\n   var st = new Date();\n   \n   // for a single location.\n   \n   \n  \n   var runSync=  function() {\n        \n       \n       new Pman.Request( {\n            url : baseURL+'/Roo/cohead',\n            method : 'GET',\n            timeout : 60000,\n            params : {\n                _fill_shipvoid : 1,\n                offset : offset\n            },\n            success : function(res) {\n                Roo.log(res);\n                if (!res.data.total) {\n                    Roo.MessageBox.hide();\n                    return;\n                }\n                var el = new Date();\n       \n                var elapsed = el - st;\n                \n                var total_time = (elapsed / offset) * res.data.total ;\n                var remaining = (total_time - elapsed) / (1000 * 60);\n                \n                \n                offset = res.data.offset + res.data.limit;\n                Roo.MessageBox.updateProgress ( offset  / res.data.total, \"Done \" + offset + '/' + res.data.total + \n                    \" Est. complete in \" + remaining.toFixed(1) + \"mins\");\n                runSync();\n            }, \n            failure : function() {\n                Roo.MessageBox.alert(\"Error\", \"Sending failed - probably a timeout\");\n            }\n            \n        \n       });\n   }\n   runSync();\n}\n"
+                                    },
+                                    "text": "Shipvoid Fill",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invdetail_id",
+                            "header": "Invdetail#",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    return v;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transdate",
+                            "header": "Date",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );\n    return String.format('{0}', vv ? vv.format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_created",
+                            "header": "Entered",
+                            "hidden": true,
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n    var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );\n    return String.format('{0}', vv ? vv.format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "item_number",
+                            "header": "Item",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n     \n    return String.format('<b>{0}</b>', v );\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_ordnumber",
+                            "header": "Order#",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) {\n\n\n     return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_docnumber",
+                            "header": "doc#",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transtype",
+                            "header": "Type",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invhist_unitcost",
+                            "header": " unitcost",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "location_name",
+                            "header": "Location",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('<B>{0}</B>', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invdetail_qty",
+                            "header": "Change",
+                            "width": 50,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invdetail_balance_qty",
+                            "header": "Balance",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', parseInt( v)); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "xtype": "ColumnModel",
+                            "header": "Invhist comments",
+                            "width": 200,
+                            "dataIndex": "invhist_comments",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid",
+                            "*prop": "colModel[]"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_qty_after",
+                            "header": "Fifo After",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    if ( r.data.invdetail_qty < 0 ) {\n        return '';\n    }\n    return   (v*1).toFixed(0) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_qty_after",
+                            "header": "Fifo After",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    if ( r.data.invdetail_qty > 0 ) {\n        return '';\n    }\n    return   (v*1).toFixed(0) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_cost_before",
+                            "header": "Fifo Cost Before",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n        if ( r.data.invdetail_qty < 0 ) {\n        return '';\n    } \n    return   (v*1).toFixed(2) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_cost_after",
+                            "header": "Fifo Cost After",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n        if ( r.data.invdetail_qty < 0 ) {\n        return '';\n    } \n    return   (v*1).toFixed(2) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_cost_before",
+                            "header": "Fifo Cost Before",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    if ( r.data.invdetail_qty > 0 ) {\n        return '';\n    }\n    return   (v*1).toFixed(2) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_cost_after",
+                            "header": "Fifo Cost After",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    if ( r.data.invdetail_qty > 0 ) {\n        return '';\n    }\n    return   (v*1).toFixed(2) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_unitcost",
+                            "header": "Fifo Unitcost",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n     \n    return   (v*1).toFixed(2) ;\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "align": "right",
+                            "dataIndex": "invfifo_landedunitcost",
+                            "header": "Fifo Landed Unitcost",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n    \n    var cu = ((r.data.invfifo_cost_after*1 - r.data.invfifo_cost_before*1) / Math.abs(r.data.invdetail_qty)).toFixed(2);\n    var lu = (v*1).toFixed(2) ;\n    if (cu != lu) {\n        return '<span style=\"color:red\">' + lu +'/' +cu + '</span>';\n    }\n    return  lu;\n }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "005"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleStockHistory.js b/Pman.Tab.XtupleStockHistory.js
new file mode 100644 (file)
index 0000000..0f533d5
--- /dev/null
@@ -0,0 +1,1135 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleStockHistory = new Roo.XComponent({
+    part     :  ["Xtuple","StockHistory"],
+    order    : '005-Pman.Tab.XtupleStockHistory',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleManage',
+    name     : "Pman.Tab.XtupleStockHistory",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'invhist',
+            title : "Inventory History",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        //_this.dialog = Pman.Dialog.FILL_IN
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    celldblclick : function (_self, rowIndex, colIndex, e)
+                    {
+                        var col = _this.grid.colModel.config[colIndex].dataIndex;
+                        
+                        if (col !='item_number') {
+                            return;
+                        }
+                        var r = _this.grid.ds.getAt(rowIndex).data;
+                        
+                        _this.itemsiteCombo.setValue(r.item_number);
+                        _this.grid.footer.onClick('first');
+                        
+                        
+                    }
+                },
+                autoExpandColumn : 'invhist_comments',
+                loadMask : true,
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, record, index)
+                                {
+                                  
+                                 
+                                   (function() { 
+                                     if (_this.grid) {
+                                        _this.grid.footer.onClick('first'); 
+                                    }
+                                     }).defer(100);
+                                },
+                                render : function (_self)
+                                {
+                                    _this.itemsiteCombo = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'itemsite_item_id_item_number',
+                            editable : true,
+                            emptyText : "Select itemsite",
+                            fieldLabel : 'Item',
+                            forceSelection : true,
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'itemsite_item_id_item_number',
+                            pageSize : 20,
+                            qtip : "Select itemsite",
+                            queryParam : 'query[number]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{itemsite_item_id_item_number}</b> {itemsite_item_id_item_descrip1}</div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'itemsite_item_id_item_number',
+                            width : 200,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        var l = _this.locationCombo.getValue();
+                                        if (l ) { 
+                                            o.params._has_invdetail_location_id = l;
+                                        }
+                                    
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'id' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/itemsite.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"id","type":"int"},{"name":"itemsite_abcclass","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, record, index)
+                                {
+                                  
+                                 
+                                   (function() { 
+                                     if (_this.grid) {
+                                        _this.grid.footer.onClick('first'); 
+                                    }
+                                     }).defer(100);
+                                },
+                                render : function (_self)
+                                {
+                                    _this.locationCombo = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'location_descrip',
+                            editable : true,
+                            emptyText : "Select location",
+                            fieldLabel : 'location',
+                            forceSelection : true,
+                            hiddenName : 'location_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'location_descrip',
+                            pageSize : 200,
+                            qtip : "Select location",
+                            queryParam : 'query[location_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_descrip}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'location_id',
+                            width : 200,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        o.params._has_invdetail = 1;
+                                        // set more here
+                                         var item_num =  _this.itemsiteCombo.getValue();
+                                         if (item_num.length) {
+                                            o.params._has_invdetail_item = item_num;
+                                        }
+                                        
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/location.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.viewtype = _self;
+                                },
+                                select : function (combo, record, index)
+                                {
+                                    Roo.log('select');
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : false,
+                            displayField : 'fname',
+                            editable : false,
+                            hiddenName : 'status',
+                            listWidth : 200,
+                            mode : 'local',
+                            name : 'status_name',
+                            triggerAction : 'all',
+                            value : "BOTH",
+                            valueField : 'ftype',
+                            width : 150,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                data : [ 
+                                    [ 'BOTH', "All Transactions"],
+                                    [ 'IN' , "Incomming"],
+                                    [ 'OUT', "Outgoing"] ,
+                                    [ 'BOTHALL', "All Transactions (with voided)"]
+                                
+                                ],
+                                fields : [  'ftype', 'fname']
+                            }
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "From"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.dateSel = _self;
+                                },
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            fieldLabel : 'Date',
+                            format : 'Y-m-d',
+                            useIso : true,
+                            width : 150
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'TextItem',
+                            xns: Roo.Toolbar,
+                            text : "To"
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.endDateSel = _self;
+                                },
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            fieldLabel : 'Date',
+                            format : 'Y-m-d',
+                            useIso : true,
+                            width : 150
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function ()
+                                {
+                                    var id = 1* _this.form.findField('cohead_id').getValue();
+                                    if (!id) {
+                                        Roo.MessageBox.alert("Error", "Save Sales order first");
+                                        return;
+                                    
+                                    }
+                                    // check current status of shipment..
+                                
+                                        new Pman.Download({
+                                            url : baseURL + '/Roo/cohead',
+                                            method : 'GET',
+                                            params : {
+                                                cohead_id :  id,
+                                                _excel : 1
+                                            },
+                                            success : function() {
+                                
+                                            }
+                                        })
+                                            
+                                            
+                                   
+                                }
+                            },
+                            text : "Download Reports",
+                            icon : rootURL + '/Pman/templates/images/spreadsheet.gif',
+                            menu : {
+                                xtype: 'Menu',
+                                xns: Roo.menu,
+                                items : [
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                if (!_this.itemsiteCombo.getValue().length  && 
+                                                    !_this.locationCombo.getValue() && 
+                                                    !_this.dateSel.getValue() && 
+                                                    !_this.endDateSel.getValue()) {
+                                                    _this.grid.ds.removeAll();
+                                                    Roo.MessageBox.alert("Error", "Nothing to download!");
+                                                    return false;
+                                                }
+                                                
+                                                new Pman.Download({
+                                                    params : {_asExcel : 1,  limit : 99999},
+                                                    grid : _this.grid,
+                                                    newWindow : 1
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "History"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                
+                                                var dt = _this.dateSel.getValue();
+                                                var end_dt =           _this.endDateSel.getValue();
+                                               
+                                                
+                                                if(!dt){
+                                                    Roo.Msg.alert('Error', 'Please select a FROM date to download');
+                                                    return;
+                                                }
+                                                if(!end_dt){
+                                                    Roo.Msg.alert('Error', 'Please select a TO date to download');
+                                                    return;
+                                                }
+                                                
+                                                var    params = {
+                                                    _group : 'invhist',
+                                                    _name : 'summary',
+                                                    'from_dt:text' : dt,
+                                                    'to_dt:text' : end_dt,
+                                                            
+                                                    csvCols : '*',
+                                                    csvTitles : '*',    
+                                                    limit : 9999   
+                                                    
+                                                }
+                                                if (  _this.locationCombo.getValue() * 1) {
+                                                          params['invdetail_location_id:number']  =  _this.locationCombo.getValue() ;
+                                                }
+                                                
+                                                
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/Metasql',
+                                                    method : 'GET',
+                                                    params :  params
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "Summary of Orders/Transfers"
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.menu
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                            
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/Metasql',
+                                                    method : 'GET',
+                                                    params : {
+                                                        _group : 'inventory',
+                                                        _name : 'asset',
+                                                        csvCols : '*',
+                                                        csvTitles : '*', 
+                                                        limit : 9999         
+                                                        
+                                                    }
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "Day by Day - GL to stock comparison"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var dt = _this.dateSel.getValue();
+                                                
+                                                if(!dt){
+                                                    Roo.Msg.alert('Error', 'Please select a FROM date to download');
+                                                    return;
+                                                }
+                                                
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/Metasql',
+                                                    method : 'GET',
+                                                    params : {
+                                                        _group : 'inventory',
+                                                        _name : 'bydate',
+                                                        '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                        csvCols : '*',
+                                                        csvTitles : '*', 
+                                                        limit : 9999         
+                                                        
+                                                    }
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "Inventory Transactions on From date"
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var dt = _this.dateSel.getValue();
+                                                
+                                                if(!dt){
+                                                    Roo.Msg.alert('Error', 'Please select a FROM date to download');
+                                                    return;
+                                                }
+                                                
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/Metasql',
+                                                    method : 'GET',
+                                                    params : {
+                                                        _group : 'gltrans',
+                                                        _name : 'bydate',
+                                                        '_as_of:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                        csvCols : '*',
+                                                        csvTitles : '*', 
+                                                        limit : 9999         
+                                                        
+                                                    }
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "GL Stock Transactions on From date"
+                                    },
+                                    {
+                                        xtype: 'Separator',
+                                        xns: Roo.menu
+                                    },
+                                    {
+                                        xtype: 'Item',
+                                        xns: Roo.menu,
+                                        listeners : {
+                                            click : function (_self, e)
+                                            {
+                                                var dt = _this.dateSel.getValue();
+                                                var end_dt =           _this.endDateSel.getValue();
+                                                var location_id =           _this.locationCombo.getValue() *1;
+                                                
+                                                if(!dt){
+                                                    Roo.Msg.alert('Error', 'Please select a FROM date to download');
+                                                    return;
+                                                }
+                                                if(!end_dt){
+                                                    Roo.Msg.alert('Error', 'Please select a TO date to download');
+                                                    return;
+                                                }
+                                                 if(!location_id){
+                                                    Roo.Msg.alert('Error', 'Please select a Location to download');
+                                                    return;
+                                                }
+                                                new Pman.Download({
+                                                    url : baseURL + '/Roo/Metasql',
+                                                    newWindow : 1,
+                                                    method : 'GET',
+                                                    params : {
+                                                        _group : 'invdetail',
+                                                        '_name[0]' : 'opening',
+                                                        '_name[1]' : 'closing',                        
+                                                        '_name[2]' : 'byitem',
+                                                        '_name[3]' : 'bydate',     
+                                                        'location_id:number' : location_id,
+                                                        'from_dt:text' : typeof(dt) == 'string' ? dt : dt.format('Y-m-d'),
+                                                        'to_dt:text' : typeof(end_dt) == 'string' ? end_dt : end_dt.format('Y-m-d'),            
+                                                        limit : 9999         
+                                                        
+                                                    }
+                                                });
+                                                
+                                                Roo.MessageBox.alert("Notice", "Report will download shortly");
+                                            }
+                                        },
+                                        text : "Consignment Detail Report"
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                },
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            if (!_this.itemsiteCombo.getValue().length  && 
+                                !_this.locationCombo.getValue() && 
+                                !_this.dateSel.getValue() && 
+                                !_this.endDateSel.getValue()) {
+                                _this.grid.ds.removeAll();
+                                return false;
+                            }
+                            o.params['query[item_number]'] = _this.itemsiteCombo.getValue();
+                            o.params.invdetail_location_id   = _this.locationCombo.getValue();
+                            o.params['query[viewtype]']   = _this.viewtype.getValue();    
+                            o.params._with_item =1;
+                            
+                            var start = _this.dateSel.getValue();
+                            var end = _this.endDateSel.getValue();
+                           
+                            o.params['query[dateSel]'] = typeof(start) == 'string' ? start : start.format('Y-m-d');
+                            o.params['query[endDateSel]'] = typeof(end) == 'string' ? end : end.format('Y-m-d');
+                            
+                            o.params._with_balance = 1;
+                            
+                           
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'invhist_transdate,invdetail_id', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Roo/invdetail.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'invhist_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_itemsite_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_transdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'invhist_transtype',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_invqty',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_invuom',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_ordnumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_docnumber',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_qoh_before',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_qoh_after',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_unitcost',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_acct_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_xfer_warehous_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_comments',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_posted',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_imported',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_hasdetail',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_ordtype',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_analyze',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_user',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_created',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'invhist_costmethod',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_value_before',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_value_after',
+                                'type': 'float'
+                            },
+                            {
+                                'name': 'invhist_series',
+                                'type': 'int'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    displayInfo : true,
+                    displayMsg : "Displaying invhist{0} - {1} of {2}",
+                    emptyMsg : "No invhist found",
+                    pageSize : 25,
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                   Roo.MessageBox.progress ("Syncing Fifo fill", "Sending");
+                                  
+                                   var offset = 0;
+                                   var st = new Date();
+                                   
+                                   // for a single location.
+                                   
+                                   
+                                  
+                                   var runSync=  function() {
+                                       
+                                
+                                       
+                                       
+                                       new Pman.Request( {
+                                            url : baseURL+'/Roo/Invdetail',
+                                            method : 'GET',
+                                            timeout : 60000,
+                                            params : {
+                                                _fifo_fill : 1,
+                                                offset : offset,
+                                                location_id : _this.locationCombo.getValue(),
+                                                item_number : _this.itemsiteCombo.getValue()
+                                            },
+                                            success : function(res) {
+                                                Roo.log(res);
+                                                if (!res.data.total) {
+                                                    Roo.MessageBox.hide();
+                                                    return;
+                                                }
+                                                var el = new Date();
+                                       
+                                                var elapsed = el - st;
+                                                
+                                                var total_time = (elapsed / offset) * res.data.total ;
+                                                var remaining = (total_time - elapsed) / (1000 * 60);
+                                                
+                                                
+                                                offset = res.data.offset + res.data.limit;
+                                                Roo.MessageBox.updateProgress ( offset  / res.data.total, "Done " + offset + '/' + res.data.total + 
+                                                    " Est. complete in " + remaining.toFixed(1) + "mins");
+                                                runSync();
+                                            }, 
+                                            failure : function() {
+                                                Roo.MessageBox.alert("Error", "Sending failed - probably a timeout");
+                                            }
+                                            
+                                        
+                                       });
+                                   }
+                                   runSync();
+                                }
+                            },
+                            text : "Fifo Fill"
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                   Roo.MessageBox.progress ("Syncing Fifo fill values", "Sending");
+                                  
+                                   var offset = 0;
+                                   var st = new Date();
+                                   
+                                   // for a single location.
+                                   
+                                   
+                                  
+                                   var runSync=  function() {
+                                       
+                                
+                                       
+                                       
+                                       new Pman.Request( {
+                                            url : baseURL+'/Roo/Invdetail',
+                                            method : 'GET',
+                                            timeout : 60000,
+                                            params : {
+                                                _fifo_fill : 2,
+                                                offset : offset,
+                                                location_id : _this.locationCombo.getValue(),
+                                                item_number : _this.itemsiteCombo.getValue()
+                                            },
+                                            success : function(res) {
+                                                Roo.log(res);
+                                                if (!res.data.total) {
+                                                    Roo.MessageBox.hide();
+                                                    return;
+                                                }
+                                                var el = new Date();
+                                       
+                                                var elapsed = el - st;
+                                                
+                                                var total_time = (elapsed / offset) * res.data.total ;
+                                                var remaining = (total_time - elapsed) / (1000 * 60);
+                                                
+                                                
+                                                offset = res.data.offset + res.data.limit;
+                                                Roo.MessageBox.updateProgress ( offset  / res.data.total, "Done " + offset + '/' + res.data.total + 
+                                                    " Est. complete in " + remaining.toFixed(1) + "mins");
+                                                runSync();
+                                            }, 
+                                            failure : function() {
+                                                Roo.MessageBox.alert("Error", "Sending failed - probably a timeout");
+                                            }
+                                            
+                                        
+                                       });
+                                   }
+                                   runSync();
+                                }
+                            },
+                            text : "Fifo Fill Values"
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                   Roo.MessageBox.progress ("Syncing shipvoid fill", "Sending");
+                                  
+                                   var offset = 0;
+                                   var st = new Date();
+                                   
+                                   // for a single location.
+                                   
+                                   
+                                  
+                                   var runSync=  function() {
+                                        
+                                       
+                                       new Pman.Request( {
+                                            url : baseURL+'/Roo/cohead',
+                                            method : 'GET',
+                                            timeout : 60000,
+                                            params : {
+                                                _fill_shipvoid : 1,
+                                                offset : offset
+                                            },
+                                            success : function(res) {
+                                                Roo.log(res);
+                                                if (!res.data.total) {
+                                                    Roo.MessageBox.hide();
+                                                    return;
+                                                }
+                                                var el = new Date();
+                                       
+                                                var elapsed = el - st;
+                                                
+                                                var total_time = (elapsed / offset) * res.data.total ;
+                                                var remaining = (total_time - elapsed) / (1000 * 60);
+                                                
+                                                
+                                                offset = res.data.offset + res.data.limit;
+                                                Roo.MessageBox.updateProgress ( offset  / res.data.total, "Done " + offset + '/' + res.data.total + 
+                                                    " Est. complete in " + remaining.toFixed(1) + "mins");
+                                                runSync();
+                                            }, 
+                                            failure : function() {
+                                                Roo.MessageBox.alert("Error", "Sending failed - probably a timeout");
+                                            }
+                                            
+                                        
+                                       });
+                                   }
+                                   runSync();
+                                }
+                            },
+                            text : "Shipvoid Fill"
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invdetail_id',
+                        header : 'Invdetail#',
+                        width : 75,
+                        renderer : function(v) { 
+                            return v;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transdate',
+                        header : 'Date',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { 
+                            var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );
+                            return String.format('{0}', vv ? vv.format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_created',
+                        header : 'Entered',
+                        hidden : true,
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { 
+                            var vv = Date.parseDate(v.split(' ')[0],'Y-m-d' );
+                            return String.format('{0}', vv ? vv.format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'item_number',
+                        header : 'Item',
+                        width : 75,
+                        renderer : function(v) { 
+                             
+                            return String.format('<b>{0}</b>', v );
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_ordnumber',
+                        header : 'Order#',
+                        width : 100,
+                        renderer : function(v,x,r) {
+                        
+                        
+                             return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_docnumber',
+                        header : 'doc#',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transtype',
+                        header : 'Type',
+                        width : 50,
+                        renderer : function(v,x,r) { return String.format('{0}/{1}', v,r.data.invhist_ordtype); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invhist_unitcost',
+                        header : ' unitcost',
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'location_name',
+                        header : 'Location',
+                        width : 100,
+                        renderer : function(v) { return String.format('<B>{0}</B>', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invdetail_qty',
+                        header : 'Change',
+                        width : 50,
+                        renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invdetail_balance_qty',
+                        header : 'Balance',
+                        width : 75,
+                        renderer : function(v) { return String.format('{0}', parseInt( v)); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        header : 'Invhist comments',
+                        width : 200,
+                        dataIndex : 'invhist_comments',
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_qty_after',
+                        header : 'Fifo After',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                            if ( r.data.invdetail_qty < 0 ) {
+                                return '';
+                            }
+                            return   (v*1).toFixed(0) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_qty_after',
+                        header : 'Fifo After',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                            if ( r.data.invdetail_qty > 0 ) {
+                                return '';
+                            }
+                            return   (v*1).toFixed(0) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_cost_before',
+                        header : 'Fifo Cost Before',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                                if ( r.data.invdetail_qty < 0 ) {
+                                return '';
+                            } 
+                            return   (v*1).toFixed(2) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_cost_after',
+                        header : 'Fifo Cost After',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                                if ( r.data.invdetail_qty < 0 ) {
+                                return '';
+                            } 
+                            return   (v*1).toFixed(2) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_cost_before',
+                        header : 'Fifo Cost Before',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                            if ( r.data.invdetail_qty > 0 ) {
+                                return '';
+                            }
+                            return   (v*1).toFixed(2) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_cost_after',
+                        header : 'Fifo Cost After',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                            if ( r.data.invdetail_qty > 0 ) {
+                                return '';
+                            }
+                            return   (v*1).toFixed(2) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_unitcost',
+                        header : 'Fifo Unitcost',
+                        width : 75,
+                        renderer : function(v) { 
+                             
+                            return   (v*1).toFixed(2) ;
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        align : 'right',
+                        dataIndex : 'invfifo_landedunitcost',
+                        header : 'Fifo Landed Unitcost',
+                        width : 75,
+                        renderer : function(v,x,r) { 
+                            
+                            var cu = ((r.data.invfifo_cost_after*1 - r.data.invfifo_cost_before*1) / Math.abs(r.data.invdetail_qty)).toFixed(2);
+                            var lu = (v*1).toFixed(2) ;
+                            if (cu != lu) {
+                                return '<span style="color:red">' + lu +'/' +cu + '</span>';
+                            }
+                            return  lu;
+                         }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Tab.XtupleTransfer.bjs b/Pman.Tab.XtupleTransfer.bjs
new file mode 100644 (file)
index 0000000..55b0041
--- /dev/null
@@ -0,0 +1,368 @@
+{
+    "id": "roo-file-62",
+    "name": "Pman.Tab.XtupleTransfer",
+    "parent": "Pman.Tab.XtupleSales",
+    "title": "",
+    "path": "/home/edward/gitlive/web.xtuple/Pman/Xtuple/Pman.Tab.XtupleTransfer.bjs",
+    "items": [
+        {
+            "listeners": {
+                "|activate": "function() {\n    _this.panel = this;\n    if (_this.grid) {\n        _this.grid.footer.onClick('first');\n    }\n}"
+            },
+            "background": true,
+            "fitContainer": true,
+            "fitToframe": true,
+            "region": "center",
+            "tableName": "invhist_transfer",
+            "title": "Transfers",
+            "xtype": "GridPanel",
+            "|xns": "Roo",
+            "items": [
+                {
+                    "listeners": {
+                        "|render": "function() \n{\n    _this.grid = this; \n    _this.dialog =Pman.Dialog.XtupleTransfer;\n    if (_this.panel.active) {\n       this.footer.onClick('first');\n    }\n}",
+                        "|rowdblclick": "function (_self, rowIndex, e)\n{\n     var sel = _this.postedCombo.getValue();\n     \n     var tdb = baseURL.split('/').pop().split('.').shift();\n     \n     \n     if (sel.match(/^office-/)) {\n          tdb = sel.split('-').pop();\n         \n     }\n    \n    \n    if (!_this.dialog) return;\n    \n    var data = this.getDataSource().getAt(rowIndex).data;\n    \n    \n    _this.dialog.show( {\n         invhist_transfer_id : data.invhist_transfer_id,\n         _roo_office : tdb\n         }, function() {\n        _this.grid.footer.onClick('first');\n    }); \n}\n",
+                        "rowclass": "function (gridview, rowcfg)\n{\n    if(rowcfg.record.data.invhist_transfer_void){\n        rowcfg.rowClass = 'strikethrough';\n    }\n}"
+                    },
+                    "*prop": "grid",
+                    "autoExpandColumn": "invhist_transfer_descrip",
+                    "loadMask": true,
+                    "xtype": "Grid",
+                    "|xns": "Roo.grid",
+                    "items": [
+                        {
+                            "listeners": {
+                                "beforeload": "function (_self, o)\n{\n    var tdb = baseURL.split('/').pop().split('.').shift();     \n    o.params._roo_office = tdb;\n    o.params['query[location_id]'] = _this.locCombo.getValue();\n    o.params['query[invhist_transfer_number]'] = _this.searchBox.getValue();\n    var sel = _this.postedCombo.getValue();\n    switch (sel) {\n        case 'VOIDED': \n            o.params.invhist_transfer_void = 1; \n            break;\n        case 'POSTED': \n            o.params.invhist_transfer_posted = 1; \n            break;\n        case 'UNPOSTED': \n            o.params.invhist_transfer_posted = 0; \n            o.params.invhist_transfer_void = 0; \n            break;        \n        case 'ALL': \n            break;\n        default: \n            if (!sel.match(/^office-/)) {\n                break;\n            }\n            delete o.params['query[location_id]'];\n            \n            o.params._roo_office=  sel.replace(/^office-/,'');\n            o.params.cust_to_internalcompany = tdb;\n            break;\n    }\n    var dt = _this.dateSel.getValue();\n   \n    o.params['query[dateSel]'] = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');\n    \n\n    \n    \n}"
+                            },
+                            "*prop": "dataSource",
+                            "remoteSort": true,
+                            "xtype": "Store",
+                            "|sortInfo": "{ field : 'invhist_transfer_transdate', direction: 'DESC' }",
+                            "|xns": "Roo.data",
+                            "items": [
+                                {
+                                    "*prop": "proxy",
+                                    "method": "GET",
+                                    "xtype": "HttpProxy",
+                                    "|url": "baseURL + '/Xtuple/Roo/invhist_transfer.php'",
+                                    "|xns": "Roo.data"
+                                },
+                                {
+                                    "|xns": "Roo.data",
+                                    "xtype": "JsonReader",
+                                    "totalProperty": "total",
+                                    "root": "data",
+                                    "*prop": "reader",
+                                    "id": "id",
+                                    "|fields": "[\n    {\n        'name': 'invhist_transfer_id',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_transdate',\n        'type': 'date',\n        'dateFormat': 'Y-m-d'\n    },\n    {\n        'name': 'invhist_transfer_number',\n        'type': 'string'\n    },\n    {\n        'name': 'invhist_transfer_from',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_to',\n        'type': 'int'\n    },\n    {\n        'name': 'invhist_transfer_descrip',\n        'type': 'string'\n    }\n]"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "footer",
+                            "xtype": "PagingToolbar",
+                            "pageSize": 25,
+                            "displayInfo": true,
+                            "displayMsg": "Displaying invhist_transfer{0} - {1} of {2}",
+                            "emptyMsg": "No invhist_transfer found",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "click": "function (_self, e)\n{\n    new Pman.Download({\n        grid : _this.grid\n    });\n    Roo.MessageBox.alert(\"Downloading\", \"Report is downloading\");\n}"
+                                    },
+                                    "text": "Download",
+                                    "xtype": "Button",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "toolbar",
+                            "xtype": "Toolbar",
+                            "|xns": "Roo",
+                            "items": [
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n  _this.searchBox = _self;\n}",
+                                        "specialkey": "function (_self, e)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "xtype": "TextField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "select": "function (combo, record, index)\n{\n _this.grid.footer.onClick('first');\n}",
+                                        "render": "function (_self)\n{\n    _this.locCombo = _self;\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "displayField": "location_name",
+                                    "editable": true,
+                                    "emptyText": "Select location",
+                                    "fieldLabel": "location",
+                                    "forceSelection": true,
+                                    "hiddenName": "location_id",
+                                    "listWidth": 400,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "location_id",
+                                    "pageSize": 200,
+                                    "qtip": "Select location",
+                                    "queryParam": "query[location_name]",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{location_name}</b>  - <b style=\"color:red\">{location_cust_id_char_internalcompany} </b> {location_descrip} </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "valueField": "location_id",
+                                    "width": 250,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "listeners": {
+                                                "|beforeload": "function (_self, o){\n    o.params = o.params || {};\n    // set more here\n    o.params.location_restrict = 0;\n  \n}\n"
+                                            },
+                                            "*prop": "store",
+                                            "remoteSort": true,
+                                            "xtype": "Store",
+                                            "|sortInfo": "{ direction : 'ASC', field: 'location_name' }",
+                                            "|xns": "Roo.data",
+                                            "items": [
+                                                {
+                                                    "*prop": "proxy",
+                                                    "method": "GET",
+                                                    "xtype": "HttpProxy",
+                                                    "|url": "baseURL + '/Roo/location.php'",
+                                                    "|xns": "Roo.data"
+                                                },
+                                                {
+                                                    "*prop": "reader",
+                                                    "xtype": "JsonReader",
+                                                    "|xns": "Roo.data",
+                                                    "id": "id",
+                                                    "root": "data",
+                                                    "totalProperty": "total",
+                                                    "|fields": "[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"location_name\",\"type\":\"string\"}]"
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "|select": "function (combo, record, index)\n{\n  _this.grid.footer.onClick('first');\n}",
+                                        "|render": "function (_self)\n{\n  _this.postedCombo = _self;\n}"
+                                    },
+                                    "allowBlank": false,
+                                    "displayField": "title",
+                                    "editable": false,
+                                    "emptyText": "Select Action",
+                                    "forceSelection": true,
+                                    "listWidth": 300,
+                                    "loadingText": "Searching...",
+                                    "minChars": 2,
+                                    "name": "action",
+                                    "pageSize": 20,
+                                    "qtip": "Select Action",
+                                    "selectOnFocus": true,
+                                    "tpl": "<div class=\"x-grid-cell-text x-btn button\"><b>{title}</b> </div>",
+                                    "triggerAction": "all",
+                                    "typeAhead": true,
+                                    "value": "ALL",
+                                    "valueField": "code",
+                                    "width": 150,
+                                    "xtype": "ComboBox",
+                                    "|xns": "Roo.form",
+                                    "items": [
+                                        {
+                                            "*prop": "store",
+                                            "isLocal": true,
+                                            "xtype": "SimpleStore",
+                                            "|data": "(function() { \n    var ret = [\n        [ 'ALL', 'All Transactions' ],\n        [ 'UNPOSTED', 'Unposted' ],\n        [ 'POSTED', 'Posted' ],\n        [ 'VOIDED', 'Voided' ],\n        [ '--', '-----------------' ]    \n    ];\n    var c = baseURL.split('/').pop().split('.').shift();     \n    Roo.each(uiConfig.xtuple_offices, function(o) {\n        if (o == c) {\n            return;\n        }\n        ret.push( [ 'office-' + o,    \"Transfers from \" +   Pman.Xtuple.offices[o] ] );\n\n    });\n    \n    return ret;\n    \n    \n})()",
+                                            "|fields": "[ 'code', 'title' ]",
+                                            "|xns": "Roo.data"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "listeners": {
+                                        "render": "function (_self)\n{\n    _this.dateSel = _self;\n}",
+                                        "select": "function (combo, date)\n{\n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "allowBlank": true,
+                                    "fieldLabel": "Date",
+                                    "format": "Y-m-d",
+                                    "width": 150,
+                                    "xtype": "DateField",
+                                    "|xns": "Roo.form"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n_this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/search.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function (_self, e)\n{\n    _this.searchBox.setValue('');\n    \n    _this.locCombo.setValue(''); \n\n    \n    _this.grid.footer.onClick('first');\n}"
+                                    },
+                                    "cls": "x-btn-icon",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/edit-clear.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Fill"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    \n     var sel = _this.postedCombo.getValue();\n     if (sel.match(/^office-/)) {\n        Roo.Msg.alert('Error', \"You can create transfers for another office\");\n        return;\n     }\n    \n    if (!_this.dialog) return;\n    _this.dialog.show( { id : 0, _roo_office : baseURL.split('/').pop().split('.').shift() } , function() {\n        _this.grid.footer.onClick('first');\n   }); \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Add",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n    \n     var sel = _this.postedCombo.getValue();\n     if (sel.match(/^office-/)) {\n        Roo.Msg.alert('Error', 'You can not create reversals of transfer from another office');\n        return;\n     }\n     \n    \n    var s = _this.grid.getSelectionModel().getSelected();\n    if(!s){\n        Roo.Msg.alert('Error', 'Please select a row!');\n        return;\n    }\n    Roo.log(s);\n    if(s.data.cust_to_internalcompany.length > 0){\n        Roo.Msg.confirm(\"Comfirm\", \"Are you sure? <br/>\" + \n            \"This will create a transfer in the other company dragon, you will need to log to that company and post for it to happen.<br/>\" +\n            \"Otherwise, it just creates a transfer, and then opens the dialog to edit it.\", \n            function(r) {\n                if (r != 'yes') {\n                    return;\n                }\n               \n               Roo.Msg.alert('Warnning', 'Sorry, it is comming soon !!');\n            }\n        );\n        \n        return;\n    }\n    \n    \n    Roo.Msg.confirm(\"Comfirm\", \"Are you sure? <br/>\" + \n        \"You can void a transfer, however if you need to reverse a transfer at a different date press 'yes', and a new transfer will be created.\", \n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            var data = {\n                invhist_transfer_transdate : new Date(),\n                invhist_transfer_arrivaldate : new Date(),\n                invhist_transfer_to : s.data.invhist_transfer_from_location_id,\n                invhist_transfer_to_location_descrip : s.data.invhist_transfer_from_location_descrip,\n                invhist_transfer_from : s.data.invhist_transfer_to_location_id,\n                invhist_transfer_from_location_descrip : s.data.invhist_transfer_to_location_descrip,\n                invhist_transfer_price : s.data.invhist_transfer_price,\n                invhist_transfer_descrip : s.data.invhist_transfer_descrip,\n                _createReverse : s.data.invhist_transfer_id\n                \n            };\n           _this.dialog.show( data, function() {\n                _this.grid.footer.onClick('first');\n            }); \n           \n        }\n    );\n    return;\n   \n}\n"
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Create Reverse Transfer",
+                                    "xtype": "Button",
+                                    "|icon": "Roo.rootURL + 'images/default/dd/drop-add.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n      var sel = _this.postedCombo.getValue();\n      if (sel.match(/^office-/)) {\n        Roo.Msg.alert('Error', \"You can not Post transfer from another office\");\n        return;\n     }\n     var s = _this.grid.selModel.getSelected();\n    if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row to post\");\n        return;\n    }\n    \n    if(s.data.invhist_transfer_void){\n        Roo.MessageBox.alert(\"Error\", \"You can not post a voided transfer\");\n        return;\n    }\n    \n    var msg = \"Posting\";\n    \n    if (s.data.cust_from_internalcompany.length || s.data.cust_to_internalcompany.length) {\n        msg += \" Cross company transfer - large orders may take some time, so do not cancel or reload\";\n    }\n    \n    \n    new Pman.Request({\n        url : baseURL + '/Roo/invhist_transfer',\n        method : 'POST',\n        mask: msg,\n        timeout : 1200000, //20 minutes...! - big xfer should be 10mins.\n        params : {\n            invhist_transfer_id : s.data.invhist_transfer_id,\n            _post : 1\n        },\n        success : function () \n        {\n            _this.grid.footer.onClick('refresh');\n        }\n    });\n    \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Post",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/mail-close.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                },
+                                {
+                                    "|xns": "Roo.Toolbar",
+                                    "xtype": "Separator"
+                                },
+                                {
+                                    "listeners": {
+                                        "|click": "function()\n{\n       var sel = _this.postedCombo.getValue();\n       if (sel.match(/^office-/)) {\n        Roo.Msg.alert('Error', \"You can not Post transfer from coid office\");\n        return;\n     }\n    \n    var s = _this.grid.selModel.getSelected();\n    if (!s) {\n        Roo.MessageBox.alert(\"Error\", \"Select a row to void\");\n        return;\n    }\n    \n    var voidposted = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/invhist_transfer',\n            method : 'POST',\n            mask : \"Voiding\",\n            params : {\n                invhist_transfer_id : s.data.invhist_transfer_id,\n                _void : 1\n            },\n            success : function () \n            {\n                _this.grid.footer.onClick('refresh');\n            }\n        });\n    }\n    \n    var voidunposted = function(){\n        new Pman.Request({\n            url : baseURL + '/Roo/invhist_transfer',\n            method : 'POST',\n            mask : \"Voiding\",\n            params : {\n                invhist_transfer_id : s.data.invhist_transfer_id,\n                invhist_transfer_void : 1\n            },\n            success : function () \n            {\n                _this.grid.footer.onClick('refresh');\n            }\n        });\n    }\n    \n    \n    var posted = s.data.invhist_transfer_posted;\n    \n    Roo.MessageBox.confirm(\"Confirm\", \"Are you sure you want to void that\", \n        function(r) {\n            if (r != 'yes') {\n                return;\n            }\n            if(posted){\n                voidposted();\n                return;\n            }       \n            voidunposted();\n        }\n    )\n    \n}\n        "
+                                    },
+                                    "cls": "x-btn-text-icon",
+                                    "text": "Void",
+                                    "xtype": "Button",
+                                    "|icon": "rootURL + '/Pman/templates/images/trash.gif'",
+                                    "|xns": "Roo.Toolbar"
+                                }
+                            ]
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_posted",
+                            "header": "Posted",
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) {  \n    var state = v * 1 > 0 ?  '-checked' : '';\n\n    return '<img class=\"x-grid-check-icon' + state + '\" src=\"' + Roo.BLANK_IMAGE_URL + '\"/>';\n                \n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_transdate",
+                            "header": "Date",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n\n    return String.format('{0}', v ? Date.parseDate(v.split(' ').shift(),'Y-m-d').format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_arrivaldate",
+                            "header": "Arrival",
+                            "sortable": true,
+                            "width": 75,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { \n\n    return String.format('{0}', v ? Date.parseDate(v.split(' ').shift(),'Y-m-d').format('d/M/Y') : '');\n }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_number",
+                            "header": "reference#",
+                            "sortable": true,
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n     var sel = _this.postedCombo.getValue();\n      var p = baseURL.split('/').pop().split('.').shift().toUpperCase();;\n    if (sel.match(/^office-/)) {\n       p = sel.split('-').pop().toUpperCase();\n     }\n    \n    return String.format(r.data.invhist_transfer_void ? '<s>{0}</s>' : '{0}', p+':'+v); \n    \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_from_location_name",
+                            "header": "From",
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n    var lv = _this.locCombo.getValue();\n     var fmt = lv == r.data.invhist_transfer_from   ? '<B>{0}</B>' : '{0}';\n     if (r.data.cust_from_internalcompany.length) {\n        fmt = '<span style=\"color:red\">[Intercompany {1}] ' + fmt + '</span>';\n     }\n     \n    return String.format(fmt, v,r.data.cust_from_internalcompany );  \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_to_location_name",
+                            "header": "To",
+                            "sortable": true,
+                            "width": 150,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v,x,r) { \n\n    var lv = _this.locCombo.getValue();\n    var fmt = lv == r.data.invhist_transfer_to   ? '<B>{0}</B>' : '{0}';\n    if (r.data.cust_to_internalcompany.length) {\n        fmt = '<span style=\"color:red\">[Intercompany {1}] ' + fmt + '</span>';\n    }\n    \n    return String.format(fmt, v, r.data.cust_to_internalcompany); \n}",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "qty",
+                            "header": "Quantity Moved",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_salesrep_id_salesrep_name",
+                            "header": "Sales Rep",
+                            "width": 100,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        },
+                        {
+                            "*prop": "colModel[]",
+                            "dataIndex": "invhist_transfer_descrip",
+                            "header": "Notes",
+                            "width": 200,
+                            "xtype": "ColumnModel",
+                            "|renderer": "function(v) { return String.format('{0}', v); }",
+                            "|xns": "Roo.grid"
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "permname": "",
+    "modOrder": "700"
+}
\ No newline at end of file
diff --git a/Pman.Tab.XtupleTransfer.js b/Pman.Tab.XtupleTransfer.js
new file mode 100644 (file)
index 0000000..3dceca7
--- /dev/null
@@ -0,0 +1,729 @@
+//<script type="text/javascript">
+
+// Auto generated file - created by app.Builder.js- do not edit directly (at present!)
+
+Pman.Tab.XtupleTransfer = new Roo.XComponent({
+    part     :  ["Xtuple","Transfer"],
+    order    : '700-Pman.Tab.XtupleTransfer',
+    region   : 'center',
+    parent   : 'Pman.Tab.XtupleSales',
+    name     : "unnamed module",
+    disabled : false, 
+    permname : '', 
+    _tree : function()
+    {
+        var _this = this;
+        var MODULE = this;
+        return {
+            xtype: 'GridPanel',
+            xns: Roo,
+            listeners : {
+                activate : function() {
+                    _this.panel = this;
+                    if (_this.grid) {
+                        _this.grid.footer.onClick('first');
+                    }
+                }
+            },
+            background : true,
+            fitContainer : true,
+            fitToframe : true,
+            region : 'center',
+            tableName : 'invhist_transfer',
+            title : "Transfers",
+            grid : {
+                xtype: 'Grid',
+                xns: Roo.grid,
+                listeners : {
+                    render : function() 
+                    {
+                        _this.grid = this; 
+                        _this.dialog =Pman.Dialog.XtupleTransfer;
+                        if (_this.panel.active) {
+                           this.footer.onClick('first');
+                        }
+                    },
+                    rowdblclick : function (_self, rowIndex, e)
+                    {
+                         var sel = _this.postedCombo.getValue();
+                         
+                         var tdb = baseURL.split('/').pop().split('.').shift();
+                         
+                         
+                         if (sel.match(/^office-/)) {
+                              tdb = sel.split('-').pop();
+                             
+                         }
+                        
+                        
+                        if (!_this.dialog) return;
+                        
+                        var data = this.getDataSource().getAt(rowIndex).data;
+                        
+                        
+                        _this.dialog.show( {
+                             invhist_transfer_id : data.invhist_transfer_id,
+                             _roo_office : tdb
+                             }, function() {
+                            _this.grid.footer.onClick('first');
+                        }); 
+                    },
+                    rowclass : function (gridview, rowcfg)
+                    {
+                        if(rowcfg.record.data.invhist_transfer_void){
+                            rowcfg.rowClass = 'strikethrough';
+                        }
+                    }
+                },
+                autoExpandColumn : 'invhist_transfer_descrip',
+                loadMask : true,
+                dataSource : {
+                    xtype: 'Store',
+                    xns: Roo.data,
+                    listeners : {
+                        beforeload : function (_self, o)
+                        {
+                            var tdb = baseURL.split('/').pop().split('.').shift();     
+                            o.params._roo_office = tdb;
+                            o.params['query[location_id]'] = _this.locCombo.getValue();
+                            o.params['query[invhist_transfer_number]'] = _this.searchBox.getValue();
+                            var sel = _this.postedCombo.getValue();
+                            switch (sel) {
+                                case 'VOIDED': 
+                                    o.params.invhist_transfer_void = 1; 
+                                    break;
+                                case 'POSTED': 
+                                    o.params.invhist_transfer_posted = 1; 
+                                    break;
+                                case 'UNPOSTED': 
+                                    o.params.invhist_transfer_posted = 0; 
+                                    o.params.invhist_transfer_void = 0; 
+                                    break;        
+                                case 'ALL': 
+                                    break;
+                                default: 
+                                    if (!sel.match(/^office-/)) {
+                                        break;
+                                    }
+                                    delete o.params['query[location_id]'];
+                                    
+                                    o.params._roo_office=  sel.replace(/^office-/,'');
+                                    o.params.cust_to_internalcompany = tdb;
+                                    break;
+                            }
+                            var dt = _this.dateSel.getValue();
+                           
+                            o.params['query[dateSel]'] = typeof(dt) == 'string' ? dt : dt.format('Y-m-d');
+                            
+                        
+                            
+                            
+                        }
+                    },
+                    remoteSort : true,
+                    sortInfo : { field : 'invhist_transfer_transdate', direction: 'DESC' },
+                    proxy : {
+                        xtype: 'HttpProxy',
+                        xns: Roo.data,
+                        method : 'GET',
+                        url : baseURL + '/Xtuple/Roo/invhist_transfer.php'
+                    },
+                    reader : {
+                        xtype: 'JsonReader',
+                        xns: Roo.data,
+                        totalProperty : 'total',
+                        root : 'data',
+                        id : 'id',
+                        fields : [
+                            {
+                                'name': 'invhist_transfer_id',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_transfer_transdate',
+                                'type': 'date',
+                                'dateFormat': 'Y-m-d'
+                            },
+                            {
+                                'name': 'invhist_transfer_number',
+                                'type': 'string'
+                            },
+                            {
+                                'name': 'invhist_transfer_from',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_transfer_to',
+                                'type': 'int'
+                            },
+                            {
+                                'name': 'invhist_transfer_descrip',
+                                'type': 'string'
+                            }
+                        ]
+                    }
+                },
+                footer : {
+                    xtype: 'PagingToolbar',
+                    xns: Roo,
+                    pageSize : 25,
+                    displayInfo : true,
+                    displayMsg : "Displaying invhist_transfer{0} - {1} of {2}",
+                    emptyMsg : "No invhist_transfer found",
+                    items : [
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    new Pman.Download({
+                                        grid : _this.grid
+                                    });
+                                    Roo.MessageBox.alert("Downloading", "Report is downloading");
+                                }
+                            },
+                            text : "Download"
+                        }
+                    ]
+                },
+                toolbar : {
+                    xtype: 'Toolbar',
+                    xns: Roo,
+                    items : [
+                        {
+                            xtype: 'TextField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                  _this.searchBox = _self;
+                                },
+                                specialkey : function (_self, e)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, record, index)
+                                {
+                                 _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                    _this.locCombo = _self;
+                                }
+                            },
+                            allowBlank : true,
+                            displayField : 'location_name',
+                            editable : true,
+                            emptyText : "Select location",
+                            fieldLabel : 'location',
+                            forceSelection : true,
+                            hiddenName : 'location_id',
+                            listWidth : 400,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'location_id',
+                            pageSize : 200,
+                            qtip : "Select location",
+                            queryParam : 'query[location_name]',
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{location_name}</b>  - <b style="color:red">{location_cust_id_char_internalcompany} </b> {location_descrip} </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            valueField : 'location_id',
+                            width : 250,
+                            store : {
+                                xtype: 'Store',
+                                xns: Roo.data,
+                                listeners : {
+                                    beforeload : function (_self, o){
+                                        o.params = o.params || {};
+                                        // set more here
+                                        o.params.location_restrict = 0;
+                                      
+                                    }
+                                },
+                                remoteSort : true,
+                                sortInfo : { direction : 'ASC', field: 'location_name' },
+                                proxy : {
+                                    xtype: 'HttpProxy',
+                                    xns: Roo.data,
+                                    method : 'GET',
+                                    url : baseURL + '/Roo/location.php'
+                                },
+                                reader : {
+                                    xtype: 'JsonReader',
+                                    xns: Roo.data,
+                                    id : 'id',
+                                    root : 'data',
+                                    totalProperty : 'total',
+                                    fields : [{"name":"id","type":"int"},{"name":"location_name","type":"string"}]
+                                }
+                            }
+                        },
+                        {
+                            xtype: 'ComboBox',
+                            xns: Roo.form,
+                            listeners : {
+                                select : function (combo, record, index)
+                                {
+                                  _this.grid.footer.onClick('first');
+                                },
+                                render : function (_self)
+                                {
+                                  _this.postedCombo = _self;
+                                }
+                            },
+                            allowBlank : false,
+                            displayField : 'title',
+                            editable : false,
+                            emptyText : "Select Action",
+                            forceSelection : true,
+                            listWidth : 300,
+                            loadingText : "Searching...",
+                            minChars : 2,
+                            name : 'action',
+                            pageSize : 20,
+                            qtip : "Select Action",
+                            selectOnFocus : true,
+                            tpl : '<div class="x-grid-cell-text x-btn button"><b>{title}</b> </div>',
+                            triggerAction : 'all',
+                            typeAhead : true,
+                            value : "ALL",
+                            valueField : 'code',
+                            width : 150,
+                            store : {
+                                xtype: 'SimpleStore',
+                                xns: Roo.data,
+                                isLocal : true,
+                                data : (function() { 
+                                    var ret = [
+                                        [ 'ALL', 'All Transactions' ],
+                                        [ 'UNPOSTED', 'Unposted' ],
+                                        [ 'POSTED', 'Posted' ],
+                                        [ 'VOIDED', 'Voided' ],
+                                        [ '--', '-----------------' ]    
+                                    ];
+                                    var c = baseURL.split('/').pop().split('.').shift();     
+                                    Roo.each(uiConfig.xtuple_offices, function(o) {
+                                        if (o == c) {
+                                            return;
+                                        }
+                                        ret.push( [ 'office-' + o,    "Transfers from " +   Pman.Xtuple.offices[o] ] );
+                                
+                                    });
+                                    
+                                    return ret;
+                                    
+                                    
+                                })(),
+                                fields : [ 'code', 'title' ]
+                            }
+                        },
+                        {
+                            xtype: 'DateField',
+                            xns: Roo.form,
+                            listeners : {
+                                render : function (_self)
+                                {
+                                    _this.dateSel = _self;
+                                },
+                                select : function (combo, date)
+                                {
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            allowBlank : true,
+                            fieldLabel : 'Date',
+                            format : 'Y-m-d',
+                            width : 150
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/search.gif'
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function (_self, e)
+                                {
+                                    _this.searchBox.setValue('');
+                                    
+                                    _this.locCombo.setValue(''); 
+                                
+                                    
+                                    _this.grid.footer.onClick('first');
+                                }
+                            },
+                            cls : 'x-btn-icon',
+                            icon : rootURL + '/Pman/templates/images/edit-clear.gif'
+                        },
+                        {
+                            xtype: 'Fill',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    
+                                     var sel = _this.postedCombo.getValue();
+                                     if (sel.match(/^office-/)) {
+                                        Roo.Msg.alert('Error', "You can create transfers for another office");
+                                        return;
+                                     }
+                                    
+                                    if (!_this.dialog) return;
+                                    _this.dialog.show( { id : 0, _roo_office : baseURL.split('/').pop().split('.').shift() } , function() {
+                                        _this.grid.footer.onClick('first');
+                                   }); 
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Add",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                    
+                                     var sel = _this.postedCombo.getValue();
+                                     if (sel.match(/^office-/)) {
+                                        Roo.Msg.alert('Error', 'You can not create reversals of transfer from another office');
+                                        return;
+                                     }
+                                     
+                                    
+                                    var s = _this.grid.getSelectionModel().getSelected();
+                                    if(!s){
+                                        Roo.Msg.alert('Error', 'Please select a row!');
+                                        return;
+                                    }
+                                    Roo.log(s);
+                                    if(s.data.cust_to_internalcompany.length > 0){
+                                        Roo.Msg.confirm("Comfirm", "Are you sure? <br/>" + 
+                                            "This will create a transfer in the other company dragon, you will need to log to that company and post for it to happen.<br/>" +
+                                            "Otherwise, it just creates a transfer, and then opens the dialog to edit it.", 
+                                            function(r) {
+                                                if (r != 'yes') {
+                                                    return;
+                                                }
+                                               
+                                               Roo.Msg.alert('Warnning', 'Sorry, it is comming soon !!');
+                                            }
+                                        );
+                                        
+                                        return;
+                                    }
+                                    
+                                    
+                                    Roo.Msg.confirm("Comfirm", "Are you sure? <br/>" + 
+                                        "You can void a transfer, however if you need to reverse a transfer at a different date press 'yes', and a new transfer will be created.", 
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            var data = {
+                                                invhist_transfer_transdate : new Date(),
+                                                invhist_transfer_arrivaldate : new Date(),
+                                                invhist_transfer_to : s.data.invhist_transfer_from_location_id,
+                                                invhist_transfer_to_location_descrip : s.data.invhist_transfer_from_location_descrip,
+                                                invhist_transfer_from : s.data.invhist_transfer_to_location_id,
+                                                invhist_transfer_from_location_descrip : s.data.invhist_transfer_to_location_descrip,
+                                                invhist_transfer_price : s.data.invhist_transfer_price,
+                                                invhist_transfer_descrip : s.data.invhist_transfer_descrip,
+                                                _createReverse : s.data.invhist_transfer_id
+                                                
+                                            };
+                                           _this.dialog.show( data, function() {
+                                                _this.grid.footer.onClick('first');
+                                            }); 
+                                           
+                                        }
+                                    );
+                                    return;
+                                   
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Create Reverse Transfer",
+                            icon : Roo.rootURL + 'images/default/dd/drop-add.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                      var sel = _this.postedCombo.getValue();
+                                      if (sel.match(/^office-/)) {
+                                        Roo.Msg.alert('Error', "You can not Post transfer from another office");
+                                        return;
+                                     }
+                                     var s = _this.grid.selModel.getSelected();
+                                    if (!s) {
+                                        Roo.MessageBox.alert("Error", "Select a row to post");
+                                        return;
+                                    }
+                                    
+                                    if(s.data.invhist_transfer_void){
+                                        Roo.MessageBox.alert("Error", "You can not post a voided transfer");
+                                        return;
+                                    }
+                                    
+                                    var msg = "Posting";
+                                    
+                                    if (s.data.cust_from_internalcompany.length || s.data.cust_to_internalcompany.length) {
+                                        msg += " Cross company transfer - large orders may take some time, so do not cancel or reload";
+                                    }
+                                    
+                                    
+                                    new Pman.Request({
+                                        url : baseURL + '/Roo/invhist_transfer',
+                                        method : 'POST',
+                                        mask: msg,
+                                        timeout : 1200000, //20 minutes...! - big xfer should be 10mins.
+                                        params : {
+                                            invhist_transfer_id : s.data.invhist_transfer_id,
+                                            _post : 1
+                                        },
+                                        success : function () 
+                                        {
+                                            _this.grid.footer.onClick('refresh');
+                                        }
+                                    });
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Post",
+                            icon : rootURL + '/Pman/templates/images/mail-close.gif'
+                        },
+                        {
+                            xtype: 'Separator',
+                            xns: Roo.Toolbar
+                        },
+                        {
+                            xtype: 'Button',
+                            xns: Roo.Toolbar,
+                            listeners : {
+                                click : function()
+                                {
+                                       var sel = _this.postedCombo.getValue();
+                                       if (sel.match(/^office-/)) {
+                                        Roo.Msg.alert('Error', "You can not Post transfer from coid office");
+                                        return;
+                                     }
+                                    
+                                    var s = _this.grid.selModel.getSelected();
+                                    if (!s) {
+                                        Roo.MessageBox.alert("Error", "Select a row to void");
+                                        return;
+                                    }
+                                    
+                                    var voidposted = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/invhist_transfer',
+                                            method : 'POST',
+                                            mask : "Voiding",
+                                            params : {
+                                                invhist_transfer_id : s.data.invhist_transfer_id,
+                                                _void : 1
+                                            },
+                                            success : function () 
+                                            {
+                                                _this.grid.footer.onClick('refresh');
+                                            }
+                                        });
+                                    }
+                                    
+                                    var voidunposted = function(){
+                                        new Pman.Request({
+                                            url : baseURL + '/Roo/invhist_transfer',
+                                            method : 'POST',
+                                            mask : "Voiding",
+                                            params : {
+                                                invhist_transfer_id : s.data.invhist_transfer_id,
+                                                invhist_transfer_void : 1
+                                            },
+                                            success : function () 
+                                            {
+                                                _this.grid.footer.onClick('refresh');
+                                            }
+                                        });
+                                    }
+                                    
+                                    
+                                    var posted = s.data.invhist_transfer_posted;
+                                    
+                                    Roo.MessageBox.confirm("Confirm", "Are you sure you want to void that", 
+                                        function(r) {
+                                            if (r != 'yes') {
+                                                return;
+                                            }
+                                            if(posted){
+                                                voidposted();
+                                                return;
+                                            }       
+                                            voidunposted();
+                                        }
+                                    )
+                                    
+                                }
+                            },
+                            cls : 'x-btn-text-icon',
+                            text : "Void",
+                            icon : rootURL + '/Pman/templates/images/trash.gif'
+                        }
+                    ]
+                },
+                colModel : [
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_posted',
+                        header : 'Posted',
+                        width : 75,
+                        renderer : function(v) {  
+                            var state = v * 1 > 0 ?  '-checked' : '';
+                        
+                            return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
+                                        
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_transdate',
+                        header : 'Date',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { 
+                        
+                            return String.format('{0}', v ? Date.parseDate(v.split(' ').shift(),'Y-m-d').format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_arrivaldate',
+                        header : 'Arrival',
+                        sortable : true,
+                        width : 75,
+                        renderer : function(v) { 
+                        
+                            return String.format('{0}', v ? Date.parseDate(v.split(' ').shift(),'Y-m-d').format('d/M/Y') : '');
+                         }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_number',
+                        header : 'reference#',
+                        sortable : true,
+                        width : 100,
+                        renderer : function(v,x,r) { 
+                        
+                             var sel = _this.postedCombo.getValue();
+                              var p = baseURL.split('/').pop().split('.').shift().toUpperCase();;
+                            if (sel.match(/^office-/)) {
+                               p = sel.split('-').pop().toUpperCase();
+                             }
+                            
+                            return String.format(r.data.invhist_transfer_void ? '<s>{0}</s>' : '{0}', p+':'+v); 
+                            
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_from_location_name',
+                        header : 'From',
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) { 
+                        
+                            var lv = _this.locCombo.getValue();
+                             var fmt = lv == r.data.invhist_transfer_from   ? '<B>{0}</B>' : '{0}';
+                             if (r.data.cust_from_internalcompany.length) {
+                                fmt = '<span style="color:red">[Intercompany {1}] ' + fmt + '</span>';
+                             }
+                             
+                            return String.format(fmt, v,r.data.cust_from_internalcompany );  
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_to_location_name',
+                        header : 'To',
+                        sortable : true,
+                        width : 150,
+                        renderer : function(v,x,r) { 
+                        
+                            var lv = _this.locCombo.getValue();
+                            var fmt = lv == r.data.invhist_transfer_to   ? '<B>{0}</B>' : '{0}';
+                            if (r.data.cust_to_internalcompany.length) {
+                                fmt = '<span style="color:red">[Intercompany {1}] ' + fmt + '</span>';
+                            }
+                            
+                            return String.format(fmt, v, r.data.cust_to_internalcompany); 
+                        }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'qty',
+                        header : 'Quantity Moved',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_salesrep_id_salesrep_name',
+                        header : 'Sales Rep',
+                        width : 100,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    },
+                    {
+                        xtype: 'ColumnModel',
+                        xns: Roo.grid,
+                        dataIndex : 'invhist_transfer_descrip',
+                        header : 'Notes',
+                        width : 200,
+                        renderer : function(v) { return String.format('{0}', v); }
+                    }
+                ]
+            }
+        };
+    }
+});
diff --git a/Pman.Xtuple.DashboardRender.js b/Pman.Xtuple.DashboardRender.js
new file mode 100644 (file)
index 0000000..72c351c
--- /dev/null
@@ -0,0 +1,1394 @@
+Pman.Xtuple.DashboardRender = {
+    offices : {
+        hk : 'Hong Kong',
+        sg : 'Singapore',
+         my: 'Malaysia',
+        au: 'Australia',
+        'au-0': 'Australia Online',
+        'au-1': 'Australia Trade',
+        cn: 'China',  
+        all: 'Group'
+    },
+    currency : false,
+    
+    templates  : {
+       
+        summary : '',
+        totals : '',
+        
+        salestrend : '',
+        percountry : '',
+        revenuebycustomer : '',
+        profitbycustomer : '',
+        perbrand : '',
+        perproduct : '',
+        slowmoving : ''
+        
+    },
+   
+    state : false,
+    
+    default_state  :
+    {
+        'perday-type'    : 'voice',
+        'perday-vtype'   : 'value',
+        'perday-date'   : (new Date()).format('Y') +'' // 2001 2001Q1 200012 W2012-01-01
+        
+    },
+    
+    filterCfg  :{
+        titles : {
+            /*
+            'country':  "Filter by Country",
+            'language':     "Filter by Language",
+            'mediatype':    "Filter by Media Type",
+            //'publication':     "Filter by Publication",
+            'tonality':    "Filter by Tonality",
+            'keywords':     "Filter by Voice"
+            */
+        }
+     
+    },
+    papers : false,
+    paper : false,
+    
+    initPaper : function(rg)
+    {
+        this.papers = this.papers || {};
+        this.paper=  false;
+        
+        var ge = rg.select('.report-graph',true).first();
+        if (!ge) {
+            Roo.log("NO report-graph  ("+ this.view +") found - skipping");
+            return false;
+        }
+        Roo.log("init paper?");
+        Roo.log(ge);
+        this.dash = Pman.Tab.XtupleDashboard;
+           
+        this.paper = Raphael(ge.dom);
+        var sz = ge.getSize();
+        this.paper.setSize(sz.width,sz.height);
+        this.papers[this.view] = this.paper;
+        
+        return true;
+     
+    },
+    resize : function(w,h)
+    {
+        //this.initPaper();
+        //this.paper.setSize(width,400);
+         
+    },
+    
+    view : 'summary',
+    
+    // top level load ....
+    load: function()
+    {
+        
+        Pman.Tab.XtupleDashboard.panel.el.mask("Loading");
+        // if no combined - only show current..
+        var cdb = baseURL.split('/').pop().split('.').shift();
+        
+        
+        if (!Pman.hasPerm('Xtuple.AccountsCombined', 'S') || cdb !='hk'){ //|| window.location.host == 'localhost') {
+            var offices = {};
+            
+            offices[ cdb ] = this.offices[cdb];
+            this.offices = offices;
+        }
+        
+        
+        this.dash = Pman.Tab.XtupleDashboard;
+        this.tree = Pman.Tab.XtupleDashboard.tree.tree;
+        this.treeroot = this.tree.getRootNode();
+        //var sn =   this.dash.tpanel.tree.getSelectionModel().getSelectedNode();
+        this.view = 'summary';
+        
+        //if(sn) {
+        //    this.view = sn.attributes.id.toLowerCase();
+        //    
+        //}
+        if (!this.state) {
+            this.state = Roo.apply({}, this.default_state);
+        }
+        
+        this.updateStateFromTree();
+        
+        // build a list of views to fetch,
+        this.views = [];
+        for (var i in this.templates) {
+            if (i == 'summary') {
+                continue;
+            }
+            for (k in this.offices) {
+                if(k == 'au' && i == 'totals'){
+                    this.views.push(i + '-' + k + '-0');
+                    this.views.push(i + '-' + k + '-1');
+                    continue;
+                }
+                this.views.push(i + '-' + k);
+            }
+        }
+        
+        this.papers = {}; // reset papers..
+       
+        this.templates.summary.overwrite( this.templateEl(),   {
+            dates : this.buildDates() ,
+            curdates : this.parseDate()
+        }  );
+        
+        // resize height for Month..
+        var dt = this.parseDate();
+        if (dt.type == 'M') {
+            this.templateEl().select('.report-group-perday',true).setStyle('height', '530px');
+            this.templateEl().select('.report-graph-perday',true).setStyle('height', '300px');
+        }
+          
+        
+        //this.dash.viewPanel.el.mask("Loading");
+        this.data = {};
+        this.loadNextView();
+    },
+    
+    data : {},
+    
+    
+    parseDate : function()
+    {
+        // formats :
+        // 2012
+         var ret = {
+            type : '', 
+            year : '',
+            quarter : '',
+            month : '',
+            week:  '',
+            day : '',
+            breadcrumb : ''
+        }
+        
+        ret.type = this.dash.viewType.getValue();
+        
+        var df = Date.parseDate(this.dash.mfrom.getValue(),'Y-m-d');
+        var dt = Date.parseDate(this.dash.mto.getValue(),'Y-m-d');
+        var dp = Date.parseDate(this.dash.daypick.getValue(),'Y-m-d');
+        
+      
+        // year
+        switch(ret.type) {
+            case 'Y':
+            
+                //ret.year = this.state['perday-date'] *1;
+                ret.date = df;
+                ret.dateto =  df.add(Date.YEAR, 1);
+                ret.breadcrumb =  df.format('F Y') + ' to ' + ret.dateto.format('F Y');
+                return ret;
+            case 'H':
+                ret.date = df;
+                ret.dateto =  df.add(Date.MONTH, 6);
+                ret.breadcrumb =  df.format('F Y') + ' to ' + ret.dateto.format('F Y');
+                return ret;
+            
+            case 'Q':
+        
+                ret.date = df;
+                ret.dateto =  df.add(Date.MONTH, 3);
+                ret.breadcrumb =  df.format('F Y') + ' to ' + ret.dateto.format('F Y');
+                return ret;
+            case 'M':
+        
+                ret.date = df;
+                ret.dateto =  df.add(Date.MONTH, 1);
+                ret.breadcrumb =  df.format('F Y');
+                return ret;
+            
+          
+            case 'R':
+                ret.date = df;
+                ret.dateto =  dt;
+                ret.breadcrumb =  df.format('F Y') + ' to ' + ret.dateto.format('F Y');
+                return ret;
+        }
+        return false;
+    },
+    
+    buildDates : function()
+    {
+        var dt = this.parseDate();
+        var ret = {
+            yprev : dt.year - 1,
+            ycur : dt.year,
+            ynext : 0,
+            quarters : [],
+            months : []
+        };
+        
+        if (dt.date.add(Date.YEAR, 1) <= (new Date())) {
+            ret.ynext = dt.year +1;
+        }
+         // quaters..
+        for (var i =0; i < 2; i++) {
+            // is it greater than now..
+            var qs = new Date(dt.year, i * 6, 1);
+            if (qs <= new Date()) {
+                ret.quarters.push({
+                    qtitle : 'H' + (i+1),
+                    qlink : dt.year + 'H' + (i+1)
+                });
+            }
+            
+        }
+        
+        
+        // quaters..
+        for (var i =0; i < 4; i++) {
+            // is it greater than now..
+            var qs = new Date(dt.year, i * 3, 1);
+            if (qs <= new Date()) {
+                ret.quarters.push({
+                    qtitle : 'Q' + (i+1),
+                    qlink : dt.year + 'Q' + (i+1)
+                });
+            }
+            
+        }
+        // months..
+        for (var i =0; i < 12; i++) {
+            // is it greater than now..
+            var qs = new Date(dt.year, i , 1);
+            if (qs <= new Date()) {
+                ret.months.push({
+                    mtitle : qs.format('M')[0],
+                    mlink : dt.year + 'M' + (i+1)
+                });
+            }
+        }
+        
+        return ret;
+        
+        //if ()
+        //ret.ynext 
+        
+        
+        
+    },
+    
+    
+    
+    
+    loadNextView : function()
+    {
+        if (!this.views.length || !this.dash.panel.active) {
+            //this.dash.viewPanel.el.unmask();
+            //this.showFilters();
+            //this.boldSelected();
+            Pman.Tab.XtupleDashboard.panel.el.unmask();
+            return false;
+        }
+        
+        this.view = this.views.shift();
+        //Roo.log(this.view);
+        var rg = this.view == Roo.select('.report-group-' + this.view,true).first();
+        
+        // no hiding in this version??
+        // also need to hide all the share of voices???
+        
+        
+        var _this = this;
+        
+        // not handled yet..
+        //if (['keywords'].indexOf(this.view) > -1) {
+        //    this.loadNextView();
+        //    return false;
+        //}
+        var dt = this.parseDate();
+        
+        var view = this.view.toUpperCase();
+        
+        var ext = view.split('-');
+        view = ext[0];
+        var office = ext[1];
+//        var ext = view.match(/\-[A-Z]+$/i);
+//        view = view.replace(/\-[A-Z]+$/, '');
+//        var office = ext[0].substr(1);
+        var url = office == 'HK' ? baseURL+'/Roo/Dragon_report'  : baseURL+'/Xtuple/Roo/Dragon_report';
+        
+        
+        if(dt.type == 'M' && view == 'SALESTREND') {
+            // it should just mask that entry?
+            Roo.log("skip sales trend");
+            //dash.viewPanel.el.mask("No data available");
+            _this.loadNextView();
+            return false;
+        }
+        
+        
+        var country = this.dash.countryCombo.getValue();
+        
+        if (view == 'PERCOUNTRY' && country.length) {
+            Roo.log("skip per country");
+            //dash.viewPanel.el.mask("No data available");
+            _this.loadNextView();
+            return false;
+        }
+        
+        
+        if ( office == 'ALL') {
+            
+             
+            var rg =   Roo.select('.report-group-' + this.view ,true).first();
+            if (!rg) {
+                _this.loadNextView();
+                Roo.log("missing : .report-group-" + this.view);
+                return false;
+                
+            }
+            var res = (view == 'TOTALS') ?  { data : [  {} ] } :
+                        { data : [  ] }; // use data from totals.
+            
+            var map = {};
+            
+            for(var k in this.offices) {
+                var dk = view.toLowerCase()+'-' +k;
+                
+                if (typeof(this.data[dk]) == 'undefined') {
+                    Roo.log('skip combined - missing data :'+dk);
+                    continue;
+                }
+                
+                if (view == 'TOTALS') {
+                    //Roo.log("combined : " + view + " " + dk);
+                    //Roo.log(this.data[dk]);
+                    
+                    var dv = this.data[dk][0];
+                    
+                    for (var kk in dv) {
+                        res.data[0][kk] = typeof(res.data[0][kk]) == 'undefined' ?  0 : res.data[0][kk] ;
+                        var n = dv[kk] *1;
+                        if (isNaN(n)) {
+                            res.data[0][kk]  = dv[kk] ;
+                        } else {
+                            res.data[0][kk]  += n;
+                        }
+                        
+                        
+                    }
+                    
+                    
+                } else {
+                   // Roo.log('combined non-totals : DATA');
+                    // add the rows for each country together..
+                    
+                    // australia double reports...
+                    var unsplit_country = dk.replace(/-[0-9]+$/,'');
+                    if (dk != unsplit_country && typeof(this.data[unsplit_country]) != 'undefined') {
+                        continue;
+                    }
+                    
+                    var dv = this.data[dk];
+                   // Roo.log(dv);
+                    Roo.each(dv, function (dvr) {
+                        dvr.qtysold *= 1;
+                        dvr.rvalue *= 1;
+                       
+                        if (typeof (map[dvr.rkey] ) == 'undefined') {
+                             
+                            map[dvr.rkey] = Roo.apply({}, dvr);
+                            map[dvr.rkey].percent = '';
+                            res.data.push(map[dvr.rkey]);
+                            return;
+                        }
+                        map[dvr.rkey].qtysold +=   dvr.qtysold ;
+                        map[dvr.rkey].rvalue +=   dvr.rvalue ;
+                        
+                        
+                    });
+                       
+                    
+                    
+                }
+               
+            }
+            Roo.log("MAP for combined");
+            Roo.log(map);
+            if (view != 'TOTALS') {
+                //_this.data[_this.view] = res.data.slice(0); // copy..
+                
+                // percents are borked..
+                res.data.sort(function(a,b) {
+                    //Roo.log(a.rvalue +' ?= ' + b.rvalue);
+                    if (a.rvalue == b.rvalue) {
+                        return 0;
+                    }
+                    return a.rvalue > b.rvalue ? -1 : 1;
+                    
+                });
+                
+                
+               //Roo.log(res);
+                var meth = 'render' + _this.view.toUpperCase().split('-').shift();
+                
+                if (typeof(_this[meth]) == 'undefined') {
+                    if (res.data.length) {
+                        _this.renderDefault( res, _this.view.toLowerCase())
+                    }
+                    
+                    
+                    
+                } else {
+                     
+                    _this[meth]( res , _this.view.toLowerCase());
+                }
+             
+            }  else {
+                res.office = this.offices[office.toLowerCase()];
+                if (res.data.length) {
+                    this.templates[view.toLowerCase()].overwrite( rg,  res);
+                }
+                //Roo.log(res);
+                
+            
+            }
+           
+            
+            
+          
+             
+            
+            //dash.viewPanel.el.mask("No data available");
+            _this.loadNextView();
+            return false;
+        }
+        
+        var p = {
+            'query[report]' : view,
+            'query[dateFrom]' : dt.date.format('Y-m-d'),
+            'query[dateUpto]' : dt.dateto.format('Y-m-d'),
+            'query[country]' : country,
+            'query[showExtra]' : 0,
+            'query[notmg]' : 0,
+            '_roo_office' : office.toLowerCase(),
+            limit : 999//,
+            //_columns : 'rkey,rvalue,rkid,radvalue,rcirculation,rcountry,rkiso'
+        };
+        // combined all in HKD..
+        if (Pman.hasPerm('Xtuple.AccountsCombined', 'S') && baseURL.match(/hk\.php$/)) {
+            p['query[currency]'] = 'HKD';
+        }
+        
+        if(ext[2]){
+            p['query[showExtra]'] = 1;
+            p['query[notmg]'] = ext[2];
+        }
+
+        new Pman.Request({
+            timeout: 600000,    // 10 mins ?!
+            url: url,
+            method: 'GET',
+            params: p,
+            
+            failure : function() {
+                _this.loadNextView();
+                
+            },
+            success: function(res)
+            {
+                if(!res.data.length) {
+                    // it should just mask that entry?
+                    Roo.log("NO DATA?");
+                    //dash.viewPanel.el.mask("No data available");
+                    _this.loadNextView();
+                    return;
+                }
+                
+                
+                //_this.dash.viewPanel.el.unmask();
+                //_this.initPaper();
+                //var sz = this.dash.viewPanel.el.getSize()
+                       // h = sz.height - 20;
+                //_this.width = sz.width;
+                //_this.paper.setSize(sz.width, 400);
+                //_this.paper.clear();
+                 
+                _this.data[_this.view] = res.data.slice(0); 
+                
+                var meth = 'render' + _this.view.toUpperCase().split('-').shift();
+                
+                if (typeof(_this[meth]) == 'undefined') {
+                    _this.renderDefault( res, _this.view.toLowerCase())
+                    
+                    
+                } else {
+                     
+                    _this[meth]( res , _this.view.toLowerCase());
+                }
+                _this.loadNextView(); 
+                
+            }
+        });
+        return false;
+    },
+
+    currentColor : function()
+    {
+        var dash = Pman.Tab.XtupleDashboard;
+        
+        var clr = dash.themeCombo.getValue();
+        var clname = dash.themeCombo.el.dom.value;
+        
+        if(!clr) {
+            clr = dash.themeCombo.store.getAt(0).data.themeData;
+            clname = dash.themeCombo.store.getAt(0).data.name;
+        }
+        
+        if(clname.indexOf('Spectral') != 0) {
+            clr = clr.slice(0);
+            clr.reverse();
+            clr.pop();
+            clr.pop();
+        }
+        return clr;
+    },
+    
+    
+    colorthemes : function() {
+        //  too damn lazy to write
+        //  something elegant here
+        var map = [];
+        map['RdYlGn'] = 'Red Yellow Green';
+        map['RdYlBu'] = 'Red Yellow Blue';
+        map['YlOrBr'] = 'Yellow Orange Brown';
+        map['YlOrRd'] = 'Yellow Orange Red';
+        map['PuBuGn'] = 'Purple Blue Green';
+        map['YlGnBu'] = 'Yellow Green Blue';
+
+        var arr = [];
+        Roo.each(colorbrewer, function(cb, i) {
+            for(var j in cb) {
+                if(j.length > 4) {
+                    for(var k in cb[j]) {
+                        if(k > 8) {
+                            var cn = (map[j] != undefined) ? map[j] : j;
+                            arr.push([cn+' - '+(k-8), cb[j][k]]);
+                        }
+                    }
+                }
+            }
+        });
+        return arr;
+    },
+    
+    mediamap : false,
+    
+    renderDefault : function(res, tmplname)
+    {
+       // var view = this.view.replace(/\-[A-Z]+$/i, '');
+        
+        var ext = this.view.split('-');
+        var view = ext[0];
+        var office = ext[1];
+        
+        var rg =   Roo.select('.report-group-' + this.view ,true).first();
+        if (!rg) {
+            Roo.log("missing : .report-group-" + this.view);
+            return;
+            
+        }
+        
+//        var ext = this.view.match(/\-[A-Z]+$/i);
+//        var office = ext[0].substr(1);
+        
+        
+        //res.dates =  this.buildDates();
+        //res.curdates = this.parseDate();
+        res.office = this.offices[office];
+        if (typeof(res.data[0].currency) != 'undefined') {
+            Roo.log("Got currency:" +  res.data[0].currency)
+            this.currency = res.data[0].currency;
+        }
+        Roo.log("Setting currency to " + this.currency)
+        res.currency = this.currency;
+        
+        if (typeof(res.data[0].total_type) != 'undefined') {
+            res.total_type = res.data[0].total_type;
+        }
+        
+        var dash = Pman.Tab.XtupleDashboard;
+        
+        var clr = this.currentColor();
+        var data = [],
+                l = [],
+                n = res.data.length,
+                per = 1.0 / Math.min(n, 10), // use 10 colours..
+                colours = [];
+
+      
+        var total = 0.0;
+        var resdata = [];
+        
+        Roo.each(res.data, function(r,i) {
+            if (this.state[this.view] &&
+                this.state[this.view].length &&
+                this.state[this.view].split(',').indexOf(r.rkid) < 0)
+            {
+                    return;
+            }
+            
+            
+            data.push(r.rvalue * 1);
+            total+=r.rvalue * 1.0 ;
+            
+            
+            l.push(' %% - ' + r.rkey ); //+ ' (' + r.rvalue + ')');
+            colours.push(clr[i % clr.length]);
+            resdata.push(r);
+        }, this);
+        
+        res.data = resdata;
+        //Roo.log("total:" + total);
+        
+        Roo.each(res.data, function(r,i) {
+            // the type of r.rvalue is string;
+            r.percent =  ((parseInt(r.rvalue) *1.0/ total) * 100.0).toFixed() + '%';
+        })
+        
+        this.templates[view].overwrite( rg,  res);
+        
+         if (!this.initPaper(rg)) {
+            Roo.log("no paper found for " + this.view);
+            return;
+         }          
+        
+        /*
+        var sdata = data.length > 20 ? data.slice(0,20) : data;
+        dash.bar = this.paper.hbarchart(
+            400,
+            10,
+            500,
+            350,
+            sdata ,
+            { 
+                type :   'sharp' ,
+                colors : colours
+            }
+        );
+        */
+        //dash.bar.label(l,true);
+        dash.pie = this.paper.piechart(
+            (this.paper.height - 70) / 2,
+            this.paper.height  / 2 ,
+            (this.paper.height / 2) - 60,
+            data ,
+            { 
+                cut: 10,
+                colors :  colours,
+                legend: l,
+                legendpos: "east"
+            }
+        );
+        dash.pie.hover(
+            // in?
+            function() {
+            
+                this.sector.stop();
+                this.sector.scale(1.1, 1.1, this.cx, this.cy);
+
+                if (this.label) {
+                    this.label[0].stop();
+                    this.label[0].attr({ r: 7.5 });
+                    this.label[1].attr({ "font-weight": 800 });
+                }
+            },
+            // out..?
+            function () {
+                this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
+
+                if (this.label) {
+                    this.label[0].animate({ r: 5 }, 500, "bounce");
+                    this.label[1].attr({ "font-weight": 400 });
+                }
+            
+            
+        })
+        /*
+        var mx = 43;
+        if (tmplname == 'publication') {
+            mx = 10;
+        }
+        
+        if (tmplname == 'country') {
+            mx = 10;
+        }
+        
+        res.data = res.data.splice(0,mx);
+        if (tmplname !== false) {
+            this.templates[tmplname].overwrite(
+                this.templateEl().select('.report-data-' + this.view,true).first(),
+                res
+            );
+        }
+        */
+        //this.templates[tmplname].overwrite( this.templateEl(),   res  );
+        
+    },
+     
+    renderSALESTREND : function(res)
+    {
+         var view = this.view.replace(/\-[A-Z]+$/i, '');
+       
+        var rg =   Roo.select('.report-group-' + this.view ,true).first();
+        if (!rg) {
+            Roo.log("missing : .report-group-" + this.view);
+            return;
+            
+        }
+        Roo.log("do template");
+        var ext = this.view.match(/\-[A-Z]+$/i);
+        
+        var office = ext[0].substr(1);
+    
+        res.office = this.offices[office];
+        
+         if (typeof(res.data[0].currency) != 'undefined') {
+            this.currency = res.data[0].currency;
+        }
+        res.currency = this.currency;
+        
+        
+        
+        Roo.each(res.data, function(r, i) {
+
+            r.rmonth = Date.parseDate(r.rkey, 'Y-m-d').format('M Y');
+            r.shortMonth = Date.parseDate(r.rkey, 'Y-m-d').format('My');
+        });
+        // fill in dates..
+        
+        var dt = this.parseDate();
+        // range is more than a year, then do not show last..
+        var showlast =  (dt.dateto > dt.date.add(Date.YEAR, 1)) ? false : true; 
+        
+        this.templates[view].overwrite( rg,  res);
+        Roo.log("done template"); 
+        var dash = Pman.Tab.XtupleDashboard;
+        
+        var clr = this.currentColor();
+        var qty = [  [], [] ],
+                date = [],
+                colors = [],
+                xpos = 75,
+                ypos = 5;
+          
+        var fc = (res.data[0].rkid +'')[0];
+        
+      
+        var xlabels  = [];
+        var dates = [];
+        // fill data..
+        for (var i = 0; i < res.data.length; i++) {
+            xlabels[i] = res.data[i].shortMonth;
+            qty[1][i] = 0; // make sure previous year is filled out.
+            dates[i] = i;
+             
+        }
+        // fill in the extra data points.
+        
+         
+        // fc can be 'W' or 'M'
+             
+        var k =  'rvalue'  ;
+         var colors = [];
+         var adata = {
+            rvaluetotal: 0,
+            radvaluetotal : 0,
+            rcirculationtotal : 0
+          };
+        var pydata = [];
+        Roo.each(res.data, function(r, i) {
+            
+            var off = r.rkid ;
+            
+            // depending on type of view:
+            // YEARLY - 0000M1
+            // QUARTER --0000M1
+            // anything else... -> nolink...
+            
+            //res.data.rklink = 'nolink';
+            if (r.rkiso) {
+                var d= Date.parseDate(r.rkey, 'Y-m-d');
+                r.rklink = d.format('Y')+'M'+d.format('m');
+            }
+            
+            
+              
+            //qty[i]  =  [ r.sales  * 1,  r.salespy  * 1 ];
+            if (r.sales * 1) {
+                qty[ 0][i] =   r.sales  * 1
+                
+            }
+            if (showlast && r.salespy *1) {
+                qty[1][i] =   r.salespy  * 1 ;
+                
+            }
+            //xlabels[i]  = r.rkey;
+            // not sure if this is needed...
+            colors.push(clr[i%clr.length]);
+            
+            adata.salestotal        += (r.sales *1);
+             
+           
+            
+        });
+        // fill in any empty holes in the original data.
+        for(var i = 0; i < qty[0].length;i++) {
+            qty[0][i] = typeof(qty[0][i] ) == 'undefined' ? 0 : qty[0][i] ;
+        }
+        
+        
+        
+       //Roo.apply(res, adata);
+        
+        // will not work yet..
+        if (this.state['perday-vtype'] == 'cumulative') {
+            var cum = 0;
+
+            for (var i = 0 ; i < last+1;i++) {
+                cum += qty[i];
+                qty[i] = cum;
+            }
+            
+            
+        }
+         
+        var xdata = qty; //qty.length > 20 ? qty.slice(0, 20) : qty;
+        var ydata = dates; //date.length > 20 ? date.slice(0, 20) : date;
+
+        Roo.log(xdata);
+        Roo.log(ydata);
+        Roo.log(colors);
+        Roo.log(xlabels);
+        //return;
+        if (xdata.length < 2) {
+            //dash.viewPanel.el.mask("Not enough data");
+            rg.dom.innerHTML = "not big enough range";
+            return;
+        }
+     
+        
+         if (!this.initPaper(rg)) {
+            Roo.log("no paper found for " + this.view);
+            return;
+         }
+        var       w = this.paper.width - 90,
+                h = this.paper.height - 25;
+
+         
+        Roo.log("Draw linechart");
+        this.line = this.paper.linechart(
+            xpos,
+            ypos,
+            w,
+            h,
+             ydata ,
+            xdata,
+            {
+                'colors' : colors,
+                'axis' : '0 0 1 1',
+                'symbol' : 'circle',
+                'shade' : '0.2',
+                z : xdata.length -1,
+                axisxlabels : xlabels,
+                axisxstep : xlabels.length -1,
+                axisxorientation : 3,
+                ymin : 0
+                
+            }
+        );
+
+
+        this.line.labels = this.paper.set();
+        
+        Roo.log("Set labels");
+
+        var qtyLbl = this.paper.text(
+                0,
+                (h/2+ypos),
+                'Sales')
+                .attr({
+                    fill : '#000',
+                    'text-anchor' :
+                    'start',
+                    font : '10px Arial',
+                    transform: 'r270'
+                });
+        
+        this.line.labels.push(qtyLbl);
+    /*
+        var timeLbl = dash.paper.text(
+                    ((w/2)+xpos+40),
+                    (h+20+45),
+                    'Date'
+                ).attr({
+                        fill : '#000',
+                        'text-anchor' : 'start',
+                        font : '18px Arial'
+                });
+        
+        this.line.labels.push(timeLbl);
+    */
+        var snum = xdata.length -1;
+        Roo.log("Draw grid labels");
+        this.paper.drawGrid(
+                xpos + 8, //+(snum/2) ,
+                ypos + 8, //+(snum/2)  ,
+                w - 16 ,
+                h  - 16,
+                snum,
+                snum,
+             //   'rgba(192,192,192,0.2)'
+                '#ccc'
+            );
+     //   Roo.log(res.data);
+         
+        
+        //this.templates.perday.overwrite( this.templateEl(),   res  );
+
+        
+    },
+    _template_el : false,
+    templateEl  : function ()
+    {
+        if (this._template_el) {
+            return this._template_el;
+        }
+        
+        var dash = Pman.Tab.XtupleDashboard;
+        this._template_el =  dash.viewPanel.el.createChild( '<div></div' );
+        this._template_el.on('click', this.handleClick, this);
+        return this._template_el ;
+    },
+    handleClick : function(a,b)
+    {
+        Roo.log(a);
+        Roo.log(b);
+        if (typeof(b.href) != 'string') {
+            return true;
+        }
+        var href= b.href.replace(/^[^#]*#/, '');
+        var parts = href.split('-');
+        var _t = this;
+        if ((!parts[0].length) || typeof(_t['handleClick' + parts[0]]) == 'undefined') {
+            Roo.log("No handler for " + parts[0] + ' (' + b.href +')');
+            return true;
+        }
+        Roo.log(parts);
+        var type = parts.shift();
+        _t['handleClick' + type](parts);
+        
+        return true;
+        
+        
+    },
+  
+    handleClickperday: function(parts)
+    {
+        var old = this.state['perday-' + parts[0]] ;
+        this.state['perday-' + parts[0]] = parts[1];
+        if (old == parts[1]) {
+            return;
+            
+        }
+        this.load();
+    },
+    
+    updateStateFromTree : function() {
+        
+        return;
+        
+        var ids = this.tree.getChecked('id');
+        Roo.each([
+                'mediatype'    ,
+                'country'      ,
+                'language'     ,
+            //    'publication' , 
+                 'keywords'     ,
+                'tonality'
+            ],
+            function(i) {
+                this.state[i] = '';
+            },
+            this
+        );
+        
+        Roo.each(ids, function(i) {
+            var ar = i.split('-');
+            var l = ar.shift();
+            var r = ar.join('-');
+            var old = this.state[l].length ? this.state[l].split(',') : [];
+            old.push(r);
+            this.state[l] = old.join(',');
+            
+        }, this);
+        
+    },
+     
+    /*boldSelected: function()
+    {
+        _this = this;
+        Roo.log(this.state);
+        Pman.Clipping.DashboardRender.templateEl().select('a.report-select',true).each(
+            function(e) {
+                //Roo.log(e.dom);
+                var href = e.dom.href.replace(/^[^#]*#/, '');
+                var parts = href.split('-');
+                switch(parts[0]) {
+                    
+                    case 'perday':
+                        var state = _this.state['perday-'+parts[1]];
+                        Roo.log("CHECK " + parts[2] + '?=' + state);
+                        if (parts[2] == state) {
+                            e.addClass('report-selected');
+                        }
+                        break;
+                    
+                      
+                    case 'mediatype':
+                    case 'country':
+                    case 'language':                        
+                        var k = parts.shift();
+                        var v = parts.join('-');
+                        var state = _this.state[k].split(',');
+                        //Roo.log(JSON.stringify(state) + ' ?= ' + parts[1]);
+                        if (state.indexOf(v) > -1) {
+                            e.addClass('report-selected-on');
+                        }
+                        break;
+                     
+                    
+                    default:
+                        Roo.log("no style handler for " + parts[0]);
+                        break;
+                    
+                 
+                }
+                
+                
+            }
+        );
+        
+        
+    },
+    */
+    handleClickdownloadpdf: function(parts)
+    {
+        this.downloadSvg(this.papers[parts[0]],'application/pdf');
+    },
+    handleClickdownload: function(parts)
+    {
+        this.downloadSvg(this.papers[parts[0]],'image/jpeg');
+    },
+    downloadSvg : function(paper, to)
+    {
+        
+        new Pman.Download({
+            method : 'POST',
+            
+            url : baseURL + '/Core/Images',
+            params : {
+                as : to,
+                mimetype  : 'image/svg',
+                data : paper.toSVG() ,
+                width : paper.width * 2  ,
+                height: paper.height * 2 
+                
+            }
+        });
+        
+        
+        
+        
+    },
+    replaceSvgAll: function(acb)
+    {
+        var q = [];
+        for (var i in this.papers) {
+            q.push(i);
+        }
+        var _t = this;
+        var cb = function()
+        {
+            if (!q.length) {
+                if (acb) {
+                    acb();
+                }
+                return;
+            }
+            var p = q.pop();
+            
+            _t.replaceSvg(_t.papers[p], p, cb);
+            
+            
+        }
+        
+        cb();
+    },
+     
+     
+    replaceSvg: function(paper ,view, cb )
+    {
+        var _t = this;
+        new Pman.Request({
+            method : 'POST',
+            
+            url : baseURL + '/Core/Images',
+            params : {
+                as : 'image/jpeg',
+                mimetype  : 'image/svg',
+                data : paper.toSVG(),
+                as_data : 1,
+                width : paper.width ,
+                height: paper.height 
+            },
+            success: function(data){
+                //Roo.log(data);
+                var g = Roo.get(_t.clonedBase).select('.report-graph-' + view, true).first();
+                if (g) {
+                    g.dom.innerHTML = '<img src="' + 'data:image/jpeg;base64,' +data.data + '">';
+                }
+                if (cb) {
+                    cb();
+                }
+                
+            }
+        });
+        
+        
+        
+        
+    },
+    
+    clonedBase : false,
+    
+    downloadDoc : function()
+    { 
+    
+        var _t = this;
+        Roo.MessageBox.alert("Notice", "Creating Graphs");
+        
+        var tp = _t.templateEl();
+           
+        // copy and rmeove stufff.
+        var cp = document.importNode(tp.dom,true);
+        
+        
+        cp.removeAttribute('id');
+        this.clonedBase= cp;
+        // remove the top level style..
+        Roo.get(cp).select('style',true).remove();
+        
+        // remove hidden stuff..
+        
+        Roo.get(cp).select('.report-no-print',true).remove();
+        
+        //this.printReplace(cp); -- this does not appear to work.
+        //Roo.log(cp);
+        
+        this.replaceSvgAll(function() {
+            
+          
+            //Roo.log(cp.innerHTML);
+           
+           
+            var html = '<HTML>' +
+                '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' +
+                '<BODY><div style="font-family:sans-serif;font-size:10pt">' + cp.innerHTML + '</div></BODY></HTML>';
+           
+            new Pman.Download({
+                method : 'POST',
+                
+                url : baseURL + '/Core/Images',
+                params : {
+                   // as : 'application/msword',
+                    as : 'application/rtf',
+                    mimetype  : 'text/html',
+                    data : html
+                    
+                }
+                
+            });
+            
+            Roo.MessageBox.alert("Notice", "Download will start shortly");
+            
+            
+        });
+        /// downloading dialog.?
+    
+    },
+    
+    
+    printReplace : function(cp)
+    {
+        Roo.log('print replace');
+        var st = document.styleSheets;
+        Roo.log('n sheets' + st.length);
+        
+        for (var i = 0;i < st.length; i++) {
+            try {
+                Roo.log(st[i].media[0] );
+                if (st[i].media[0] != 'print') {
+                    continue;
+                }
+            } catch(e) {
+                Roo.log(e);
+                continue;
+            }
+            var rules = st[i].rules; // or cssRules?
+            
+            for (var j = 0; j < rules.length; j++) {
+                var rule = rules[j];
+                var sel = rule.selectorText;
+                var val = rule.style.cssText;
+                Roo.log("SEL : "+ sel + " => " + val);
+                
+                Roo.get(cp).select(sel,true).each(function(el) {
+                    el.dom.setAttribute('style',  val);
+                    
+                });
+                
+                
+                
+            }
+            
+            
+        }
+        
+        
+    } /*,
+    
+    
+    showFilters : function()
+    {
+      
+        // build filters from array
+        
+        while( this.treeroot.firstChild){
+            this.treeroot.removeChild( this.treeroot.firstChild);
+        }
+        //this.treeroot = this.tree.getRootNode();
+        this.treeroot.childrenRendered = true;
+        
+        
+        var filters = [];
+        for (var box in this.filterCfg.titles) {
+            
+            
+            
+            
+            
+            var filter = {
+                name : this.filterCfg.titles[box],
+                options : []
+            };
+            if (!this.data[box]) {
+                continue;
+            }
+            var gnode = false;
+            if (box != 'keywords') {
+                Roo.log("Add to root");
+                
+                gnode = this.treeroot.appendChild( new Roo.tree.TreeNode({
+                    id : 'box',
+                    text : this.filterCfg.titles[box],
+                    is_leaf : false,
+                    expanded: true
+                }));
+            }    
+            
+            var kword_ar = [];
+            var kword_nodes = {};
+            Roo.each(this.data[box], function(e) {
+                
+                
+                
+                
+                if (box == 'keywords') {
+                    if (typeof(kword_nodes[e.parent_id]) == 'undefined') {
+                        
+                        kword_nodes[e.parent_id] = this.treeroot.appendChild(new Roo.tree.TreeNode({
+                            text: e.parent_id_keyword ,
+                            id : box +'-'+ e.parent_id,
+                            is_leaf : false,
+                            checked : this.state[box].split(',').indexOf(e.parent_id) > -1 ? true : false,
+                            expanded: true
+                        }));
+                        
+                    }
+                    kword_nodes[e.parent_id].appendChild(new Roo.tree.TreeNode({
+                        text: e.rkey + ' (' + e.rvalue + ')',
+                        id : box +'-'+ e.rkid,
+                        is_leaf : true,
+                        checked : this.state[box].split(',').indexOf(e.rkid) > -1 ? true : false
+                    }));
+                    
+                    
+                    // need to add child data on?
+                    return;  
+                }
+                
+                filter.options.push({
+                    text: (e.rkey && e.rkey.length ? e.rkey : (e.rkid  +' (Untitled)'))   + '(' + e.rvalue + ')',
+                    id : box +'-'+ e.rkid,
+                    is_leaf : true,
+                    checked : this.state[box].split(',').indexOf(e.rkid) > -1 ?  true : false
+                });
+               
+                
+            }, this);
+            
+            
+            
+            filter.options.sort( function(r1, r2){
+                var st = Roo.data.SortTypes.asUCString;
+                var v1 = st(r1.text), v2 = st(r2.text);
+                return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+            });
+            Roo.each(filter.options, function (n) {
+                
+                gnode.appendChild(new Roo.tree.TreeNode( n));
+                
+            });
+            
+            
+            filters.push(filter);
+            
+        }
+        
+        
+        
+        
+        
+        
+        //this.templates.filters.overwrite(
+        //    this.templateEl().select('.report-filters', true).first(),
+        //    { filters : filters }
+        //);
+       
+        
+        
+    }
+    */
+};
+// load all the templates.
+for (var i in Pman.Xtuple.DashboardRender.templates) {
+     Pman.Xtuple.DashboardRender.templates[i] =  new Roo.DomTemplate({
+                url : rootURL + '/Pman/Xtuple/domtemplates/' + i +'.html'
+                 
+        });
+}
+
+
+
diff --git a/Pman.Xtuple.js b/Pman.Xtuple.js
new file mode 100644 (file)
index 0000000..7b37e12
--- /dev/null
@@ -0,0 +1,66 @@
+
+
+
+
+Pman.on('load', function() {Pman.Xtuple.load(); } );
+
+Pman.Xtuple  = {
+    
+    offices : {
+        'hk' : 'Hong Kong',
+        'sg' : 'Singapore',
+        'my' : 'Malaysia',
+        'cn' : 'China',
+        'au' : 'Australia',
+        'zh' : 'China(Retail)'
+        
+        
+    },
+    
+    
+    load : function()
+    {
+            
+        if (typeof(Pman.Login) == 'undefined') {
+            return;
+        }
+        var logoel = Roo.get('headerInformation-company-logo');
+        
+        if (logoel && logoel.dom.parentNode) {
+            var div = document.createElement('span');
+            logoel.dom.parentNode.replaceChild( div,logoel.dom);
+            div = Roo.get(div);
+            
+            var db = baseURL.split('.php').shift().substr(-2,2);
+            
+            //var pstr = - switch to ";
+            var pstr = '';
+            for (var k in this.offices) {
+                if (k == db) {
+                    continue;
+                }
+                if (uiConfig.xtuple_offices.indexOf(k) < 0) {
+                    continue;
+                }
+                
+                
+                pstr += ' : <a style="color:#999;" target="_blank" href="' + rootURL + '/' + k + '.php">' + this.offices[k] + '</a>';
+            }
+            var str = '<span style="font-family:arial;"><b>' + "Dragon" + '</B> - <b style="color:blue;">' + this.offices[db] + "</b> " +
+                (pstr.length ? ("- switch to " + pstr) : '');
+             
+             
+            div.update( str) ;
+        }
+        
+        if(baseURL.match('/sandbox/')){
+            Roo.get('title').dom.style.backgroundColor = 'pink';
+        }
+    
+         
+        
+        
+    }
+    
+    
+}
diff --git a/Pman.php b/Pman.php
new file mode 100644 (file)
index 0000000..e07aecb
--- /dev/null
+++ b/Pman.php
@@ -0,0 +1,41 @@
+<?php
+
+
+class Pman_Xtuple_Pman extends Pman {
+    
+    
+    function getAuth() {
+        $this->jerr("access denied");
+    }
+    
+    function init($pman)
+    {   
+        // add the offices to the uiConfig.
+        if (empty($pman->uiConfig)) {
+            $pman->uiConfig = array();
+        }
+        
+        // scan the root directory for xx.php
+        foreach(scandir($pman->rootDir) as $fn) {
+            if (!is_file($pman->rootDir.'/'.$fn)) {
+                continue;
+            }
+            if (!preg_match('/^[a-z]{2}\.php$/',$fn)) {
+                continue;
+            }
+            $offices[] = preg_replace('/\.php$/', '', $fn);
+            
+            
+        };
+        $pman->uiConfig['xtuple_offices'] = $offices;
+        
+        // add the default config..
+        if(!empty($pman->bootLoader->uiConfig)){
+            foreach ($pman->bootLoader->uiConfig as $k => $v){
+                $pman->uiConfig[$k] = $v;
+            }
+        }
+        
+    }
+    
+}
diff --git a/Pricing.php b/Pricing.php
new file mode 100644 (file)
index 0000000..00a0828
--- /dev/null
@@ -0,0 +1,166 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+class Pman_Xtuple_Pricing extends Pman_Roo
+{
+    
+    /**
+     *  get .. same as roo... 
+     * 
+     */
+    
+    function get()
+    {
+        
+         PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        //DB_DataObject::DebugLevel(1);
+        require_once 'File/Convert.php';
+        $fc = new File_Convert('/tmp/pricelist2012-07-20.xls', 'application/vnd.ms-excel');
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        $this->importCsv($csv);
+    }
+    
+    
+    function post( )
+    {
+        
+                PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+
+        
+        $img = DB_DataObject::Factory('images');
+        $img->setFrom(array(
+            'onid' => 0,
+            'ontable' => 'ipshead'
+        ));
+        $img->onUpload(false);
+        
+        require_once 'File/Convert.php';
+        $fc = new File_Convert($img->getStoreName(), $img->mimetype );
+        //var_Dump($img->getStoreName());
+        $csv = $fc->convert('text/csv');
+        //print_R($fc);exit;
+        //var_dump($csv);exit;
+        $this->importCsv($csv);
+    }
+    function importCsv($csv)
+    {
+        ini_set("auto_detect_line_endings", true);
+
+        $fh = fopen($csv, 'r');
+        
+        $bom = "\xEF\xBB\xBF";
+        for ($i = 0; $i< 3;$i++) {
+            if ($bom[$i] != fgetc($fh)) {
+                fseek($fh,0);
+                break;
+            }
+            
+        }
+        
+        // we need to break this into cols..
+        $cols = array();
+        $names = fgetcsv($fh);
+        $curr = fgetcsv($fh);
+        
+       
+        
+        $plist = array();
+        foreach($names as $i=>$n) {
+            if (!strlen(trim($n))) { // skip the empty columsn
+                continue;
+            }
+            
+            
+            $plist[$i] = array(
+                'curr' => $curr[$i],
+                'name' => $n,
+                'prices' => array()
+            );
+            
+            
+        }
+        
+        $skucol = 0;
+        
+        
+        if (!strlen(trim($names[1])) && $curr[1] == 'item_number') {
+            $skucol = 1;
+        }
+    
+        $allsku = array();
+        
+        while (false !== ($row = fgetcsv($fh))) {
+            $sku = $row[$skucol]; // if first column is brand..
+            
+            
+            $allsku[$sku] = 1;
+            for ($i = $skucol+1; $i  < count($row); $i++) {
+                $plist[$i]['prices'][$sku] = $row[$i];
+            }
+            
+        }
+        fclose($fh);
+        // grab all the sku's... nice and emmeor
+        
+        //print_R($plist);exit;
+        
+        $it = DB_DataObject::Factory('item');
+        $imap = $it->fetchAll('item_number','item_id');
+        
+        foreach($allsku as $sku => $n) {
+            if (empty($imap[$sku])) {
+                $this->jerr("invalid sku in upload:" . $sku);
+            }
+            
+        }
+        
+        foreach($plist as $nn => $data) {
+            $ih = DB_DataObject::Factory('ipshead');
+            $ih->selectAdd('(SELECT curr_name   FROM curr_symbol where curr_id = ipshead_curr_id LIMIT 1) AS ipshead_curr');
+            $ih->ipshead_name = $data['name'];
+            
+            if (!$ih->find(true)) {
+                $this->jerr('unknown pricelist column('. $nn .')'. @$data['name'] );
+            }
+            
+            if ($ih->ipshead_curr != $data['curr']) {
+               //  var_Dump($data['curr']);
+                $this->jerr("currency on pricelist {$data['name']} can not be changed from {$ih->ipshead_curr}  to {$data['curr']}");
+            }
+            $plist[$nn]['ipshead'] = $ih;
+            
+        }
+        $ret = array('updated'=>0, 'inserted'=>0,'deleted'=>0);
+        foreach($plist as $nn => $data) {
+            $res = $data['ipshead']->updatePrices($data['prices'],$imap);
+            $ret['deleted'] += $res['deleted'];
+            $ret['inserted'] += $res['inserted'];
+            $ret['updated'] += $res['updated'];
+        }
+        $this->jok($ret);
+        
+        
+        
+        
+        
+        
+        
+        
+        print_R($plist);
+        
+        
+        
+        
+        exit;
+        
+        
+        
+        
+    
+    }
+    
+}
diff --git a/Print.php b/Print.php
new file mode 100644 (file)
index 0000000..3ebd957
--- /dev/null
+++ b/Print.php
@@ -0,0 +1,242 @@
+<?php
+
+
+require_once 'Pman.php';
+
+class Pman_Xtuple_Print extends Pman
+{
+    function getAuth()
+    {
+        parent::getAuth();
+        $au = $this->getAuthUser();
+        if (!$au) {
+            $this->jerr("access denied");
+        }
+        
+    }
+    
+    
+    function get()
+    {
+        // accept
+        // param : 
+        // template
+        // filemanem
+        
+        $args = array(
+            'template' => $_REQUEST['template']
+        );
+        if (isset($_REQUEST['param'])) {
+            $args['param'] =  $_REQUEST['param'];
+        }
+        $this->toPdf($args, $_REQUEST['filename']);
+         
+    }
+    
+    /**
+     * run rptrender and output the file..
+     *
+     * @param array $cfg configuration - param=> ... => loadfromdb=>
+     * @param filename
+     * 
+     */
+    
+    function toPdf($cfg, $name)
+    {
+        if (isset($cfg['template'])) {
+            $cfg['template'] = rtrim($cfg['template'],'-');
+        }
+        $ocfg = $cfg;
+        
+        $do = DB_DataObject::Factory('invchead');
+        
+        $dsn  = $do->getDatabaseConnection()->dsn;
+        
+        $office = substr($do->database(),-2);
+        
+
+        $fn = tempnam(sys_get_temp_dir(),'print').'.pdf';
+        
+        $args = array(
+            'databaseURL'=> 'psql://' . $dsn["hostspec"] .'/'. $dsn["database"] .':5432',
+            'username' =>  $dsn["username"],
+            'passwd' => $dsn["password"],
+            'pdf' => true,
+            'outpdf' => $fn,
+            
+            
+            //'param' => "invchead_id:integer='{$this->invchead_id}'",
+            //'loadfromdb' => 'Invoice',
+            'close' => true
+        );
+         /*
+        $template  = '';
+        if (isset($cfg['template'])) {
+            $template = realpath(dirname(__FILE__).'/report_templates'). '/'.$cfg['template']. '.xml';
+            unset($cfg['template']);
+        }
+        // do we have a localized version???
+        $template_test = preg_replace('/\.xml$/', '-'.$office .'.xml', $template);
+       //$this->jerr($template_test);
+        if (file_exists($template_test)) {
+            $template = $template_test; 
+        }
+        if (!file_exists($template)) {
+            
+            // see if exists in the database..
+            $r = DB_DAtaObject::factory('report');
+            
+            
+            if (!$r->get('report_name', $ocfg['template'])) {
+                $this->jerr("No template '{$ocfg['template']}' exists or $template or $template_test", array(), 'text/plain');
+            }
+            
+            
+            $args['loadfromdb'] = escapeshellarg($ocfg['template']);
+            $template = '';
+            
+        }
+        */
+         
+        $args['loadfromdb'] = escapeshellarg($this->syncDB($cfg));
+        unset($cfg['template']);
+        // -loadfromdb={report_name}
+        
+        $args = array_merge($cfg,$args);
+        
+        $cmd = array();
+        require_once 'System.php';
+        $xvfb = System::which('xvfb-run');
+        if (!$xvfb ) {
+            $this->jerr("no xvfb-run found", array(), 'text/plain');
+        }
+        
+        
+        $rpt = System::which('rptrender');
+        if (!$rpt) {
+            $this->jerr("no report renderer", array(), 'text/plain');
+        }
+        $cmd[] = "$xvfb --auto-servernum";
+
+        
+        
+        $cmd[] = $rpt;
+
+        foreach($args as $k=>$v) {
+            if (is_array($v)) {
+                foreach($v as $vv) {
+                    $cmd[] = '-'.$k . ($vv === true   ? '' : '='. $vv);
+                }
+                continue;
+            }
+            $cmd[] = '-'.$k . ($v === true   ? '' : '='. $v);
+            
+        }
+        $cmd = implode(' ', $cmd) ;
+        //$cmd = implode(' ', $cmd) . ' ' . (strlen($ocfg['template']) ? escapeshellarg($template) : '');
+        if (isseT($_REQUEST['_debug'])) {
+            echo $cmd;
+            exit;
+        }
+        
+       // echo $cmd;exit;
+        $res = `$cmd`;
+        // var_dump( $res);
+        
+        if (!file_exists($fn)) {
+            $this->jerr("File creation failed:  " . $cmd, array(), 'text/plain');
+        }
+        
+        require_once 'File/Convert.php';
+        $x = new File_Convert($fn,  "application/pdf");
+        $x->convert("application/pdf");
+        $x->serve('attachment', $name .'.pdf', true); // delte after...
+        exit;
+        
+    }
+    function syncDB($cfg) {
+        
+        $do = DB_DataObject::Factory('invchead');
+        
+        $office = substr($do->database(),-2);
+       
+        
+        $ocfg = $cfg;
+        $template  = '';
+        if (isset($cfg['template'])) {
+            $template = realpath(dirname(__FILE__).'/report_templates'). '/'.$cfg['template']. '.xml';
+            unset($cfg['template']);
+        }
+        // do we have a localized version???
+        $template_test = preg_replace('/\.xml$/', '-'.$office .'.xml', $template);
+       //$this->jerr($template_test);
+        if (file_exists($template_test)) {
+            $template = $template_test; 
+        }
+        
+        // template now == full path with .xml at the end..
+        
+        
+        
+        if (!file_exists($template)) {
+            
+            // see if exists in the database..
+            $r = DB_DAtaObject::factory('report');
+            
+            
+            if (!$r->get('report_name', $ocfg['template'])) {
+                $this->jerr("No template '{$ocfg['template']}' exists or $template or $template_test", array(), 'text/plain');
+            }
+            
+            return $ocfg['template'];
+            
+            
+        }
+        
+        
+        // we have a file, and we need to sync it with database.
+        
+        $mt = filemtime($template);
+        
+        $r = DB_DAtaObject::factory('report');
+            
+            
+        if (!$r->get('report_name', $ocfg['template'])) {
+            // insert one..
+            $r = DB_DAtaObject::factory('report');
+            $r->setFrom(array(
+                
+                'report_name' => $ocfg['template'],
+                
+                'report_source' => file_get_contents($template),
+                
+                'report_grade' => 0,
+                'report_loaddate' => date('Y-m-d H:i:s', $mt)
+            ));
+            $r->insert();
+            return $ocfg['template'];
+        } 
+        // see if it needs updating..
+        if (strtotime($r->report_loaddate) < $mt) {
+            $r->setFrom(array(
+                
+                 'report_source' => file_get_contents($template),
+                
+                
+                'report_loaddate' => date('Y-m-d H:i:s', $mt)
+            ));
+            $r->update();
+            
+            return $ocfg['template'];
+            
+            
+        }
+        // system is newer than ours..
+            
+        return $ocfg['template'];
+         
+        
+        
+    }
+    
+}
diff --git a/Reports/AccountCheckEmail.php b/Reports/AccountCheckEmail.php
new file mode 100644 (file)
index 0000000..5e0fe16
--- /dev/null
@@ -0,0 +1,515 @@
+<?php
+require_once 'Pman.php';
+
+
+class Pman_Xtuple_Reports_AccountCheckEmail extends Pman
+{
+    static $cli_desc = "Email a summary of what the account status is";
+    
+    static $cli_opts = array(
+        'send-to' => array(
+            'desc' => 'Send the message to this address',
+            'default' => '',
+            'short' => 't',
+            'min' => 0,
+            'max' => 1,
+        )
+    );
+    
+    function getAuth()
+    {
+        $ff = HTML_FlexyFramework::get();
+        if (!$ff->cli) {
+            die("access denied");
+        }
+        //HTML_FlexyFramework::ensureSingle(__FILE__, $this);
+        return true;
+        
+    }
+   
+    function get($id,$opts)
+    {
+        if(empty($opts['send-to'])){
+            $this->jerr("Missing send to information, try -t [email]");
+        }
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+   
+        require_once 'Pman/Core/Mailer.php';
+        
+        $template = 'AccountCheckEmail';
+        
+        $random_hash = md5(date('r', time()));
+        
+        // build the message
+        
+        $message = new stdClass();
+        
+        $do = DB_DataObject::factory('core_enum');
+        $db = strtoupper(substr($do->database(),-2));
+        
+        $message->subject = "[Report - {$db}] Dragon data summary";
+        
+        $message->baseCurr = DB_DataObject::factory('curr_symbol')->base()->curr_name;
+        
+        
+        //print_r($this->neverBought()); exit;
+        
+        
+        
+        $message->stock = $this->stockCheck();
+
+        
+        $message->aropen = $this->aropenCheck();
+        $message->apopen = $this->apopenCheck();
+        $message->highProfit = $this->profitCheck('DESC', false);
+        $message->zeroProfit = $this->profitCheck('ASC', true);
+        $message->lowProfit = $this->profitCheck('ASC', false);
+        $message->landedCost = $this->landedcostCheck();
+        $message->neverBought = $this->neverBought();
+        $message->fifoCohead = $this->fifoCohead();
+        $message->fifoVoidCheck = $this->fifoVoidCheck();
+        
+        
+        
+        
+        $r = new Pman_Core_Mailer(array(
+            'template'=> $template,
+            'page' => $this,
+            'contents' => array(
+                'random_hash' => $random_hash,
+                'person' => $opts['send-to'],
+                'data' => $message,
+                'date' => date('Y-m-d')
+            )
+        ));
+        
+        $sent = $r->send();
+        
+        if(!is_object($sent)){
+            $this->jok('SUCCESS');
+        }
+        $this->jerr('error!!:' . $sent->toString());
+    }
+    
+    function aropenCheck()
+    {
+        $result = array();
+        
+        
+        // customer depostist (124, or 296?)
+        
+        
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->accnt_descrip = 'Customer Deposits';
+        if(!$accnt->find(true)){
+            $this->jerr("Missing Customer Deposits Account");
+        }
+        
+        $araccnt = DB_DataObject::factory('araccnt');
+        $araccnt->araccnt_custtype = '.*';
+        if(!$araccnt->find(true)){
+            $this->jerr("Missing araccnt");
+        }
+        
+        $araging = DB_DataObject::factory('aropen');
+        $araging->selectAdd();
+        $araging->query("
+                            SELECT
+                                    ROUND(SUM(COALESCE(araging_total_val ,0)),2) AS araging_total_val
+                            FROM
+                                    araging(current_date,true)
+                        ");
+        $araging->fetch();
+        $result['araging_total_val'] = number_format($araging->araging_total_val, 2);
+        
+        $gltrans = DB_DataObject::factory('gltrans');
+        $gltrans->selectAdd();
+        $gltrans->selectAdd("
+            ROUND(SUM(COALESCE(gltrans_amount * -1.0,0)),2) AS gltrans_total_val
+        ");
+        $gltrans->whereAdd("
+            gltrans_date <= current_date
+            AND
+            gltrans_accnt_id IN ({$araccnt->araccnt_deferred_accnt_id},{$araccnt->araccnt_ar_accnt_id})
+            AND
+            gltrans_posted
+            AND
+            NOT gltrans_deleted
+        ");
+        $gltrans->find(true);
+        $result['gltrans_total_val'] = number_format($gltrans->gltrans_total_val, 2);
+        
+        $result['ar_diff'] = number_format($gltrans->gltrans_total_val - $araging->araging_total_val, 2);
+        
+        return (object)$result;
+        
+    }
+    
+    function apopenCheck()
+    {
+        $result = array();
+        
+        $apaccnt = DB_DataObject::factory('apaccnt');
+        $apaccnt->apaccnt_custtype = '.*';
+        if(!$apaccnt->find(true)){
+            $this->jerr("Missing apaccnt");
+        }
+        
+        $apaging = DB_DataObject::factory('apopen');
+        $apaging->selectAdd();
+        $apaging->query("
+                            SELECT
+                                    ROUND(SUM(COALESCE(apaging_total_val * -1.0,0)),2) AS apaging_total_val
+                            FROM
+                                    apaging(current_date,true)
+                        ");
+        $apaging->fetch();
+        $result['apaging_total_val'] = number_format($apaging->apaging_total_val, 2);
+        
+        $gltrans = DB_DataObject::factory('gltrans');
+        $gltrans->selectAdd();
+        $gltrans->selectAdd("
+            ROUND(SUM(COALESCE(gltrans_amount * -1.0,0)),2) AS gltrans_total_val
+        ");
+        $gltrans->whereAdd("
+            gltrans_date <= current_date
+            AND
+            gltrans_accnt_id = {$apaccnt->apaccnt_ap_accnt_id}
+            AND
+            gltrans_posted
+            AND
+            NOT gltrans_deleted
+        ");
+        $gltrans->find(true);
+        $result['gltrans_total_val'] = number_format($gltrans->gltrans_total_val, 2);
+        
+        $result['ap_diff'] = number_format($gltrans->gltrans_total_val - $apaging->apaging_total_val, 2);
+        
+        return (object)$result;
+        
+    }
+    
+    function stockCheck()
+    {
+        $result = array();
+        
+        $costcat = DB_DataObject::factory('costcat');
+        if(!$costcat->find(true)){
+            $this->jerr("Missing Costcat");
+        }
+        
+        //DB_DataObject::debugLevel(1);
+        $location = DB_DataObject::factory('location');
+        
+        $db = substr($location->database(),-2);
+        
+        $location->selectAdd();
+        $location->selectAdd("
+            ROUND(SUM(COALESCE(invcost_location_atdate(current_date - INTERVAL '2 DAY', location_id),0)),2) AS stock_total_val
+        ");
+        $location->whereAdd("
+                (SELECT charass_getvalue('C', location_cust_id  ,'INTERNALCOMPANY'))  IN ('', '{$db}')
+            AND
+                location_restrict = false
+        ");
+        $location->find(true);
+        $result['stock_total_val'] = number_format($location->stock_total_val, 2);
+        //exit;
+        $gltrans = DB_DataObject::factory('gltrans');
+        $gltrans->selectAdd();
+        $gltrans->selectAdd("
+            ROUND(SUM(COALESCE(gltrans_amount * -1.0,0)),2) AS gltrans_total_val
+        ");
+        $gltrans->whereAdd("
+            gltrans_date <= current_date - INTERVAL '2 DAY'
+            AND
+            gltrans_accnt_id = {$costcat->costcat_asset_accnt_id}
+            AND
+            gltrans_posted
+            AND
+            NOT gltrans_deleted
+        ");
+        $gltrans->find(true);
+        
+        $result['gltrans_total_val'] = number_format($gltrans->gltrans_total_val, 2);
+        
+        $result['stock_diff'] = number_format($gltrans->gltrans_total_val - $location->stock_total_val, 2);
+        
+        return (object)$result;
+        
+    }
+    
+    function profitCheck($code = 'ASC', $zero = true)
+    {
+        
+        
+        $where = ($zero) ? 'sale_value = 0' : 'sale_value != 0';
+        
+        $from = date('Y-m-d', strtotime("-3 month"));
+        $to = date('Y-m-d',strtotime("-2 days")) ;
+        
+        $meta = DB_DAtaObject::Factory('metasql');
+        $queryinfo = $meta->buildReportQuery(array(
+                '_group' => 'invhist',
+                '_name' => 'summary',
+                'from_dt:text' => $from,
+                'to_dt:text' => $to
+                ),$this);
+        
+        $query = $queryinfo['query'];
+        
+        $query = "SELECT 
+                        invhist_fullordernumber AS docnumber,
+                        ROUND(COALESCE(sale_value,0),2) AS sale_value,
+                        ROUND(COALESCE(sale_cost * -1.0,0),2) AS sale_cost,
+                        CASE WHEN
+                                sale_value  = 0.0
+                            THEN
+                                ROUND(COALESCE(sale_cost ,0),2)
+                            ELSE 
+                                ROUND((((sale_value - (sale_cost* -1.0)) / (sale_cost* -1.0)) * 100),2)
+                            END AS
+                                profit
+                                
+                  FROM 
+                        ($query) mquery 
+                  WHERE
+                        -- it suppose will not happen, but just in case...
+                        -- but this does???
+                        sale_cost != 0
+                    AND
+                        {$where}
+                  ORDER BY 
+                        profit {$code}
+                  LIMIT 20
+                  ";
+        
+        $meta = DB_DAtaObject::Factory('metasql');
+        $meta->query("$query");
+        
+        $result = array();
+        while ($meta->fetch()){
+            $result[] = clone($meta);
+        }
+        
+        return $result;
+    }
+    
+    function landedcostCheck()
+    {
+        $pohead = DB_DataObject::factory('pohead');
+        $pohead->selectAdd();
+        $pohead->query("
+            SELECT
+                    pohead_id,
+                    pohead_orderdate,
+                    pohead_number,
+                    COALESCE(pohead_val,0) AS pohead_val,
+                    COALESCE(landed_cost,0) AS landed_cost,
+                    ROUND(((COALESCE(landed_cost,0) / pohead_val) * 100),2) AS expense,
+                    array_to_string(array(
+                            SELECT 
+                                    vohead_number
+                                FROM
+                                    recvgrpland
+                                LEFT JOIN
+                                    vohead
+                                ON
+                                    recvgrpland_vohead_id = vohead_id
+                                LEFT JOIN
+                                    recvgrp
+                                ON
+                                    recvgrpland_recvgrp_id = recvgrp_id
+                                WHERE
+                                    recvgrp_pohead_id = pohead_id
+                                
+                                
+                        ), ', '
+                    
+                    ) as voucher_numbers
+                    
+                    
+            FROM
+                    (
+                        SELECT
+                                pohead_id,
+                                pohead_orderdate,
+                                pohead_number,
+            
+                                (
+                                    SELECT 
+                                            ROUND(SUM(COALESCE(currtobase(pohead_curr_id, poitem_unitprice * poitem_qty_ordered, pohead_orderdate::date),0)),2)
+                                    FROM 
+                                            poitem 
+                                    WHERE 
+                                            poitem_pohead_id = pohead_id
+                                ) AS pohead_val,
+
+                                (
+                                    SELECT
+                                        ROUND(SUM(COALESCE(currtobase(recvgrpland_curr_id,recvgrpland_cost, gltrans_date::date),0)),2)
+                                    FROM
+                                        recvgrpland
+                                    LEFT JOIN
+                                        gltrans
+                                    ON
+                                        gltrans_sequence = recvgrpland_glseries
+                                        AND
+                                        gltrans_amount > 0
+                                    LEFT JOIN
+                                        recvgrp
+                                    ON
+                                        recvgrpland_recvgrp_id = recvgrp_id
+                                    WHERE
+                                        recvgrp_pohead_id = pohead_id
+
+                                ) AS landed_cost
+                        FROM
+                                pohead
+                            WHERE
+                                 pohead_orderdate > NOW() - INTERVAL '1 YEAR'
+                    ) x
+            WHERE
+                    -- it suppose will not happen, but just in case...
+                    pohead_val != 0
+            ORDER BY 
+                    expense DESC
+            LIMIT 10
+        ");
+        
+        $result = array();
+        while ($pohead->fetch()){
+            $result[] = clone($pohead);
+        }
+        
+        return $result;
+        
+    }
+    
+    function neverBought()
+    {
+        ///DB_DataObject::debugLevel(1);
+        $invcitem = DB_DataObject::factory('invcitem');
+        $invcitem->autoJoin();
+        $invcitem->selectAdd();
+        $invcitem->selectAdd("
+            DISTINCT(itemsite_id) AS itemsite_id
+        ");
+        $invcitem->_join .= "
+            LEFT JOIN
+                    itemsite
+            ON
+                    itemsite_item_id = invcitem_item_id
+        ";
+        $invcitem->whereAdd("
+            join_invcitem_invchead_id_invchead_id.invchead_invcdate >= current_date - INTERVAL '1 MONTH'
+        ");
+        $invcitems = $invcitem->fetchAll('itemsite_id');
+        
+        $coitem = DB_DataObject::factory('coitem');
+        $coitem->autoJoin();
+        $coitem->selectAdd();
+        $coitem->selectAdd("
+            DISTINCT(coitem_itemsite_id) AS coitem_itemsite_id
+        ");
+        $coitem->whereAdd("
+            join_coitem_cohead_id_cohead_id.cohead_orderdate >= current_date - INTERVAL '1 MONTH'
+        ");
+        $coitems = $coitem->fetchAll('coitem_itemsite_id');
+
+        $sold = array_unique(array_merge($invcitems, $coitems)); // have been sold!
+        
+        $recv = DB_DataObject::factory('recv');
+        $recv->selectAdd();
+        $recv->selectAdd("
+            DISTINCT(recv_itemsite_id) AS recv_itemsite_id
+        ");
+        $bought = $recv->fetchAll('recv_itemsite_id');
+        
+        $err = array_diff($sold, $bought);
+        
+        //DB_DataObject::debugLevel(1);
+        
+        
+        $itemsite = DB_DataObject::factory('itemsite');
+        $itemsite->autoJoin();
+        $itemsite->selectAdd();
+        $itemsite->selectAdd("
+            join_itemsite_item_id_item_id.item_number AS item_number,
+            array_to_string(array(SELECT
+                distinct(cohead_number)
+                FROM
+                    coitem
+                LEFT JOIN
+                    cohead
+                ON
+                    coitem_cohead_id = cohead_id
+                WHERE
+                    coitem_itemsite_id = itemsite_id
+                ), ', ') as order_numbers
+            
+        ");
+        $itemsite->whereAddIn('itemsite_id', $err, 'int');
+        $itemsite->whereAdd("
+            join_itemsite_item_id_item_id.item_type = 'P'
+        ");
+        $itemsite->orderBy('item_number ASC');
+        $result = $itemsite->fetchAll();
+        
+        return $result;
+    }
+    
+    function fifoCohead()
+    {
+        //DB_DataObject::debugLevel(1);
+        $c = DB_DataObject::factory('cohead');
+        $c->autoJoin();
+        $c->applyFilters(array(
+            'viewtype'=>'FIFOBUG',
+            ),
+            $this->authUser,
+            $this
+         
+        );
+        $c->orderBy('cohead_orderdate DESC');
+      
+        $ret = $c->fetchAll();
+        //exit;
+        return $ret;
+        
+        
+    }
+    
+    function fifoVoidCheck()
+    {
+    
+        $c = DB_DataObject::factory('cohead');
+        $c->query( " 
+            SELECT item_number, stock_with_void, stock_all FROM
+                (select
+                        item_number,
+                        ROUND(COALESCE(sum(CASE WHEN invfifo_void =0 THEN invdetail_qty ELSE 0 END),0.0)) as stock_with_void ,
+                        ROUND(COALESCE(sum(invdetail_qty),0.0),0) as stock_all
+                    from
+                        invdetailview
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        invhist_itemsite_id = itemsite_id
+                    LEFT JOIN
+                        item
+                    ON
+                        item_id = itemsite_item_id
+                    GROUP BY
+                        item_number
+                ) x
+            WHERE
+                stock_all != stock_with_void
+            ");
+        $ret = array();
+        while ($c->fetch()) {
+            $ret[] = clone($c);
+        }
+        return $ret;
+    }
+}
\ No newline at end of file
diff --git a/Reports/Base.php b/Reports/Base.php
new file mode 100644 (file)
index 0000000..14f99f9
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+require_once 'Pman/Roo.php';
+class Pman_Xtuple_Reports_Base extends Pman_Roo
+{
+    
+    function getAuth()
+    {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
+        return parent::getAuth();
+    }
+            
+    
+    function get()
+    {
+        $this->jerr("not implemented");
+        
+    }
+    function post ()
+    {
+        $this->jerr("not implemented");   
+    }
+    // is this still used?
+    
+    function toCsv($q, $head)
+    {
+        return parent::toCsv($q,$head,'*','');
+    }
+/*
+        if (!is_array($q)) {
+            $qq = array();
+            while ($q->fetch()) {
+                $qq[] = $q->toArray('%s', true);
+                
+            }
+            $q = $qq;
+        }
+        if (empty($head)) {
+            $head = empty($q) ? array() : array_keys($q[0]);
+        }
+        $titles = array();
+        foreach($head as $h) {
+            if (preg_match('/_xt[a-z]+role$/i', $h)) {
+                $col = preg_replace('/_xt[a-z]+role$/i', '', $h);
+              //  $titles[$col] = $q[0][$h];
+                continue;
+            }
+            $titles[$h] = $h;
+        }
+        $head = array_keys($titles);
+        $titles =array_values($titles);
+        
+        
+        
+        $fn = array_pop(explode('_',get_class($this))) . '-report-';
+        header('Content-type: text/csv');
+        header('Content-Disposition: attachment; filename="'.$fn.date('Y-m-d') . '.csv"');
+            //header('Content-type: text/plain');
+        $fh = fopen('php://output', 'w');
+        fwrite($fh,"\xEF\xBB\xBF"); // Stupid Excel and unicode!
+        fputcsv($fh, $titles);
+        
+        
+        
+        foreach($q as $qq) {
+            $row = array();
+            foreach($head as $k) {
+                $row[] = isset($qq[$k]) ? $qq[$k] : '';
+            }
+            
+            fputcsv($fh, $row);
+        }
+        
+        fclose($fh);
+        exit;
+    }
+    */
+}
+
+    
+    
\ No newline at end of file
diff --git a/Reports/ConsolidatedAccounts.php b/Reports/ConsolidatedAccounts.php
new file mode 100644 (file)
index 0000000..6d07105
--- /dev/null
@@ -0,0 +1,578 @@
+<?php 
+
+
+
+
+// fetch the consildated accounts from each system, and combine them.
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_ConsolidatedAccounts extends Pman_Xtuple_Reports_Base
+{
+    var $outlets = array(
+        'hk' => array('Hong Kong', 'HKD'),
+        'sg'=> array('Singapore', 'SGD'),
+        'my'=> array('Malaysia', 'MYR'),
+        'au'=> array('Australia', 'AUD'),
+        'cn'=> array('China', 'RMB'),
+        'zh' => array('China (Trade)', 'RMB')
+        //
+    );
+    var $intervalnames = array(
+        'Y' => 'Since Start of Financial Year to end of ',
+        'M' => 'Single Month'
+        
+    );
+    
+    var $groups = array();
+    var $fullpath = array();
+    function get()
+    {
+        
+        if (!empty($_REQUEST['_debug'])) {
+            DB_DAtaObject::DebugLevel(1);
+        }
+        
+        //$_REQUEST['flhead_name'] = 'Basic Balance Sheet';
+        //$_REQUEST['period'] = '2012-08-01';
+        
+        $interval  =  empty($_REQUEST['interval'])   ? 'Y' : $_REQUEST['interval'];
+        $this->withinterval  = '';
+        if (strlen($interval) == 2) {
+            $this->withinterval = $interval[1];
+            $interval = $interval[0];
+        }
+        
+        $nperiod = array();
+        $period = empty($_REQUEST['period']) ? date('Y-m-01') : date('Y-m-01', strtotime($_REQUEST['period']));
+        $operiod = $period;
+        if (!empty($this->withinterval )) {
+            if($this->withinterval != 'F' && $this->withinterval != 'L'){
+                $add = $this->withinterval  == 'M' ? ' 1 MONTH' : '1 YEAR';
+                $nperiod[] = date('Y-m-01', strtotime($period . ' - ' . $add));
+                $nperiod[] = $period;
+                
+            }else{
+                $pp = explode('-', $period);
+                $year = $pp[0];
+                $month = $pp[1];
+                switch (true){
+                    // 
+                    case ($this->withinterval == 'L') :
+                        $from = date('Y-m-01', strtotime($period . " - 12 MONTH + 1 MONTH"));
+                        break;
+                    
+                    case ($month < 5 ) :
+                        $from = ($year -1) . '-05-01';
+                        break;
+                    
+                    default :
+                        $from = $year . '-05-01';
+                        break;
+                }
+                
+                for($m = $from; strtotime($m) <= strtotime($period); $m = date('Y-m-01', strtotime("$m + 1 MONTH"))){
+                    $nperiod[] = $m;
+                }
+                
+                
+            }
+        }
+        if(!count($nperiod)){
+            $nperiod[] = $period;
+        }
+            
+        $period = implode(',', $nperiod);
+        
+        $x = DB_DataObject::Factory('flhead');
+        $ourdb = substr($x->database(), -2);
+        //$cbd = substr($x->database(), -2);
+        $cbd = empty($_REQUEST['company']) ? $ourdb : $_REQUEST['company'];
+        $outlets = array();
+        $outlets[$cbd ] = $this->outlets[$cbd ];
+        
+        if ($this->hasPerm('Xtuple.AccountsCombined', 'S') && $cbd == 'hk' &&   empty($_REQUEST['singleCountry']  )) {
+            $outlets = $this->outlets ;
+        }
+        $this->outlets=  $outlets;
+        
+        foreach($this->outlets as $o=>$name) { 
+            
+            $args = array(
+                'flhead_name' => $_REQUEST['flhead_name'],
+                'interval' => $interval,
+                'period' => $period,
+                // multiple periods...?
+            );
+            // only show timewarps in hk..
+            if ( $ourdb != 'hk') {
+                $args['no_timewarp'] =1;
+            }
+            
+            
+            $qq = array();
+            
+            
+            foreach($args as $k=>$v) {
+                $qq[] = "{$k}=". urlencode($v);
+            }
+            
+           
+           //  echo "http://localhost{$this->rootURL}/{$o}.php/Roo/flhead?". implode('&', $q);
+           //  continue;
+           //echo "<PRE>\nBERFORE:" . date('H:i:s') ;
+           
+            if ($o == $ourdb) {
+                $fl = DB_DataObjecT::factory('flhead');
+                $args['_return_result'] = 1;
+                $data = $fl->applyFilters($args, $this->authUser, $this);
+               
+                $this->parseData($data, $o);
+            
+            } else {
+                $url = "http://localhost{$this->rootURL}/{$o}.php/Roo/flhead?". implode('&', $qq);
+               //s var_dump($url);
+                $xtd = json_decode(file_get_contents($url));
+                if (empty($xtd->data)) {
+                    continue;
+                }
+                $this->parseData($xtd->data, $o);
+           }
+            // echo "<PRE>\nAFTER :" . date('H:i:s') ;
+            
+            // echo '<PRE>';print_r($this->groups);exit;
+           
+            
+             //echo '<PRE>';print_r($this->groups);exit;
+        }
+        //exit;
+        if (!empty($_REQUEST['_xls'])) {
+            $this->toExcel($operiod, $nperiod, $interval);
+        }
+        $this->toHTMLBody($operiod, $nperiod, $interval);
+         
+         
+       
+    }
+    function parseData($data, $out)
+    {
+        //echo '<PRE>';print_r($data);exit;
+        
+        if ($out == 'au') {
+           // echo '<PRE>';print_r($data);exit;
+        }
+        $groups = array(); // id to group.
+        foreach($data as $g)
+        {
+            
+            if (is_array($g)) {
+                $g = (object) $g; // returned directly. - no json..
+            }
+            switch($g->fltrenditem_type) {
+                case 'G': //groups
+                    $g->items = array();
+                    $g->groups = array();
+                    $grp = $g->fltrenditem_name;
+                    $g->fullpath = $grp;
+                    
+                     
+                    if ($g->fltrenditem_parent_id > 0) {
+                        
+                        // not a top levell see if current group has a child.
+                        
+                        
+                        $parname = $groups[$g->fltrenditem_parent_id];
+                        
+                        $g->fullpath = $parname .'|'.$grp;
+                        $par= $this->fullpath[$parname];
+                        
+                        if (!isset($par->groups[$grp] )) {
+                            $par->groups[$grp] = $g;
+                        }
+                        
+                    } else {
+                        $g->fullpath = $grp;
+                        if (!isset($this->groups[$grp])) {
+                            $this->groups[$grp] = $g;
+                        }
+                    }
+                    
+                    if (!isset($this->fullpath[$g->fullpath])) {
+                        $this->fullpath[$g->fullpath] = $g;
+                    }
+                    
+                    $this->fullpath[$g->fullpath]->{$out} = $g;
+                    
+                    
+                    
+                    $groups[$g->fltrenditem_type_id] = $g->fullpath;
+                    
+                    continue;
+                
+                
+                case 'T': // totals.
+                    if (!isset($g->fltrenditem_parent_id)) {
+                        continue;
+                    }
+                    
+                    $parname = $groups[$g->fltrenditem_parent_id];
+                    $par= $this->fullpath[$parname];
+                    $par->total = isset($par->total) ? $par->total : $g;
+                    $par->total->{$out} = $g;
+                    
+                    continue;
+                
+                
+                case 'I': // account.
+                    
+                    $rowtotal = 0;
+                    for ($i =1 ; $i < 13; $i++) {
+                        $rowtotal += isset($g->{'fltrenditem_fld'.$i}) ? $g->{'fltrenditem_fld'.$i} : 0;
+                    }
+                    
+                    if ($rowtotal  == 0.0) {
+                        continue;
+                    }
+                    
+                    $parname = $groups[$g->fltrenditem_parent_id];
+                    $par = $this->fullpath[$parname];
+                    if (!isset($par->items[$g->fltrenditem_name])) {
+                        $par->items[$g->fltrenditem_name] = clone($g)  ;
+                    }
+            
+                    $par->items[$g->fltrenditem_name]->{$out} = $g;
+                    continue;
+                    
+                    
+            }
+            
+            
+        }
+        
+        
+    }
+    
+    function toHTMLBody($operiod, $nperiod, $interval)
+    {
+        
+        echo '<style>'. file_get_contents(dirname(__FILE__).'/reportstyle.css') . '</style>';
+        echo '<div class="accnt-report">';
+        $flhead = DB_DataObject::factory('flhead');
+        if (!$flhead->get('flhead_name', $_REQUEST['flhead_name'])) {
+            $this->jerr("invalid report");
+        }
+        
+        echo '<H1>' . htmlspecialchars($flhead->flhead_name) .  ' in ' . DB_DataObject::factory('curr_symbol')->base()->curr_name . '</H1>';
+        echo "<i>For {$this->intervalnames[$interval]} " . date(' F Y', strtotime($operiod)). '</i>';
+       //  echo '<PRE>';print_r($this->groups);echo '</PRE>';
+        echo '<table>';
+        
+        $ret = '<tr><td>Account</td>';
+        
+        if(($this->withinterval != 'F' && $this->withinterval != 'L') || count(array_keys($this->outlets)) == 1){
+            foreach($this->outlets as $k=>$name) {
+                foreach ($nperiod as $n => $p){
+                    if($n == 0){
+                        $ret.='<td>' .   $name[0] . '<br/>' . date(' F Y', strtotime($p)) .' </td>';
+                        continue;
+                    }
+                    $ret.='<td> <br/>'  .date(' F Y', strtotime($p))  .' </td>';
+                }
+                
+            }
+            if (count(array_keys($this->outlets)) > 1) {
+                foreach ($nperiod as $n => $p){
+                    if($n == 0){
+                        $ret.= ($this->withinterval) ? '<td>Combined<br/>' .date(' F Y', strtotime($p)) .' </td>' : '<td>Combined</td>';
+                        continue;
+                    }
+                    $ret.='<td><br/>'  . date(' F Y', strtotime($p))  .' </td>';
+                }
+            }
+        }else{
+            $ret.='<td>Consolidated</td>';
+        }
+     
+            
+        $ret .= "</tr>\n";
+        echo $ret;
+        
+        
+        
+        foreach($this->groups  as  $kk => $vv ) {
+            echo $this->toHTML($kk, $vv, $nperiod);
+        }
+        echo '</table>';
+        echo '</div>';
+        
+        exit;
+    }
+    function toHTML($key ,  $obj, $nperiod)
+    {
+        // assume head row has been sent.
+        
+        $ret = '<tr class="accnt-type-'. $obj->fltrenditem_type.'"><td class="accnt-name">'. htmlspecialchars($key) .'</td>';
+        
+        $tmp = '';
+        foreach($this->outlets as $k=>$name) {
+            foreach ($nperiod as $n => $p){
+                $str = 'fltrenditem_fld' . ($n+1);
+                $val = !empty($obj->$k->$str) ? $obj->$k->$str : 0;
+                $val = $val ? $this->currtobase($name[1], 'HKD', $val, date('Y-m-d')) : 0;
+                if (($this->withinterval == 'F' || $this->withinterval == 'L') && count(array_keys($this->outlets)) > 1) {
+                    if(!isset($consolidated)){
+                        $consolidated = 0;
+                    }
+                    $consolidated +=  (isset($obj->$k)) ? $val : 0;
+                    continue;
+                }
+                $total = 'total' . ($n+1);
+                if(!isset($$total)){
+                    $$total = 0;
+                }
+                $$total += isset($obj->$k) ? $val : 0;
+                $tmp.='<td  class="accnt-value">' .  
+                    (!empty($val) ? number_format($val, 2) : '') .
+                    '</td>';
+            }
+        }
+           
+        
+        if (count(array_keys($this->outlets)) > 1) {
+            foreach ($nperiod as $n => $p){
+                $total = 'total' . ($n+1);
+                $tmp.= '<td class="accnt-value">' .
+                (empty($$total) ? '' : number_format($$total,2)) .
+                '</td>';
+            }
+        }
+        
+        if(($this->withinterval != 'F' && $this->withinterval != 'L') || count(array_keys($this->outlets)) == 1){
+            $ret .= $tmp;    
+        }else{
+            
+            $ret.= '<td class="accnt-value">' .
+                    (empty($consolidated) ? '' : number_format($consolidated,2)) .
+                    '</td>';
+            
+        }
+        $ret .= "</tr>\n";
+        
+        foreach(isset($obj->groups) ? $obj->groups : array() as  $kk => $vv ) {
+            $ret .= $this->toHTML($kk, $vv,$nperiod);
+        }
+        
+        $items = isset($obj->items) ? $obj->items: array();
+        ksort($items);
+        foreach($items as  $kk => $vv ) {
+            $ret .= $this->toHTML($kk, $vv, $nperiod);
+        }
+        
+        if (isset($obj->total) ) {
+            
+            $ret.= $this->toHTML($obj->total->fltrenditem_name, $obj->total,$nperiod);
+        }
+        return $ret;
+        
+    }
+    function currtobase($from , $to, $amt , $date)
+    {
+       
+        static $base = false;
+        if (!$base) {
+            $base = DB_DataObject::factory('curr_symbol')->base()->curr_name;
+        }
+        // var_dump(array($from,$base));
+        
+        if (($from == $base) || ($amt == 0.0)) {
+            return $amt;
+        }
+        $do = DB_DataObject::factory('curr_symbol');
+        $do->query("select currtobase(getcurrid('{$from}'), {$amt}, '{$date}') as result");
+        $do->fetch();
+        return $do->result;
+        
+        
+    }
+    
+    function toExcel($operiod, $nperiod, $interval)
+    {
+        // assume head row has been sent.
+        
+        $curr = DB_DataObject::factory('curr_symbol')->base();
+        
+        
+        
+        $cfg =  array(
+            'formats' => array(
+                'alignright' => array(
+                        'Align' => 'right',
+                        'NumFormat' => '"'.$curr->curr_symbol. '"#,##0.00_);[Red]("'.$curr->curr_symbol. '"#,##0.00)'
+                    ),
+                'alignleft' => array( 'Align' => 'left'),
+            ),
+            'workbook' => 'Consolidated Report',
+            
+            'head' => array(),
+            'cols' =>  array(
+                
+            )   
+        );
+        
+        $flhead = DB_DataObject::factory('flhead');
+        if (!$flhead->get('flhead_name', $_REQUEST['flhead_name'])) {
+            $this->jerr("invalid report");
+        }
+        $cfg['head'][] = array($flhead->flhead_name);
+        $cfg['head'][] = array("For {$this->intervalnames[$interval]} on " . date('d F Y', strtotime($operiod)));
+        $cfg['cols'][] = array(
+                'header'=> "Account",
+                'dataIndex'=> 'name',
+                'width'=>  200,
+                'format' => 'alignleft'
+            );
+        if(($this->withinterval != 'F' && $this->withinterval != 'L') || count(array_keys($this->outlets)) == 1){
+            foreach($this->outlets as $k=>$name) {
+                foreach ($nperiod as $n => $p){
+                    if($n == 0){
+                        $cfg['cols'][] = array(
+                            'header'=> ($this->withinterval) ? $name[0] . "\n" . $p : $name[0] ,
+                            'dataIndex'=> 'data_' . $k . ($n+1),
+                            'width'=>  100,
+                            'format' => 'alignright'
+                        );
+                        continue;
+                    }
+                    $cfg['cols'][] = array(
+                        'header'=> "\n" . $p ,
+                        'dataIndex'=> 'data_' . $k . ($n+1),
+                        'width'=>  100,
+                        'format' => 'alignright'
+                    );
+
+                }
+            }
+        }else{
+            $cfg['cols'][] = array(
+                'header'=> 'Consolidated',
+                'dataIndex'=> 'consolidated',
+                'width'=>  100,
+                'format' => 'alignright'
+            );
+            
+        }
+        
+        if ($this->withinterval != 'F' && $this->withinterval != 'L' && count(array_keys($this->outlets)) > 1) {
+            foreach ($nperiod as $n => $p){
+                if($n == 0){
+                    $cfg['cols'][] = array(
+                        'header'=> ($this->withinterval) ? "Combinded\n" . $p : "Combinded",
+                        'dataIndex'=> 'total' . ($n+1),
+                        'width'=>  100,
+                        'format' => 'alignright'
+                    );
+                    continue;
+                }
+                $cfg['cols'][] = array(
+                    'header'=>  "\n". $p ,
+                    'dataIndex'=> 'total' . ($n+1),
+                    'width'=>  100,
+                    'format' => 'alignright'
+                );
+            }
+        }
+            
+       $this->edata = array();
+       
+        foreach($this->groups  as  $kk => $vv ) {
+            $this->toExcelRow($kk, $vv, $nperiod);
+        }
+        
+        $fn = $flhead->flhead_name.'-'.$this->intervalnames[$interval].'-'.date('d-F-Y', strtotime($operiod)) .'.xls';
+        
+        require_once 'Pman/Core/SimpleExcel.php';
+        //echo '<PRE>';        print_R($this->edata);        print_R($cfg);        exit;
+        $x = new Pman_Core_SimpleExcel($this->edata, $cfg);
+        $x->send(  'combined-report-' . $fn );
+        exit;
+    }
+    
+    function  toExcelRow($key, $obj, $nperiod)
+    { 
+        $out = array(
+            'name' => $key
+        );
+        
+        foreach($this->outlets as $k=>$name) {
+            foreach ((array)$nperiod as $n => $p){
+                $str = 'fltrenditem_fld' . ($n+1);
+                $val = isset($obj->$k->$str) ? $obj->$k->$str : 0;
+                $val = $this->currtobase($name[1], 'HKD', $val, date('Y-m-d'));
+                if (($this->withinterval == 'F' || $this->withinterval == 'L') && count(array_keys($this->outlets)) > 1) {
+                    if(!isset($out['consolidated'])){
+                        $out['consolidated'] = 0;
+                    }
+                    $out['consolidated'] +=  (isset($obj->$k)) ? $val : 0;
+                    continue;
+                }
+                $out['data_'.$k . ($n+1)] =  (isset($obj->$k) ? $val : '');
+                if(!isset($out['total' . ($n+1)])){
+                    $out['total' . ($n+1)] = 0;
+                }
+                $out['total' . ($n+1)]  +=  (isset($obj->$k)) ? $val : 0;
+            }
+            
+        }
+        
+        $this->edata[] = $out;
+        
+        foreach(isset($obj->groups) ? $obj->groups : array() as  $kk => $vv ) {
+             $this->toExcelRow($kk, $vv, $nperiod);
+        }
+        $items = isset($obj->items) ? $obj->items: array();
+        ksort($items);
+        foreach($items as  $kk => $vv ) {
+            $this->toExcelRow($kk, $vv, $nperiod);
+        }
+        if (isset($obj->total) ) {
+            
+             $this->toExcelRow($obj->total->fltrenditem_name, $obj->total, $nperiod);
+        }
+        
+        
+    }
+    /*
+    function findBeforeMonth($n, $dt)
+    {
+        //var_dump($dt);
+        list($y,$m, $d) = explode('-', $dt);
+        
+        if ($m > $n) {
+            return sprintf('%04d-%02d-%02d', $y,$n,1 );
+        }
+        
+        return sprintf('%04d-%02d-%02d', $y -1,$n, 1);
+        
+    }
+    
+    function merge($old, $new, $factor)
+    {
+        // merge the accounts...
+        foreach($old as $o) {
+            if (empty($o->fltrenditem_type) || $o->fltrenditem_type !='I') {
+                continue;
+            }
+            $accnt[$o->fltrenditem_accnt_id] = $o;
+        }
+        foreach($new as $o) {
+            if (empty($o->fltrenditem_type)  || $o->fltrenditem_type !='I') {
+                continue;
+            }
+            $accnt[$o->fltrenditem_accnt_id]->fltrenditem_fld1 += $factor * $o->fltrenditem_fld1;
+        }
+        return $old;
+         
+    }
+    */
+    
+}
diff --git a/Reports/Meta.php b/Reports/Meta.php
new file mode 100644 (file)
index 0000000..5560324
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+
+
+// will not work  - will take quite a bit of work to convert all the meta language into php or similar..
+require_once 'Base.php';
+class Pman_Xtuple_Reports_Meta extends Pman_Xtuple_Reports_Base
+{
+    
+    
+     
+    function get ()
+    {
+        $d = DB_DAtaObject::Factory('metasql');
+        $d->metasql_group = $_REQUEST['_report_group'];
+        $d->metasql_name = $_REQUEST['_report_name'];
+         //SELECT metasql_query   FROM metasql WHERE ((metasql_group='salesHistory')     AND (metasql_name='detail')) ORDER BY metasql_grade DESC LIMIT 1;
+        $d->limit(1);
+        $d->orderBy('metasql_grade DESC ');
+        $d->find(true);
+        //echo'<PRE>' . htmlspecialchars( print_R($d,true));exit;
+        $query = $this->toPHP($d->metasql_query);
+        
+        $d = DB_DAtaObject::Factory('metasql');
+        //DB_DAtaObject::DebugLevel(1);
+        $d->query($query);
+        return $this->toCsv($d, false);
+        
+        
+        
+        
+        
+    }
+    function toPHP($q) {
+        
+        
+        
+        
+        //echo'<PRE>' .htmlspecialchars(  $q);
+        
+        preg_match_all('#\<\?([^?]+)\?\>#', $q, $matches);
+        ///echo '<PRE>' . htmlspecialchars(print_r($matches,true));
+        foreach($matches[0] as $i=>$full) {
+            $q = str_replace($full, $this->toEl($matches[1][$i]), $q);
+        }
+        
+        //echo'<PRE>' .htmlspecialchars( print_r(explode("\n", $q),true));
+        
+        
+        $meta = $this;
+        
+        
+        ob_start();
+        eval( '?>' . $q );
+        $data = ob_get_contents();
+        ob_end_clean();
+        //echo $data;
+        // finally strip out all the comments...
+        $lines = explode("\n", $data);
+        $out = array();
+        foreach($lines as $l) {
+            if (preg_match('#^\s*--#', $l)) {
+                continue;
+            }
+            $out[] = $l;
+        }
+        
+        
+         return implode("\n", $out);
+        
+        
+    }
+    function toEl($str) {
+        // replace all the strings with variable references;
+        $str= trim($str);
+        preg_match_all('#"([a-z0-9_]+)"#i', $str, $matches);
+        //print_R($matches);
+        
+        //foreach($matches[0] as $i=>$full) {
+        //    $sub = $matches[1][$i];
+        //    $str = str_replace($full, '$t->'. $sub, $str);
+        //}
+        
+        // functions..
+        $matches = array();
+        if (preg_match_all('#([a-z0-9_]+)\(([^\)]+)\)?#i', $str, $matches)) {
+            
+            //print_R($matches);
+            
+            foreach($matches[0] as $i=>$full) {
+                $sub = $matches[1][$i];
+                $args = $matches[2][$i];
+                //if ($sub == 'exists') {
+                //    $str = str_replace($full, 'isset(' . $args . ')', $str);
+                //    continue;
+                // }
+                
+                
+                //if ($sub == 'value') {
+                //    $str = str_replace($full, 'isset(', $str);
+                //    continue;
+                //}
+                
+                $str = str_replace($full, '$meta->'. $sub .'(' . $args . ')', $str);
+            }
+        }
+        
+        
+        
+        
+        if (preg_match('#^if#', $str)) {
+            $str = preg_replace('/^if/', '', $str);
+            $str = 'if ( ' . $str .' ) {';
+            
+        } else  if (preg_match('#^endif$#', $str)) {
+            $str = '}';
+        } else if (preg_match('#^elseif#', $str)) {
+            $str = preg_replace('/^elseif/', '', $str);
+            $str = ' } else if ( ' . $str .' ) {';
+        } else if (preg_match('#^else#', $str)) {
+            $str = '} else {';
+        }
+        
+        return '<?php ' . $str . ' ?>';
+        
+        
+        
+    }
+    
+    function exists($a)
+    {
+        if (isset($_REQUEST[$a.':number']) || isset($_REQUEST[$a.':text'])) {
+            return true;
+        }
+        return false;
+        
+    }
+    
+    function value($a) {
+        
+         
+        
+        if (!$this->exists($a)) {
+            $this->jerr("required variable not found: " . $a);
+        }
+        if (isset($_REQUEST[$a.':number'])) {
+            echo (float) $_REQUEST[$a.':number'];
+            return;
+        }
+        // it's text
+        $old = DB_DataObject::debugLevel(0);    
+        
+        echo "'". $this->escape($_REQUEST[$a.':text']). "'";
+        DB_DataObject::debugLevel($old);
+    }
+    
+    
+}
+
+
diff --git a/Reports/PurchasesByProduct.php b/Reports/PurchasesByProduct.php
new file mode 100644 (file)
index 0000000..046f7d2
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_PurchasesByProduct extends Pman_Xtuple_Reports_Base
+{
+     
+    
+    function get()
+    {
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+        //DB_DataObject::debugLevel(1);
+        
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+                  
+            SELECT
+                 item_number,
+                item_descrip1,
+                qty,
+                ROUND(purchase_cost,2) as purchase_cost 
+                 
+            FROM
+            
+                
+                (SELECT
+                    item_number,
+                    item_descrip1,
+                    ROUND(sum(recv_qty),0) as qty,
+                    sum(recv_qty *   currtobase(recv_purchcost_curr_id,  recv_purchcost, recv_date::date)) as purchase_cost 
+                    FROM
+                        recv
+                    
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        itemsite_id = recv_itemsite_id
+                        
+                    LEFT JOIN
+                        item
+                    ON
+                        item_id = itemsite_item_id
+                    
+                    WHERE
+                        recv_date >= '$date_from'
+                        AND
+                        recv_date <= '$date_to'
+                    
+                    GROUP BY
+                         item_number,
+                        item_descrip1 
+                        
+                        
+                )  rq      
+            ORDER BY
+                purchase_cost DESC
+             
+        ");
+         
+        $this->toCsv($q,   explode(',', 'item_number,item_descrip1,qty,purchase_cost'));
+                
+                
+        
+        
+    }
+    
+    
+}
+
diff --git a/Reports/PurchasesByVendor.php b/Reports/PurchasesByVendor.php
new file mode 100644 (file)
index 0000000..e9cafcc
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_PurchasesByVendor extends Pman_Xtuple_Reports_Base
+{
+     
+    
+    function get()
+    {
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+           
+        //DB_DataObject::DebugLevel(1);
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+                  
+            SELECT
+                vend_number ,
+                vend_name,
+                qty,
+                ROUND(purchase_cost,2) as purchase_cost 
+                 
+            FROM
+            
+                
+                (SELECT
+                    vend_number,
+                    vend_name,
+                    ROUND(sum(recv_qty),0) as qty,
+                    sum(recv_qty *   currtobase(recv_purchcost_curr_id,  recv_purchcost, recv_date::date)) as purchase_cost 
+                    FROM
+                        recv
+                    
+                    LEFT JOIN
+                        vendinfo
+                    ON
+                        vend_id = recv_vend_id
+                        
+                          
+                    
+                    WHERE
+                        recv_date >= '$date_from'
+                        AND
+                        recv_date <= '$date_to'
+                    
+                    GROUP BY
+                        vend_name,
+                        vend_number
+                        
+                        
+                )  rq      
+            ORDER BY
+                purchase_cost DESC
+             
+        ");
+         
+        $this->toCsv($q,   explode(',', 'vend_number,vend_name,qty,purchase_cost'));
+                
+                
+        
+        
+    }
+    
+    
+}
+
diff --git a/Reports/SGTax.php b/Reports/SGTax.php
new file mode 100644 (file)
index 0000000..7c413f6
--- /dev/null
@@ -0,0 +1,176 @@
+<?php 
+
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_SGTax extends Pman_Xtuple_Reports_Base
+{
+     
+    function get()
+    {
+        // DB_DataObject::DebugLevel(1);
+        
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+           
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+            
+            SELECT
+                aropen_doctype,
+                cohead_number,
+                aropen_docnumber,
+                invchead_notes,
+                aropen_docdate,
+                cust_name,
+                curr_name,
+                ROUND(aropen_amount,2) as aropen_amount,
+                
+                ROUND(currtobase(aropen_curr_id, aropen_amount, aropen_docdate ),2) as aropen_amount_sgd,
+                
+                ROUND(CASE WHEN aropen_doctype = 'I' THEN
+                        (SELECT sum(taxhist_tax) FROM invcitemtax WHERE taxhist_parent_id IN (
+                            SELECT invcitem_id FROM invcitem where invcitem_invchead_id= invchead_id
+                        ))
+                    ELSE
+                        (SELECT sum(taxhist_tax) FROM cmitemtax WHERE taxhist_parent_id IN (
+                            SELECT cmitem_id FROM cmitem where cmitem_cmhead_id= cmhead_id
+                        ))
+                    END,2)
+                    AS tax_amount,
+                location_name
+                
+            FROM
+                
+                (
+                    SELECT
+                        aropen_doctype,
+                        cohead_number,
+                        aropen_docnumber,
+                        aropen_docdate,
+                        cust_name,
+                        curr_name,
+                        aropen_amount,
+                        aropen_curr_id,
+                        location_name,
+                        
+                        invchead_id,
+                        invchead_notes,
+                        
+                        0 as cmhead_id
+                        
+                        
+                    FROM
+                            aropen
+            
+                        LEFT JOIN
+                            invchead
+                        ON
+                            invchead_invcnumber = aropen_docnumber 
+                        
+                        LEFT JOIN
+                            cobmisc
+                        ON
+                            cobmisc_invchead_id = invchead_id 
+                            
+                        LEFT JOIN
+                            cohead
+                        ON
+                            cohead_id = cobmisc_cohead_id 
+                     
+                        LEFT JOIN
+                            location
+                        ON
+                            location_id = cohead_location_src 
+                            
+                        LEFT JOIN
+                            custinfo
+                        ON
+                            cust_id = aropen_cust_id
+                                
+                        LEFT JOIN
+                            curr_symbol
+                        ON
+                            curr_id = aropen_curr_id
+                    
+                            
+                        WHERE
+                            aropen_docdate >= '$date_from'
+                            AND
+                            aropen_docdate <= '$date_to'
+                            AND
+                            aropen_doctype = 'I'
+                            AND
+                            invchead_void = false
+                 
+                    UNION
+                 
+                    SELECT
+                           aropen_doctype,
+                           '' AS cohead_number,
+                           aropen_docnumber,
+                           aropen_docdate,
+                           cust_name,
+                           curr_name,
+                           aropen_amount * -1 AS aropen_amount,
+                           aropen_curr_id,
+                           location_name,
+    
+                           0 AS invchead_id,
+                           '' AS invchead_notes,
+                           
+                            cmhead_id
+                        FROM
+                            aropen
+                
+                        LEFT JOIN
+                            cmhead
+                        ON
+                            cmhead_number = aropen_docnumber 
+                        
+                        LEFT JOIN
+                            invdetailview
+                        ON
+                            invhist_ordtype= 'CM'
+                            AND
+                            invhist_ordnumber = 'CMSG19-22159'
+                            
+                        
+                        LEFT JOIN
+                            location
+                        ON
+                            location_id = invdetail_location_id 
+                            
+                        LEFT JOIN
+                            custinfo
+                        ON
+                            cust_id = aropen_cust_id
+                                
+                        LEFT JOIN
+                            curr_symbol
+                        ON
+                            curr_id = aropen_curr_id
+                    
+                            
+                        WHERE
+                            aropen_docdate >= '$date_from'
+                            AND
+                            aropen_docdate <= '$date_to'
+                            AND
+                            aropen_doctype = 'C'
+                            AND
+                            cmhead_void = false
+                        
+                
+                ) aropen_cm
+            ORDER BY
+                aropen_docdate ASC
+                
+        ");
+        //$q->limit(1);
+        //echo '<PRE>';$q->fetch();        print_R($q->toArray('%s', true));        exit;
+               
+        $this->toCsv($q,  explode(',',
+                'aropen_doctype,cohead_number,aropen_docnumber,invchead_notes,aropen_docdate,'.
+                'cust_name,curr_name,aropen_amount,aropen_amount_sgd,tax_amount,location_name'));
+    }
+}
diff --git a/Reports/SalesByCountry.php b/Reports/SalesByCountry.php
new file mode 100644 (file)
index 0000000..8546077
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_SalesByCountry extends Pman_Xtuple_Reports_Base
+{
+     
+    
+    function get()
+    {
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+        $sd = strtoupper(substr(HTML_FlexyFramework::get()->database,-2));
+        
+        $name = $sd == 'HK' ? 'From Hong Kong' : 'From Signapore';
+        
+        //DB_DataObject::DebugLevel(1);
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+                  
+            SELECT
+                addr_country,
+                SUM(qtysold) as qtysold,
+                ROUND(SUM(soldat),2) as soldat_hkd
+                 
+            FROM
+            
+                
+                (SELECT
+                    CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        '$name'
+                    ELSE 
+                        addr_country
+                    END AS addr_country,
+                     
+                    ROUND(sum(invcitem_billed),0) as qtysold,
+                    sum(invcitem_billed * currtocurr(invchead_curr_id, getcurrid('HKD'), invcitem_custprice, invchead_invcdate)) as soldat 
+                     
+                    FROM
+                     
+                    invcitem
+                  
+                     
+                    LEFT JOIN
+                        invchead
+                    ON
+                        invchead_id = invcitem_invchead_id
+                    
+                   
+                    
+                    
+                    LEFT JOIN
+                        custinfo
+                    ON
+                        invchead_cust_id = cust_id
+                    
+                    LEFT JOIN
+                        cntct
+                    ON
+                        cntct_id = cust_cntct_id 
+                    
+                    LEFT JOIN
+                        addr
+                    ON
+                        addr_id = cntct_addr_id 
+                    
+                    
+                    
+                    WHERE
+                        
+                        invchead_invcdate >= '$date_from'
+                        AND
+                        invchead_invcdate  <= '$date_to'
+                        AND
+                        invchead_void = false
+                        
+                    GROUP BY
+                        addr_country 
+                        
+                        
+                )  rq
+            GROUP BY
+                  addr_country 
+                
+            ORDER BY
+                soldat_hkd DESC
+          
+             
+        ");
+        if (!empty($_REQUEST['format']) && $_REQUEST['format'] == 'json' ) {
+            $ret = array();
+            $sd = strtoupper(substr(HTML_FlexyFramework::get()->database,-2));
+            while ($q->fetch()) {
+                
+                $ret[$q->addr_country] = $q->toArray($sd.'_%s',true);
+                
+                
+            }
+            $this->jdata($ret);
+        }
+        
+         $sg = array();
+        
+        if ($sd == 'HK') {
+        // fetch SG DATA...
+            $xtd = json_decode(file_get_contents(
+                    "http://localhost/xtuple/sg.php/Xtuple/Reports/SalesByCountry?date_from=$date_from&date_to=$date_to&format=json"));
+           // echo '<PRE>';print_r($xtd);exit;
+            $sg = (array) ($xtd->data);
+        }
+        
+        
+        $ours = array();
+        while ($q->fetch()) {
+            $add = $q->toArray('%s', true);
+            if (!isset($head)) {
+                $head = array_keys($add);
+            }
+            $add['total_sold'] = $add['qtysold'] ;
+            $add['total_hkd'] = $add['soldat_hkd'];
+            $ours[$q->addr_country  ] = $add;
+        }
+        
+        
+        
+        $radd = false;
+        foreach($sg as $k=>$v) {
+            $add = (array)$v;
+            
+            
+            unset($add['SG_addr_country']);
+            
+            if (!$radd) {
+                $head = array_merge($head, array_keys( $add ));
+                $radd = true;
+            }
+            if (!isset($ours[$k]) ) {
+                 
+                $ours[$k] = array();
+                $add['addr_country'] = $v->SG_addr_country;
+                 $add['qty_sold'] = $add['SG_qtysold'];
+                $add['total_hkd'] = $add['SG_soldat_hkd'];
+                
+            } else {
+                $ours[$k]['total_sold'] += $add['SG_qtysold'];
+                $ours[$k]['total_hkd'] += $add['SG_soldat_hkd'];
+            }
+            $ours[$k] = ($ours[$k] + $add);
+            
+            
+        }
+        $head[] = 'total_sold';
+        $head[] = 'total_hkd';
+        
+        
+        $ret = array_values($ours);
+        usort($ret, function($a,$b) {
+            return $a['total_hkd'] >  $b['total_hkd'] ? 1 : -1;
+            
+            
+        });
+        
+        //echo '<PRE>';print_r($head);     
+        //echo '<PRE>';print_r($ret);exit;    
+        
+        
+        
+         
+        $this->toCsv($ret,   $head);
+                
+                
+        
+        
+    }
+    
+    
+}
+
+
diff --git a/Reports/SalesByCountryItemYear.php b/Reports/SalesByCountryItemYear.php
new file mode 100644 (file)
index 0000000..eb7eb74
--- /dev/null
@@ -0,0 +1,254 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_SalesByCountryItemYear extends Pman_Xtuple_Reports_Base
+{
+     
+    
+    function get()
+    {
+        $base_date = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $cur_y = date('Y' , strtotime($_REQUEST['date_from']));
+        
+        if (empty($_REQUEST['brand'])) {
+            $this->jerr("missing brand");
+        }
+        if (empty($_REQUEST['span'])) {
+            $this->jerr("missing span");
+        }
+        // if we restrict this by brand then the output data should not be that bad...
+        
+        $sd = strtoupper(substr(HTML_FlexyFramework::get()->database,-2));
+        
+        
+        
+        
+        $q = DB_DataObject::factory('cohist');
+        $q->selectAdd();
+        $q->selectAdd("
+            itemcharvalue(item_id, 'BRAND') as item_brand,
+            itemcharvalue(item_id, 'PRODUCTCATEGORY') as item_productcategory,
+            item_number,
+            item_descrip1,
+            CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+                'UNKNOWN'
+            ELSE 
+                addr_country
+            END AS  cohist_country,
+            
+            ROUND( COALESCE(SUM(cohist_qtyshipped * currTocurr(cohist_curr_id, getcurrid('HKD'), cohist_unitprice, cohist_shipdate)),0),2) as ship_value,
+            ROUND(COALESCE(SUM(cohist_qtyshipped),0),0) as ship_qty
+                    
+                      
+                      
+        ");
+        $q->_join = "
+            LEFT JOIN
+                custinfo
+            ON
+                cust_id = cohist_cust_id
+                
+            LEFT JOIN
+                cntct
+            ON
+                cntct_id = cust_cntct_id 
+            
+            LEFT JOIN
+                addr
+            ON
+                addr_id = cntct_addr_id 
+            LEFT JOIN
+                itemsite
+            ON
+                itemsite_id = cohist_itemsite_id
+            LEFT JOIN
+                item
+            ON
+                itemsite_item_id = item_id
+         
+        ";
+        
+        $q->whereAdd(" item_type = 'P'
+                            AND
+                    itemcharvalue(item_id, 'BRAND')  = '{$q->escape($_REQUEST['brand'])}'
+        ");
+        
+        $q->groupBy("item_id,item_number,item_descrip1,addr_country");
+        
+        $q->orderBy("item_number ASC");
+        
+        
+        
+        $data = array();
+        $countries = array();
+        $span = (int) $_REQUEST['span'];
+        for ($i = 0 ; $i < 2; $i++) {
+            $qq = clone($q);
+            if (!$i) {
+                $qq->whereAdd("cohist_invcdate BETWEEN '{$base_date}'::date - INTERVAL '1 YEAR' AND '{$base_date}'::date - INTERVAL '1 YEAR' + INTERVAL '{$span} MONTH'");
+                $qq->selectAdd( ($cur_y - 1) . " as cohist_year");
+            } else {
+                $qq->whereAdd("cohist_invcdate BETWEEN '$base_date'::date AND '$base_date'::date + INTERVAL '{$span} MONTH' ");
+                $qq->selectAdd( ($cur_y ) . " as cohist_year");
+            }
+            
+            $qq->find();
+            while ($qq->fetch())  {
+                if (!isset($data[$qq->item_number])) {
+                    $data[$qq->item_number] = array();
+                }
+                
+                $data[$qq->item_number][] = (object) $qq->toArray('%s', true);
+                if (!isset($countries[$qq->cohist_country])) {
+                    $countries[$qq->cohist_country] = 1;
+                    
+                }
+                
+                
+            }
+        }
+        
+        
+        if (!empty($_REQUEST['format']) && $_REQUEST['format'] == 'json' ) {
+            
+            $this->jdata(array( 'data'=> $data, 'countries'=>$countries));
+        }
+        
+         
+        
+        if ($sd == 'HK') {
+        // fetch SG DATA...
+        
+            //echo "http://localhost{$this->rootURL}/sg.php/Xtuple/Reports/SalesByCountryItemYear".
+            //        "?date_from={$base_date}&format=json&brand=". urlencode($_REQUEST['brand']);
+            
+        
+            $xtd = json_decode(file_get_contents(
+                    "http://localhost{$this->rootURL}/sg.php/Xtuple/Reports/SalesByCountryItemYear".
+                    "?date_from={$base_date}".
+                    "&format=json".
+                    "&brand=". urlencode($_REQUEST['brand']).
+                    "&span=".$span
+           ));
+           //echo '<PRE>';print_r($xtd);exit;
+             
+            // merge in SG data..
+            foreach((array)($xtd->data->countries) as $c=>$tr) {
+                $countries[$c] = 1;
+            }
+            
+            foreach((array)($xtd->data->data) as $item=>$rdata) {
+                $data[$item] = array_merge(isset($data[$item]) ? $data[$item] : array(), $rdata);
+            }
+            
+        }
+       //echo '<PRE>'; print_R($data);exit;
+        
+        // work out what the head rows will be
+        $heads = array(
+            'item_brand' => array('Brand'),
+            'item_productcategory' => array('Category'),
+            'item_number' => array('Name'),
+            'item_descrip1' => array('Description'),
+        );
+        ksort($countries);
+        foreach($countries as $c=>$tr) {
+            for ($i = 0 ; $i < 2; $i++) {
+                
+                $heads['ship_qty:'.$c.':'. ($cur_y +$i -1)] = array($c, $cur_y +$i -1, 'Sum qty');
+                $heads['ship_value:'.$c.':'. ($cur_y +$i -1)] = array($c, $cur_y +$i -1, 'Sum Value');
+            }
+        }
+        for ($i = 0 ; $i < 2; $i++) {
+            $heads['ship_qty:'.($cur_y +$i -1)] = array('Total Qty' , ($cur_y +$i -1) );
+            $heads['ship_value:'.($cur_y +$i -1)] = array('Total Value', ($cur_y +$i -1));
+        }
+        
+        
+        $fn = 'CountryItemYear-'.urlencode($_REQUEST['brand']) . '-' . $base_date .'-for-'. $span.'Months-rptdate-';
+        header('Content-type: text/csv');
+        //header('Content-type: text/plain');
+        header('Content-Disposition: attachment; filename="'.$fn.date('Y-m-d') . '.csv"');
+            //header('Content-type: text/plain');
+        $fh = fopen('php://output', 'w');
+        fwrite($fh,"\xEF\xBB\xBF"); // Stupid Excel and unicode!
+        for($i =0; $i< 3;$i++) {
+            $row = array();
+            foreach($heads as $k=>$v) {
+                $row[] = isset($v[$i]) ? $v[$i] : '';
+                
+            }
+            fputcsv($fh, $row);
+            
+        }
+        foreach($heads as $h=>$v) {
+            $heads[$h] = explode(':', $h);
+        }
+        
+        
+        foreach($data as $item=>$recs) {
+            fputcsv($fh, $this->toRow($recs, $heads));
+            
+        }
+        
+         
+        exit;
+          
+        
+    }
+    function toRow($recs, $head) {
+        $ret = array();
+       //echo '<PRE>';print_r($head);exit;
+        
+        foreach($head as $h=>$har) {
+            //print_R($har);
+            
+            if (count($har) == 1) {
+                // simple key - eg itmems.
+                $ret[] = $recs[0]->{$h};
+                continue;
+            }
+          
+            // complex stuff..
+            $val = 0;
+            foreach($recs as $r) {
+                
+                if (count($har) == 2) {
+                    // total..
+                    
+                    if ($r->cohist_year != $har[1]) {
+                        continue;
+                    }
+                    $val += $r->{$har[0]};
+                    continue;
+                        
+                }
+                //print_R($har);
+                //print_r($r);
+                
+                if ($r->cohist_country != $har[1]) {
+                    continue;
+                }
+                if ($r->cohist_year != $har[2]) {
+                    continue;
+                }
+                //echo "GOT $har[0] \n";
+                $val += $r->{$har[0]};
+                // got matching year and country..
+            }
+            $ret[] = $val;
+            
+        }
+        //print_R($ret);exit;
+        
+        // totals...
+        return $ret;
+        
+        
+        
+        
+    }
+    
+}
+
+
diff --git a/Reports/SalesByCustomer.php b/Reports/SalesByCustomer.php
new file mode 100644 (file)
index 0000000..6daa2cf
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_SalesByCustomer extends Pman_Xtuple_Reports_Base
+{
+    
+     
+    function get()
+    {
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+           
+        
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+            
+            SELECT
+                cust_number,
+                cust_name,
+                qtysold,
+                ROUND(soldat,2) as soldat,
+                ROUND(fifocost,2) as fifocost,
+                CASE WHEN fifocost > 0 THEN
+                    ROUND(soldat / fifocost, 1)
+                ELSE
+                    0
+                END as profitrate
+            FROM
+            
+                
+                (SELECT
+                    cust_number,
+                    cust_name,
+                    ROUND(sum(shipitem_qty),0) as qtysold,
+                    sum(shipitem_qty *  currtobase(invchead_curr_id,  invcitem_custprice, invchead_shipdate)) as soldat,
+                    sum(invfifo_totalcost) as fifocost
+                    
+                    
+                    FROM
+                        shipitem
+                    
+                    LEFT JOIN
+                        invcitem
+                    ON
+                        invcitem_id = shipitem_invcitem_id
+                    
+                    LEFT JOIN
+                        shiphead
+                    ON
+                        shiphead_id = shipitem_shiphead_id
+                    
+                    LEFT JOIN
+                        invchead
+                    ON
+                        invchead_id = invcitem_invchead_id
+                    
+                    LEFT JOIN
+                        invdetailview
+                    ON
+                        invhist_id = shipitem_invhist_id
+                    
+                    LEFT JOIN
+                        custinfo
+                    ON
+                        invchead_cust_id = cust_id
+                    
+                    WHERE
+                        shiphead_shipdate >= '$date_from'
+                        AND
+                        shiphead_shipdate <= '$date_to'
+                    
+                    GROUP BY
+                        cust_number,
+                        cust_name
+                        
+                )  rq      
+            ORDER BY
+                soldat DESC
+             
+        ");
+        $this->toCsv($q,  explode(',', 'cust_number,cust_name,qtysold,soldat,fifocost,profitrate'));
+                
+                
+        
+        
+    }
+    
+    
+}
+
diff --git a/Reports/SalesByProduct.php b/Reports/SalesByProduct.php
new file mode 100644 (file)
index 0000000..8b26b34
--- /dev/null
@@ -0,0 +1,89 @@
+<?php 
+
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_SalesByProduct extends Pman_Xtuple_Reports_Base
+{
+     
+    function get()
+    {
+        $date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        $date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+           
+        $q = DB_DataObject::factory('custinfo');
+        $q->query("
+            
+            SELECT
+                item_number,
+                item_descrip1,
+                qtysold,
+                ROUND(soldat,2) as soldat,
+                ROUND(fifocost,2) as fifocost,
+                CASE WHEN fifocost > 0 THEN
+                    ROUND(soldat / fifocost, 1)
+                ELSE
+                    0
+                END as profitrate
+            FROM
+            
+                
+                (SELECT
+                    item_number,
+                    item_descrip1,
+                    ROUND(sum(shipitem_qty),0) as qtysold,
+                    sum(shipitem_qty * currtobase(invchead_curr_id,  invcitem_custprice, invchead_shipdate)) as soldat,
+                    sum(invfifo_totalcost) as fifocost
+                    
+                    
+                    FROM
+                        shipitem
+                    
+                    LEFT JOIN
+                        invcitem
+                    ON
+                        invcitem_id = shipitem_invcitem_id
+                    
+                    LEFT JOIN
+                        shiphead
+                    ON
+                        shiphead_id = shipitem_shiphead_id
+                    
+                    LEFT JOIN
+                        invchead
+                    ON
+                        invchead_id = invcitem_invchead_id
+                    
+                    LEFT JOIN
+                        invdetailview
+                    ON
+                        invhist_id = shipitem_invhist_id
+                    
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        itemsite_id = invhist_itemsite_id
+                        
+                    LEFT JOIN
+                        item
+                    ON
+                        item_id = itemsite_item_id
+                    
+                    WHERE
+                        shiphead_shipdate >= '$date_from'
+                        AND
+                        shiphead_shipdate <= '$date_to'
+                    
+                    GROUP BY
+                        item_number,
+                        item_descrip1
+                        
+                )  rq      
+            ORDER BY
+                soldat DESC
+             
+        ");
+        
+               
+        $this->toCsv($q,  explode(',', 'item_number,item_descrip1,qtysold,soldat,fifocost,profitrate'));
+    }
+}
diff --git a/Reports/StockAtLocation.php b/Reports/StockAtLocation.php
new file mode 100644 (file)
index 0000000..a83c713
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+require_once 'Pman/Xtuple/Reports/Base.php';
+
+class Pman_Xtuple_Reports_StockAtLocation extends Pman_Xtuple_Reports_Base
+{
+     
+    
+    function get()
+    {
+        $sdate = '-05-01';
+        $edate = '-04-30';
+        //if (preg_match('/sg.php$/', $this->baseURL)) {
+        //    $sdate = '-10-01';
+        //    $edate = '-09-30';
+        //}
+        $sy = strtotime(date('Y') . $sdate) > time() ? date('Y') : (date('Y')+1);
+       
+        $q = DB_DataObject::factory('location');
+        
+        //DB_DataObject::DebugLevel(1);
+       // $q->autoJoin();
+        $q->selectAdd();
+        
+        $q->selectAdd('location_name, location_descrip');
+        $cols = array('location_name', 'location_descrip');
+        
+        for ($y = 2008; $y < $sy + 1; $y++) {
+            $dt = $y . $sdate;
+       
+            $q->selectAdd( "
+                invdetail_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id, 1)
+                as  qty_on_hand_eofy_$y,
+                invdetail_location_atdate('$dt'::date + INTERVAL '1 DAY', location_id , -1)
+                as  qty_negative_eofy_$y
+                
+                ");
+            $cols[] = "qty_negative_eofy_$y";
+            $cols[] = "qty_on_hand_eofy_$y";
+        }
+        
+        $q->orderBy('location_name ASC');
+        //$date_from = date('Y-m-d', strtotime($_REQUEST['date_from']));
+        //$date_to   = date('Y-m-d', strtotime($_REQUEST['date_to']));
+        //DB_DataObject::debugLevel(1);
+        $q->find();
+         
+         
+         
+        $this->toCsv($q,   $cols);
+                
+                 
+    }
+    
+    
+}
+
diff --git a/Reports/reportstyle.css b/Reports/reportstyle.css
new file mode 100644 (file)
index 0000000..97e2574
--- /dev/null
@@ -0,0 +1,37 @@
+
+.accnt-report {
+    margin:15px;
+}
+
+.accnt-report,
+td {
+    font-family: sans-serif;
+    
+}
+td.accnt-name {
+    white-space: pre;
+}
+tr.accnt-type-G td.accnt-name {
+    font-weight: bold;
+}
+tr.accnt-type-T td.accnt-value {
+    border-top: 1px solid #ccc;
+    font-weight: bold;
+}
+
+tr.accnt-type-G td {
+    border-top: 1px solid #ccc;
+}
+
+td.accnt-value {
+    text-align: right;
+    padding-right: 30px;
+}
+
+.accnt-report h1 {
+    font-size: 16px;
+}
+.accnt-report table {
+    margin-top:15px;
+}
\ No newline at end of file
diff --git a/Roo.php b/Roo.php
new file mode 100644 (file)
index 0000000..6f440aa
--- /dev/null
+++ b/Roo.php
@@ -0,0 +1,129 @@
+<?php
+
+
+require_once 'Pman/Roo.php';
+
+/**
+ *
+ * Relay into 'main database' for queries..
+ *
+ */
+
+class Pman_Xtuple_Roo extends Pman_Roo
+{
+    
+    // getAuth.. the same..
+    function isMain()
+    {
+        $xt = HTML_FlexyFramework::get()->Xtuple;
+        $main = empty($xt['main_db']) ? false : $xt['main_db'];
+        // migration process can not transfer.
+        // transfer if necessary..
+        $do = DB_DAtaObject::Factory('Person');
+        $ret =  !$main || $do->database() == $main;
+        //var_Dump($ret);
+        return $ret;
+             
+        
+        
+    }
+    
+    function get($tab)
+    {
+        if (isset($_REQUEST['_roo_office'])) {
+            return $this->relay('GET',$tab, $_REQUEST['_roo_office']);
+        }
+        
+        
+        if ($this->isMain()) {
+            return parent::get($tab);
+        }
+        
+        $this->relay('GET', $tab);
+    }
+    
+    function post($tab)
+    {
+        if (isset($_REQUEST['_roo_office'])) {
+            return $this->relay('POST',$tab, $_REQUEST['_roo_office']);
+        }
+        
+        if ($this->isMain()) {
+            return parent::post($tab);
+        }    
+        $this->relay('POST', $tab);
+        
+    }
+    function relay($meth, $tab, $office = false)
+    {
+        
+        $office = preg_replace('/[^a-z]+/i','', $office);
+        if (!file_exists($this->rootDir.'/'. $office . '.php')) {
+            // error technically.
+            $this->jerr('office no available');
+        }
+        
+        //echo "RELAY?";
+        $ff = HTML_FlexyFramework::get();
+        require_once 'HTTP/Request.php';
+        
+        if (empty($ff->Xtuple['main_url'])) {
+            $ff->Xtuple['main_url'] = 'http://localhost'. $this->baseURL;
+        }
+        
+        $url= $ff->Xtuple['main_url'] . '/Roo/'. $tab ;
+        if (!empty($office)) {
+            $mu = preg_replace('#[a-z]+\.php$#', '', $ff->Xtuple['main_url']) .
+                preg_replace('#[^a-z]+#', '', $office) . '.php';
+            $url=$mu. '/Roo/'. $tab ;
+        }
+        
+        //var_dump($url);exit;
+        $req = new HTTP_Request( $url );
+        
+        $req->setMethod(
+                    $meth == 'POST' ?
+                        HTTP_REQUEST_METHOD_POST :
+                        HTTP_REQUEST_METHOD_GET
+        );
+        
+        if ($meth == 'POST') {
+            $req->addPostData( $_POST );
+        } else {
+            $req->addRawQueryString($_SERVER['QUERY_STRING']);
+        }
+        
+        
+        $res = $req->sendRequest();
+        if (is_a($res,'PEAR_Error')) {
+            $this->jerr("MAIN REQUEST RETURNED ERROR: ". $res->toString()); 
+        }
+        //echo '<PRE>';print_r($req);exit;
+        
+        foreach($req->getResponseHeader() as $k=>$v) {
+            switch($k) {
+                case 'connection':
+                case 'transfer-encoding':
+                case 'date':
+                case 'server':
+                case 'x-powered-by':
+                case 'expires':
+                case 'cache-control':
+                case 'pragma':
+                    $k = false;
+                default:
+                    break;
+            }
+            if (!$k) {
+                continue;
+            }
+            //echo $k .": $v <BR/>";
+            header(ucfirst($k) .": $v");
+        }
+        
+        
+        
+        echo $req->getResponseBody();exit;
+         
+    }
+}
\ No newline at end of file
diff --git a/Setup/ResetDB.php b/Setup/ResetDB.php
new file mode 100644 (file)
index 0000000..ed30437
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+/*
+ do this first..
+   dropdb -U admin xtupledemo  
+   createdb -U admin xtupledemo     
+      
+*/
+require_once 'Pman.php';
+
+class Pman_Xtuple_Setup_ResetDB extends Pman
+{
+    static $cli_desc = "Reset database";
+    
+    static $cli_opts = array(
+        'run' => array(
+            'desc' => 'Run the code (otherwise only instructions are now shown)',
+            'default' => 0,
+            'short' => 'r',
+            'min' => 1,
+            'max' => 1,
+            
+        ),
+        'base' => array(
+            'desc' => 'Base Currency',
+            'default' => '',
+            'short' => 'b',
+            'min' => 1,
+            'max' => 1,
+            
+        ),
+        'dbfile' => array(
+            'desc' => 'Base database file (eg. /home/xxx/postbooks_demo-3.8.4.backup - or "default" to use quickstart db',
+            'default' => '',
+            'short' => 'f',
+            'min' => 1,
+            'max' => 1,
+            
+        )  
+    );
+      
+     
+    function getAuth()
+    {
+        if (!HTML_FlexyFramework::get()->cli) {
+            die("not cli");
+        }
+    }
+    
+    function get($u, $opts)
+    {
+        $u = parse_url(HTML_FlexyFramework::get()->database);
+        $db= basename($u['path']);
+        $un = $u['user'];
+       // $file = $_SERVER['HOME'] .'/Dropbox/xtuple_working/postbooks_demo-3.7.4.backup';
+        
+        if (empty($opts['dbfile'])) {
+            $this->jerr("no database file selected.");
+        }
+        $file = $opts['dbfile'];
+        if ($file == 'default') {
+            $file = $_SERVER['HOME'] .'/postbooks_quickstart-3.8.4.backup';
+        }
+        
+        
+        
+        if (!$opts['run']) {
+            echo "DO THIS FIRST\n";
+            $cmd = "dropdb -U {$un} {$db}";
+            
+            echo "$cmd\n";
+            /*
+            $ret = `$cmd`;
+            echo $ret;
+            ///var_dump($ret);exit;
+            if (preg_match('/ERROR/i', $ret)) {
+                die("COULD NOT DROP DATABASE");
+            }
+            
+            */
+            $cmd = "createdb -U {$un} {$db}";
+            
+            echo "$cmd\n";
+            
+        
+            die("\nUse --run=1 to actually run this..\n\n");
+        }
+        
+        if (!file_exists($file)) {
+            die("can not file xtuple database file : $file\n");
+        }
+        
+        
+        /*
+        echo `$cmd`;
+        */
+        $cmd = "pg_restore -U {$un} -d {$db} {$file} ";
+        
+        echo "$cmd\n";
+        echo `$cmd`;
+        
+        
+        // import base data..
+        $ff = HTML_FlexyFramework::get();
+        
+        $cmd = "php {$_SERVER['SCRIPT_NAME']} Core/UpdateDatabase";
+        echo "$cmd\n"; 
+        echo `$cmd`;
+        echo `$cmd`;
+        
+        
+        $cmd = "php {$_SERVER['SCRIPT_NAME']} Core/RefreshDatabaseCache";
+        echo "$cmd\n";
+        echo `$cmd`;
+        
+        if(!empty($opts['base'])){
+            $cmd = "php {$_SERVER['SCRIPT_NAME']} Xtuple/UpdateDatabase/Curr_Symbol --base={$opts['base']}";
+            echo "$cmd\n";
+            echo `$cmd`;
+        }
+        
+        $do = DB_DataObject::Factory('person');
+        $CN = strtoupper(substr($do->database(),-2));
+        
+        
+        // clear cache..
+        $uinfo = posix_getpwuid( posix_getuid () ); 
+        $user = $uinfo['name'];
+        
+        $cd = ini_get('session.save_path') .'/' .    "xtuple{$CN}-". $user;
+        $cmd = "rm -rf $cd";
+        echo "$cmd\n";
+        echo `$cmd`;
+        
+        exit;
+         
+            
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/TestAuth.php b/TestAuth.php
new file mode 100644 (file)
index 0000000..b17be80
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+require_once 'Pman.php';
+
+class Pman_Xtuple_TestAuth extends Pman
+{
+    static $cli_desc = "Test auth code...";
+    
+    function getAuth()
+    {
+        if (!HTML_FlexyFramework::get()->cli) {
+            die("not cli");
+        }
+    }
+    
+    function get()
+    {
+        $this->init();
+        DB_DataObject::DebugLevel(1);
+        $oc = $this->loadOwnerCompany();
+        
+        $p = DB_DataObject::factory('Person');
+        if ($p->get('email', 'test@roojs.com')) {
+            $p->delete();
+        }
+        
+        
+        $p = DB_DataObject::factory('Person');
+        
+        $p->setFrom(array(
+            'email' => 'test@roojs.com',
+            'name' => 'test',
+            'company_id' => $oc->id,
+            
+        ));
+        $p->setPassword("test123");
+        $p->insert();
+        $p->onInsert(array(),$this);
+        print_R($p);exit;
+         
+        //onUpdate($old, $request,$roo)
+    
+    
+   
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/UpdateDatabase.php b/UpdateDatabase.php
new file mode 100644 (file)
index 0000000..356810c
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ *
+ * Setup the core values in the database
+ *
+ *
+ */
+
+require_once 'Pman.php';
+class Pman_Xtuple_UpdateDatabase extends Pman
+{
+    
+    static $cli_desc = "Update SQL - Beta";
+    
+    static $cli_opts = array(
+        'source' => array(
+            'desc' => 'Source directory for json files.',
+            'short' => 'f',
+            'default' => '',
+            'min' => 1,
+            'max' => 1,
+        ),
+        'base' => array(
+            'desc' => 'Base Currency',
+            'default' => '',
+            'short' => 'b',
+            'min' => 1,
+            'max' => 1,
+            
+        )
+        
+    );
+    
+    var $cli = false; 
+    function getAuth() {
+        
+        
+        $ff = HTML_FlexyFramework::get();
+        if (!empty($ff->cli)) {
+            $this->cli = true;
+            return true;
+        }
+        die("NOT ALLOWED");
+    }
+    function get($k = '',$opt)
+    {
+        $k = strtolower($k);
+        
+        if($k == 'accnt'){
+            if(empty($opt['source'])){
+                die("Missing Source directory for account json files! Try -f [JSON file path] \n");
+            }
+            
+            if (!file_exists($opt['source'])) {
+                die("can not found account json file : {$opt['source']} \n");
+            }
+
+            $accounts = json_decode(file_get_contents($opt['source']),true);
+            
+            DB_DataObject::factory('accnt')->importFromArray($this, $accounts);
+            
+            die("DONE! \n");
+        }
+        
+        if($k == 'curr_symbol'){
+            if(!empty($opt['base'])){
+                DB_DataObject::factory('curr_symbol')->setBase($this, $opt['base']);
+                die("DONE! \n");
+            }
+            
+            if(!empty($opt['source'])){
+                
+                if (!file_exists($opt['source'])) {
+                    die("can not found currency json file : {$opt['source']} \n");
+                }
+                
+                $currencies = json_decode(file_get_contents($opt['source']),true);
+                
+                DB_DataObject::factory('curr_symbol')->importFromArray($this, $currencies);
+                die("DONE! \n");
+            }
+            
+            die("Missing Base Currency or Source directory for Currency json files! Try -b [base currency] or -f [JSON file path]\n");
+        }
+        
+        if($k == 'location'){
+            if(empty($opt['source'])){
+                die("Missing Source directory for location json file! Try -f [JSON file path] \n");
+            }
+            
+            if (!file_exists($opt['source'])) {
+                die("can not found location json file : {$opt['source']} \n");
+            }
+            
+            $locations = json_decode(file_get_contents($opt['source']),true);
+            
+            DB_DataObject::factory('location')->importFromArray($this, $locations);
+            
+            die("DONE! \n");
+        }
+        
+        if($k == 'terms'){
+            if(empty($opt['source'])){
+                die("Missing Source directory for terms json file! Try -f [JSON file path] \n");
+            }
+            
+            if (!file_exists($opt['source'])) {
+                die("can not found terms json file : {$opt['source']} \n");
+            }
+            
+            $terms = json_decode(file_get_contents($opt['source']),true);
+            
+            DB_DataObject::factory('terms')->importFromArray($this, $terms);
+            
+            die("DONE! \n");
+        }
+        
+        
+        $this->updateData($k);
+        
+    }
+    
+    
+    
+    
+    function updateData($k='') {
+        //DB_DataObject::debugLevel(1);
+        $tables = empty($k) ? array(
+                
+//                'curr_symbol', //?? fixme
+                'custtype',
+                'plancode',
+                'prodcat',
+                'classcode',
+                'curr_rate',
+                'char',
+                'taxzone',
+                'taxtype',
+                'expcat',
+//                'terms', //?? add
+                
+//                'location', //?? just check hat one exists.
+        ) : array($k);
+        
+        
+        
+        foreach($tables as $t) {
+            $cs = DB_DataObject::factory($t);
+            $cs->initDatabase($this);
+        
+        }
+        
+        
+    }
+}
\ No newline at end of file
diff --git a/Verify.php b/Verify.php
new file mode 100644 (file)
index 0000000..50a21e2
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+require_once 'Pman/Roo.php';
+class Pman_Xtuple_Verify extends Pman_Roo {
+    function getAuth() {
+        if(HTML_FlexyFramework::get()->cli) {
+            return true;
+        }
+        return parent::getAuth();
+    }
+
+
+    function toParams($ar) {
+        $ret = array();
+        foreach($ar as $k=>$v) {
+            $ret[] = urlencode($k).'='.urlencode($v);
+        }
+        return implode('&', $ret);
+    }
+
+    function get() {
+        die("You must define get() in your class extension");
+    }
+}
diff --git a/VerifyAP.php b/VerifyAP.php
new file mode 100644 (file)
index 0000000..a8b7ed2
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+require_once 'Verify.php';
+class Pman_Xtuple_VerifyAP extends Pman_Xtuple_Verify {
+
+    function get() {
+        
+        $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+
+        // dump old db -> jsondecode -> get file contents ~/Dropbox/olddb...... [TBD]
+        // get Netsuite_Accounts from SG and HK and merge 
+        //
+        // review the "View Financial Report" to see how it's pulling
+        //  the Balances for the internal accounting accounts
+        //
+        //
+        // DB_DataObject::debugLevel(1);
+
+        
+        //DB_DataObject::DebugLevel(1);
+        $db = DB_DataObject::factory('vendinfo');
+        
+        $db->selectAdd(); 
+       /*   currtocurr(
+                            apopen_curr_id,
+                            getcurrid('HKD') ,
+                            CASE WHEN (apopen_doctype IN ('C', 'R')) THEN
+                                (apopen_amount - apopen_paid) * -1.0
+                                ELSE
+                                (apopen_amount - apopen_paid)
+                                END,
+                            apopen_distdate
+                            
+                   
+                    ) as apopen_remaining_hkd
+              
+             
+        ");
+       */
+       //DB_DataObject::DebugLevel(1);
+       $db->selectAdd("
+            vend_number,
+            
+            
+           
+            ROUND(
+                (SELECT
+                    SUM(
+                         currtocurr(
+                             apopen_curr_id,
+                             getcurrid('HKD' ) ,
+                        
+                             CASE WHEN (apopen_doctype IN ('C', 'R')) THEN
+                                (apopen_amount - apopen_paid) * -1.0
+                                ELSE
+                                (apopen_amount - apopen_paid)
+                                END
+                             ,
+                             apopen_distdate
+                         )
+                     )
+                     FROM apopen
+                         
+                     WHERE
+                         apopen_vend_id = vend_id
+                         AND
+                         apopen_open
+                 ),
+                3) as   balance
+            
+              
+             
+        ");
+        
+         /*
+        $db->selectAdd("
+            vend_number,
+            
+        
+            (SELECT
+                 COALESCE(SUM(currtocurr(
+                    apopen_curr_id,
+                    getcurrid('HKD' ) ,
+                    open_amount,
+                    NOW()::date
+                )),0)
+                FROM
+                    (SELECT 
+                            
+                        apopen_curr_id,
+                        COALESCE(
+                            SUM(
+                                CASE WHEN (apopen_doctype IN ('C', 'R')) THEN
+                                   (apopen_amount - apopen_paid) * -1.0
+                                   ELSE
+                                   (apopen_amount - apopen_paid)
+                                   END
+                                ),
+                                0
+                        ) AS open_amount
+                    
+                        FROM apopen
+                            WHERE
+                                apopen_vend_id = vend_id
+                                AND
+                                apopen_open
+                            GROUP BY
+                                apopen_curr_id
+                    ) subsel
+            ) as balance
+            */
+        $db->orderBy('vend_number ASC');
+        
+        $xdb =$db->fetchAll('vend_number', 'balance');
+        //ksort($xtd);
+       //  exit;
+        if ($sd != 'HK') {
+            // we only report on HK data..
+            echo json_encode($xdb);
+            exit;
+        }
+        $hkdata = $xdb;
+        
+        $sgdata = (array) json_decode(file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyAP"));
+        
+        //print_R($sgdata);exit;
+        //echo '<PRE>' ;print_R( $hkdata);
+        
+       //  echo '<PRE>';var_dump( $sgdata );exit;
+        // at this point we
+        $old = $this->oldParse('HK');
+        //echo"<PRE>"; print_r($old);
+        
+        foreach($this->oldParse('SG') as $k =>$v) {
+            $old[$k] = $v;
+        }
+        
+        
+          
+        //echo '<PRE>';
+        //var_dump($old);
+       //(int) print_r(array_keys($sgdata));
+       // print_r(array_keys($old));
+        //exit;
+        $historyfor = array();
+        header('Content-type: text/csv');
+        header( 'Content-Disposition: attachment;filename=APsummary.csv');
+        $fh = fopen('php://output','w');
+        
+        fputcsv($fh, array("Customer",  '','',"NETSUITE", "HK", "SG", "difference"));
+        foreach($old as $k=>$v) {
+            $hk = isset($hkdata[$k]) ? $hkdata[$k] : 0;
+            $sg = isset($sgdata[$k]) ? $sgdata[$k] : 0;
+            
+            if ( ( ($hk + $sg) - $v) == 0.0) {
+                continue;
+            }
+            
+            if (abs(( ($hk + $sg) - $v)) > 1.5) {
+                $historyfor[$k] = $v;
+            } else {
+                continue;
+            }
+            
+            fputcsv($fh, array(
+                $k,
+                '','',
+                $v,
+                $hk,
+                $sg,
+                ($hk + $sg) - $v
+            ));
+        }
+        
+        
+        
+        
+        
+        // aropen  - columns... docdate, doctype, docnumber,amount, paid,
+        $max = 999;
+        $i = 0;
+        foreach($historyfor as $vend=>$expect) {
+            $i++;
+            if ($i > $max) {
+                break;
+            }
+            $args = $this->toParams(array(
+                'query[vend_number]'=> trim($vend),
+                 'query[in_currency]'=> 'HKD', 
+                'sort'=>'apopen_docdate,apopen_id',
+                'dir'=>'ASC',
+                
+                
+                'csvCols[0]' => 'apopen_docdate',
+                'csvCols[1]' => 'apopen_doctype',
+                'csvCols[2]' => 'apopen_docnumber_r',
+                'csvCols[3]' => 'apopen_amount_hkd',
+                'csvCols[4]' => 'apopen_paid_hkd',
+                'csvCols[5]' => 'apopen_remaining_hkd',
+                'csvCols[6]' => 'apopen_running_hkd',
+                 
+                'csvTitles[0]' => 'Date',
+                'csvTitles[1]' => 'Type',
+                'csvTitles[2]' => 'Doc no.',
+                'csvTitles[3]' => 'Amount',
+                'csvTitles[4]' => 'Paid',
+                'csvTitles[5]' => 'Outstanding',
+                'csvTitles[6]' => 'Running',
+                'start' => 0,
+                'limit' => 800
+                
+            ));
+            
+            //fwrite($fh, "\n\n\"http://www.bloomandgrowdirect.com/xtuple/{$lprefix}hk.php/Roo/apopen?$args\"\n");
+            //exit;
+            // fwrite($fh, "\n\n\"http://www.bloomandgrowdirect.com/xtuple/{$lprefix}sg.php/Roo/apopen?$args\"\n");
+            $hk = isset($hkdata[$vend]) ? $hkdata[$vend] : 0;
+            $sg = isset($sgdata[$vend]) ? $sgdata[$vend] : 0;
+            
+            fwrite($fh, "\n\n-- ". $vend ." ,,Expecting:, $expect, HK:, $hk, SG: $sg\n");
+                       
+                       
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}hk.php/Roo/apopen?$args"));
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Roo/apopen?$args"));
+        }
+        //echo '<PRE>';
+        //print_R($old);
+        //exit;
+        
+        
+        exit;
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+    }
+    function oldParse($cn)
+    {
+        $har = explode('/', realpath(__FILE__));
+        $home = '/home/'. $har[2];
+        $fn = "$home/Dropbox/xtuple_working/old_database_snapshot/$cn/Netsuite_Vendor.sql.json.all";
+        $ar = file($fn);
+        $ret = array();
+        foreach($ar as $i=>$l) {
+            if (!$i) continue;
+            $line = json_decode($l);
+         
+            $ret[strtoupper($line->entityId)] =    $line->balance;
+        }
+        return $ret;
+         
+
+        
+    }
+    
+}
diff --git a/VerifyAR.php b/VerifyAR.php
new file mode 100644 (file)
index 0000000..6acc4ac
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+require_once 'Verify.php';
+class Pman_Xtuple_VerifyAR extends Pman_Xtuple_Verify {
+
+    function get() {
+        
+        $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+
+        // dump old db -> jsondecode -> get file contents ~/Dropbox/olddb...... [TBD]
+        // get Netsuite_Accounts from SG and HK and merge 
+        //
+        // review the "View Financial Report" to see how it's pulling
+        //  the Balances for the internal accounting accounts
+        //
+        //
+        // DB_DataObject::debugLevel(1);
+
+        
+           //DB_DataObject::DebugLevel(1);
+        $db = DB_DataObject::factory('custinfo');
+        $db->selectAdd("
+            cust_number, 
+            (SELECT
+                COALESCE(
+                    SUM(
+                        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN
+                           (aropen_amount - aropen_paid) * -1.0
+                           ELSE
+                           (aropen_amount - aropen_paid)
+                           END
+                    ),
+                0.0)
+                FROM aropen
+                WHERE
+                    aropen_cust_id = cust_id
+                    AND
+                    aropen_open
+            ) as balance
+        ");
+        $db->orderBy('cust_number ASC');
+        
+        $xdb =$db->fetchAll('cust_number', 'balance');
+;       //ksort($xtd);
+        
+        
+        //if ($sd != 'HK') {
+            // we only report on HK data..
+        //    echo json_encode($xdb);
+        //    exit;
+        //}
+        $hkdata = $xdb;
+        
+        //$sgdata = (array) json_decode(file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyAR"));
+       // echo '<PRE>';var_dump($sgdata);exit;
+        
+       //echo '<PRE>';print_R($sgdatas['97']);exit;
+        
+       //  echo '<PRE>';var_dump( $sgdata );exit;
+        // at this point we
+        //$old = $this->oldParse('HK');
+        
+        
+        foreach($this->oldParse('SG') as $k =>$v) {
+            $old[$k] = $v;
+        }
+        
+        
+          
+        //echo '<PRE>';
+        //var_dump($old);
+       //(int) print_r(array_keys($sgdata));
+       // print_r(array_keys($old));
+        //exit;
+        
+        $out = array();
+        
+      
+        $out[] = array("Customer",  "spacer","spacer", "NETSUITE", "HK", "SG", "difference");
+        foreach($old as $k=>$v) {
+            $k = trim($k);
+            $hk = isset($hkdata[''.$k]) ? $hkdata[''.$k] : 0;
+            $sg = isset($sgdata[''.$k]) ? $sgdata[''.$k] : 0;
+             
+            if ( ( ($hk + $sg) - $v) == 0.0) {
+                continue;
+            }
+            
+            if (abs(( ($hk + $sg) - $v)) < 1.5) {
+                continue;
+            }
+            
+            
+            $historyfor[$k] = $v;
+            
+            
+            
+            $out[] =  array(
+                $k,
+                '',
+                '',
+                $v,
+                $hk,
+                $sg,
+                ($hk + $sg) - $v
+            );
+        }
+        
+        
+          header('Content-type: text/csv');
+        header( 'Content-Disposition: attachment;filename=ARreport.csv');
+        $fh = fopen('php://output','w');
+        foreach($out as $o) {
+            fputcsv($fh, $o);
+        }
+        fclose($fh);
+        exit;
+        //exit;
+        // we now have all the data...
+        
+        // for ar - look in aropen..
+        // eg. sgtru = SG based (224
+        
+        // aropen  - columns... docdate, doctype, docnumber,amount, paid,
+        $max = 99999;
+        $i = 0;
+        foreach($historyfor as $cust=>$expect) {
+            $i++;
+            if ($i > $max) {
+                break;
+            }
+            $args = $this->toParams(array(
+                'query[cust_number]'=> trim($cust),
+                 
+                'sort'=>'aropen_docdate,aropen_id',
+                'dir'=>'ASC',
+                
+                
+                'csvCols[0]' => 'aropen_docdate',
+                'csvCols[1]' => 'aropen_doctype',
+                'csvCols[2]' => 'aropen_docnumber_r',
+                'csvCols[3]' => 'aropen_amount',
+                'csvCols[4]' => 'aropen_paid',
+                'csvCols[5]' => 'aropen_remaining',
+                'csvCols[6]' => 'aropen_running',
+                 
+                'csvTitles[0]' => 'Date',
+                'csvTitles[1]' => 'Type',
+                'csvTitles[2]' => 'Doc no.',
+                'csvTitles[3]' => 'Amount',
+                'csvTitles[4]' => 'Paid',
+                'csvTitles[5]' => 'Outstanding',
+                'csvTitles[6]' => 'Running',
+                'start' => 0,
+                'limit' => 800
+                
+            ));
+            
+            //fwrite($fh, "\n\n\"http://www.bloomandgrowdirect.com/xtuple/{$lprefix}hk.php/Roo/aropen?$args\"\n");
+            //fwrite($fh, "\n\n\"http://www.bloomandgrowdirect.com/xtuple/{$lprefix}sg.php/Roo/aropen?$args\"\n");
+            
+            fwrite($fh, "\n\n-- ". $cust ." ,,Expecting:, $expect\n");
+                       
+                       
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}hk.php/Roo/aropen?$args"));
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Roo/aropen?$args"));
+        }
+        //echo '<PRE>';
+        //print_R($old);
+        //exit;
+        
+        
+        
+        exit;
+        
+        
+        
+        
+        
+        
+        
+    }
+    function oldParse($cn)
+    {
+        $har = explode('/', realpath(__FILE__));
+        $home = '/home/'. $har[2];
+        $fn = "$home/Dropbox/xtuple_working/old_database_snapshot/$cn/Netsuite_Customer.sql.json.all";
+        $ar = file($fn);
+        $ret = array();
+        foreach($ar as $i=>$l) {
+            if (!$i) continue;
+            $line = json_decode($l);
+         
+            $ret[strtoupper($line->entityId)] =    $line->balance;
+        }
+        return $ret;
+         
+
+        
+    }
+    
+}
diff --git a/VerifyAccounts.php b/VerifyAccounts.php
new file mode 100644 (file)
index 0000000..490acdc
--- /dev/null
@@ -0,0 +1,421 @@
+<?php
+require_once 'Verify.php';
+class Pman_Xtuple_VerifyAccounts extends Pman_Xtuple_Verify {
+
+    function get()
+    {
+        
+       // die("START?");
+        $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+
+        // dump old db -> jsondecode -> get file contents ~/Dropbox/olddb...... [TBD]
+        // get Netsuite_Accounts from SG and HK and merge 
+        //
+        // review the "View Financial Report" to see how it's pulling
+        //  the Balances for the internal accounting accounts
+        //
+        //
+        // DB_DataObject::debugLevel(1);
+
+        $db = DB_DataObject::factory('accnt');
+        $db->selectAdd();
+        $db->selectAdd("accnt_number, 
+                    accnt_descrip,
+                    currtocurr(
+                        baseCurrId(),
+                        getcurrid('HKD' ) ,
+                        COALESCE((SELECT SUM(gltrans_amount) FROM gltrans WHERE gltrans_accnt_id=accnt_id),0),
+                        NOW()::date
+                    ) as balance");
+        // $db->whereAdd('accnt_curr_id NOT IN ( 9,6) '); // THB, TWD - not conversion rates avail..        
+        $db->find();
+        $xdb =array();
+        while($db->fetch()) {
+            $row = $db->toArray(FALSE, TRUE);
+            $xtd[$row['accnt_number']] = $row;
+        }
+        //ksort($xtd);
+        
+        
+        if ($sd != 'HK') {
+            // we only report on HK data..
+            echo json_encode($xtd);
+            exit;
+        }
+        $hkdata = $xtd;
+        
+        $xtd = (array) json_decode(file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyAccounts"));
+        $sgdata = array();
+        foreach($xtd as $k=> $v) {
+            $sgdata[(int)$k] = $v;
+        }
+        //print_R($sgdata);exit;
+        
+       //  echo '<PRE>';var_dump( $sgdata );exit;
+        // at this point we
+        $old = $this->oldParse('HK');
+        
+        
+        foreach($this->oldParse('SG') as $k =>$v) {
+            $old[$k] = $v;
+        }
+        
+        
+        
+        foreach($hkdata as $k=>$v) {
+            $k = (int)$k;
+            if (isset($old[$k])) {
+                continue;
+            }
+            $v = (object)$v;
+            $old[$k] = array(
+                'description' => $v->accnt_descrip,
+                'id' =>  $v->accnt_number,
+                
+            );
+        }
+        foreach($sgdata as $k=>$v) {
+            $k = (int)$k;
+            if (isset($old[$k])) {
+                continue;
+            }
+            $v = (object)$v;
+            $old[$k] = array(
+                'description' => $v->accnt_descrip,
+                'id' =>  $v->accnt_number,
+                 
+            );
+        }
+        //echo '<PRE>';
+        //var_dump($old);
+       //(int) print_r(array_keys($sgdata));
+       // print_r(array_keys($old));
+        foreach($old as $k=>$xx) {
+            
+            //var_dump(array($k, $sgdata[(string)$k]));
+            
+            $old[$k]['hkbalance']  = 0;
+            $old[$k]['sgbalance']  = 0;
+            if (isset($hkdata[(int)$k])) {
+                $v =(object)($hkdata[(int)$k]);
+                //print_R($v);
+                $old[(int)$k]['hkbalance'] = $v->balance;
+            }
+            if (isset($sgdata[(string)$k])) {
+                //echo "GOT SG? $k<BR>";
+                $v =(object) ($sgdata[(int)$k]);
+                $old[(int)$k]['sgbalance'] = $v->balance;
+            }
+            
+        }
+        //die("GOT THIS FAR?");
+        //exit;
+        
+        
+        header('Content-type: text/csv');
+        header( 'Content-Disposition: attachment;filename=test.csv');
+        $fh = fopen('php://output','w');
+        
+        fputcsv($fh, array("ID", "type", "Description", "NETSUITE", "HK", "SG", "difference"));
+        foreach($old as $k=>$ar) {
+            $ar = (object)$ar;
+            $ar->netsuite_balance = isset( $ar->netsuite_balance) ? $ar->netsuite_balance : 0;
+            $ar->acctType = empty($ar->acctType) ? '' : $ar->acctType;
+            if ($ar->acctType == '_expense') {
+                $ar->netsuite_balance  = -1 * $ar->netsuite_balance  ;
+            }
+            
+            if (!(1 * $ar->netsuite_balance ) && !(1 *$ar->hkbalance) && !(1 * $ar->sgbalance)) {
+                continue;
+            }
+            if ( abs(abs($ar->hkbalance + $ar->sgbalance) - abs($ar->netsuite_balance)) < 100.0) {
+                continue;
+            }
+            
+            
+            fputcsv($fh, array(
+                $ar->id,
+                $ar->acctType,
+                $ar->description,
+                $ar->netsuite_balance,
+                $ar->hkbalance,
+                $ar->sgbalance,
+                abs($ar->hkbalance + $ar->sgbalance) - abs($ar->netsuite_balance)));
+        }
+        exit;
+        // we now have all the data...
+        
+        echo '<PRE>';
+        print_R($old);
+        exit;
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+    }
+    function oldParse($cn)
+    {
+        
+        
+        $har = explode('/', realpath(__FILE__));
+        $home = '/home/'. $har[2];
+        $fn = "$home/Dropbox/xtuple_working/old_database_snapshot/$cn/Netsuite_Account.sql.json.all";
+        $ar = file($fn);
+        $ret = array();
+        foreach($ar as $i=>$l) {
+            if (!$i) continue;
+            $line = json_decode($l);
+         
+            $ret[$line->id] =   array(
+                    'id' => $line->id ,
+                    'description' => $line->description,
+                    'netsuite_balance' => $line->balance,
+                    'acctType' => $line->acctType,
+                    'is_old' => 1
+                );
+        }
+        return $ret;
+         
+
+        
+    }
+    function addEndOfDay($accnt_id , $data, $bbal, $bal, $last_exchange)
+    {
+        $ac = DB_DataObject::factory('accnt');
+        $ac->get($accnt_id);
+        $num = $ac->accnt_number;
+        
+        
+        $sd = strtoupper(substr(HTML_FlexyFramework::get()->database,-2));
+        
+        $base = $sd == 'SG' ? 'SGD' : 'HKD';
+        
+        $file = "/home/alan/netsuite_accounts/{$sd}-Account-". $num . '.csv';
+        
+        $last_exchange = false;
+        
+        // fill in dragon data..
+        
+        
+        foreach($data as $i=>$row) {
+            
+            // if the exchange rate changes..
+            // then the balance will get adjusted...
+            // EG. old rate is 5
+            // NEW rate is 10
+            // balance = [oldbalance] / 5 * 10
+            if ($last_exchange !== false && $last_exchange != $row['gltrans_curr_rate']) {
+                $bal = ($bal / $last_exchange) * $row['gltrans_curr_rate'];
+            }
+            $last_exchange = $row['gltrans_curr_rate'];
+            
+            
+            
+            
+            $bal += $row['gltrans_amount_normal'];
+            $data[$i]['gltrans_balance'] = $bal;
+            $bbal += $row['gltrans_base_normal'];
+            $data[$i]['gltrans_base_balance'] = $bbal;
+            
+            
+            $data[$i]['gltrans_nsbalance'] = '';
+            $data[$i]['gltrans_nsbalance_diff'] = '';
+            
+            
+        }
+        
+        
+        if (!file_exists($file)) {
+            //var_dump($file);exit;
+            $bal = 0;
+            $bbal = 0;
+           
+             
+            return $data;
+        }
+        // find the end of day totals
+         
+        
+        $fh = fopen($file ,'r');
+        if (!$fh) {
+            die("failed to open $file\n");
+        }
+        
+        $head = false;
+        $daybal = array();
+        $daybal_fc = array();
+        $last_date = '';
+        $last_balance = 0;
+        $bal = 0.0;
+        
+        $fcbal = 0.0;
+        $fc = false;
+        
+        
+        $daybal_base = array();
+        $basebal = 0.0;
+        
+        
+        
+        while (false !== ($row = fgetcsv($fh, 4000))) {
+            
+            if ($head == false) {
+                //if (trim($row[0]) != 'Date') {
+                //    continue;
+                //}
+                
+                $head = array();
+                foreach($row as $v) {
+                    $head[] = trim($v);
+                }
+                continue;
+            }
+            
+            //echo '<PRE>';print_r($head);print_r($row);exit;
+           // print_R($head);exit;
+            $line = array();
+            
+            foreach($head as $i=>$k) {
+                if ($k == 'Date') {
+                    $line[$k] = date('Y-m-d', strtotime(implode('-', array_reverse(explode('/', $row[$i])))));
+                    continue;
+                }
+                if ($k == 'Amount') {
+                    $line[$k] =$row[$i];
+            
+                    continue;
+                    
+                }
+                if (($k == 'Currency') || ($k == 'Amount (Foreign Currency)') || ($k == 'Number') ||  ($k == 'Posting')) {
+                    $line[$k] =$row[$i];
+                }
+                // do not care about other data!?! at present.
+                continue;
+                
+            }
+            if ($line['Posting'] == 'No') {
+                continue;
+            }
+            if ($line['Number'] == 'Memorized') {
+                continue;
+            }
+            
+            $bal += 1.0*$line['Amount'];
+            $line['Balance'] = $bal ; //$neg . preg_replace('#[^0-9.-]#','', $row[$i]);
+            
+            
+           
+            
+            if ($fc === false) {
+                //echo "FC SET TO :". $line['Currency'];
+                $fc = $line['Currency'];
+            } else if ($fc === '') {
+                
+            } else if ($fc != $line['Currency']) {
+                $fc = '';
+            }
+             
+            $am = preg_replace('/[^0-9.]+/', '', $line['Amount (Foreign Currency)']);
+            if ($line['Amount'] < 0) {
+                $am *= -1.0;
+            }
+            
+            
+            $basebal += $this->currtobase($line['Currency'] , $base, $am , $line['Date']);
+            $daybal_base[$line['Date']] = $basebal;
+             
+            if ($fc) {
+                
+                $fcbal += $am;
+                $daybal_fc[$line['Date']] = $fcbal;
+            }
+             
+            
+            if (($last_date != $line['Date']) && !empty($last_date)) {
+                $daybal[$last_date] = $last_balance;
+                
+            }
+            $last_balance = $line['Balance'];
+            $last_date = $line['Date'];
+            
+        }
+        //echo '<PRE>';print_R($daybal); exit;
+        // now let's add them to the return values..
+        $last_date = '';
+        $last_diff = 0;
+        $lastbase_balance = 0.0;
+        $bal = 0;
+        $bbal = 0;
+        foreach($data as $i=>$row) {
+            
+            if (($last_date != $row['gltrans_date']) && !empty($last_date)) {
+                 // new day..
+                if (!$fc) {
+                    $data[$i-1]['gltrans_nsbalance'] = isset($daybal[$last_date]) ? $daybal[$last_date] : 0;
+                    $data[$i-1]['gltrans_nsbalance_diff'] = sprintf("%0.2f", $data[$i-1]['gltrans_nsbalance']  - $data[$i-1]['gltrans_balance'] );
+                    if ($last_diff != $data[$i-1]['gltrans_nsbalance_diff']) {
+                        $bad_days[] = $last_date;
+                    }
+                    $last_diff = $data[$i-1]['gltrans_nsbalance_diff'];
+                } else {
+                    $data[$i-1]['gltrans_nsbalance'] = isset($daybal_fc[$last_date]) ? $daybal_fc[$last_date] : 0;
+                    $data[$i-1]['gltrans_nsbalance_diff'] = sprintf("%0.2f", $data[$i-1]['gltrans_nsbalance']  - $data[$i-1]['gltrans_balance'] );
+                    
+                }
+                
+                $data[$i-1]['gltrans_nsbalance_base'] = isset($daybal_base[$last_date]) ? $daybal_base[$last_date] : $lastbase_balance;
+                
+                $data[$i-1]['gltrans_nsbalance_base_diff'] = sprintf("%0.2f", $data[$i-1]['gltrans_nsbalance_base']  - $data[$i-1]['gltrans_base_balance'] );
+                $lastbase_balance = $data[$i-1]['gltrans_nsbalance_base'];
+                
+            }
+            $last_date =  $row['gltrans_date'];
+            
+            
+            $data[$i]['gltrans_nsbalance'] = '';
+            $data[$i]['gltrans_nsbalance_diff'] = '';
+             
+        }
+        return $data;
+    /*
+        $final = array();
+        foreach($data as $row) {
+            if (!in_array($row['gltrans_date'], $bad_days)) {
+                continue;
+            }
+            $final[] = $row;
+        }
+        
+        
+        
+        
+        //echo '<PRE>';print_R($data); exit;
+        return $final;
+        */
+          
+    }
+    
+    function currtobase($from , $to, $amt , $date)
+    {
+        if ($from == $to) {
+            return $amt;
+        }
+        $do = DB_DataObject::factory('curr_symbol');
+        $do->query("select currtobase(getcurrid('{$from}'), {$amt}, '{$date}') as result");
+        $do->fetch();
+        return $do->result;
+        
+        
+    }
+    
+}
diff --git a/VerifyMigrate.php b/VerifyMigrate.php
new file mode 100644 (file)
index 0000000..5ec1f0b
--- /dev/null
@@ -0,0 +1,668 @@
+<?php
+require_once 'Verify.php';
+class Pman_Xtuple_VerifyMigrate extends Pman_Xtuple_Verify
+{
+    
+    function get()
+    {
+        ini_set('memory_limit', '500M');
+        
+        if (isset($_REQUEST['prods'])) {
+            
+            $data = $this->txRecords($_REQUEST['loc'], explode(',',$_REQUEST['prods']));
+            echo json_encode($data);exit;
+            
+            
+        }
+        
+        if (isset($_REQUEST['prod'])) {
+            
+            $data = $this->txRecordsAll($_REQUEST['loc'],  $_REQUEST['prod'],isset($_REQUEST['day']) ? $_REQUEST['day'] : false);
+            echo json_encode($data);exit;
+            
+            
+        }
+        
+        
+        $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+        
+        
+        
+        //DB_DataObject::debugLevel(1);
+        // we need to
+        // A) grab the stock levels from the old database.
+        
+        // B) grab the stock levels from the new database
+        
+        // compare the values..
+        // for comparison:
+        
+            // use  "Location: XXXX  Product : XXXX" = $n
+            // we might even be able to use array_diff between the two..
+        $il = DB_DataObject::Factory('itemloc');
+        $il->autoJoin(array(
+                'links' => array(
+                    'itemloc_location_id' => 'location:location_id',
+                    'itemloc_itemsite_id' => 'itemsite:itemsite_id',
+                    
+                )
+        ));
+        $il->selectAdd();
+        $il->selectAdd("
+            'Location : ' ||  join_itemloc_location_id_location_id.location_name ||
+            ' Product : ' || (SELECT item_number FROM item WHERE
+                        item_id = join_itemloc_itemsite_id_itemsite_id.itemsite_item_id LIMIT 1) as pn,
+                    itemloc_qty
+                       
+                       ");
+        $il->whereAdd('itemloc_qty <> 0.0');
+        $data = $il->fetchAll('pn', 'itemloc_qty');
+        ksort($data);
+        
+        if ($sd != 'HK') {
+            // we only report on HK data..
+            echo json_encode($data);
+            exit;
+        }
+        // hard codE?
+        $har = explode('/', realpath(__FILE__));
+        $home = '/home/'. $har[2];
+        $fn = "$home/Dropbox/xtuple_working/old_database_snapshot/stock.json";
+       // var_dump($fn);exit;
+        $base_data = (array)json_decode(file_get_contents($fn));
+        //echo '<PRE>'; print_r($base_data);exit;
+        //var_dump($base_data['Location : Dymocks-CB Product : DM05001']);
+        //exit;
+        //print_r($base_data);exit;
+        // run all the child processes...
+        //
+        //echo $cmd;exit;
+        $other_data = (array) json_decode(file_get_contents(
+                    "http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyMigrate"));
+
+                    
+        
+        $core = array_merge($data,$base_data, $other_data);
+        ksort($core);
+        
+        $out = array();
+        
+        
+        
+        
+        $out[] = array("location / sku", "OLD", "HK", "SG", "difference");
+        // merge the data and produce a sensible report..
+        $errors = array();
+        foreach($core as $k=>$blah) {
+            $row = array(
+                $k,
+                isset($base_data[$k]) ? $base_data[$k] : 0,
+                isset($data[$k]) ? $data[$k] : 0,
+                isset($other_data[$k]) ? $other_data[$k] : 0,
+            );
+            $row[4] = $row[1] - ($row[2] + $row[3]);
+            
+            if ($row[4] != 0 ) {
+                $out[] = $row;
+                $errors[$row[0]] =  $row[1];
+            }
+             
+            
+        } 
+        
+        $error_ar = array();
+        foreach($errors as $r=>$qty) {
+            
+            $exp = explode(' Product : ', preg_replace('/^Location :/', '', $r));
+            //print_R( $exp); 
+            list($loc, $prod) = $exp;
+            $loc = trim($loc);
+            if (!isset($error_ar[$loc])) {
+                $error_ar[$loc] = array();
+            }
+            $error_ar[$loc][] = $prod;
+        }
+       // echo '<PRE>';print_R($error_ar);exit;
+       
+        //echo '<PRE>';
+      
+        foreach($error_ar as $loc => $prods) {
+            if ($loc != 'OLL') {
+              //  continue;
+            }
+            $out = array_merge($out,$this->processMismatch($loc, $prods));
+        }
+        
+        //die("got this far");
+      
+         foreach($out as $o) {
+            if (!is_array($o)) {
+                var_dump($o);exit;
+            }
+          }
+      
+        header('Content-type: text/csv');
+        header( 'Content-Disposition: attachment;filename=stock_report-'.date('Y-m-d').'.csv');
+        $fh = fopen('php://output','w');
+        foreach($out as $o) {
+               fputcsv($fh, $o);
+            
+        }
+        exit;
+        
+         
+        /*
+        $el = array();
+        $eltot = 0;
+        $locmax = 0;
+        $totmax = 0;
+        foreach($errors as $r=>$qty) {
+            
+            
+            $exp = explode(' Product : ', preg_replace('/^Location :/', '', $r));
+            //print_R( $exp); 
+            list($loc, $prod) = $exp;
+            
+            $loc = trim($loc);
+            $prod = trim($prod);
+            
+            $el[$loc] = isset($el[$loc]) ? $el[$loc] : 0;
+            if ($locmax && $el[$loc] > $locmax) {
+                continue;
+            }
+            if ($totmax && $eltot > $totmax) {
+                break;
+            }
+                        
+            $el[$loc]++;
+            $eltot++;
+            
+            $url = 'http://localhost/xtuple/hk.php/Roo/invdetail';
+            $args = $this->toParams(array(
+                'query[item_number]'=> trim($prod),
+                'query[location_name]'=> trim($loc),
+                '_with_item'=>'1',
+                'sort'=>'invhist_transdate,invdetail_id',
+                'dir'=>'ASC',
+                
+                
+                'csvCols[0]' => 'invhist_transdate',
+                'csvCols[1]' => 'invhist_docnumber',
+                'csvCols[2]' => 'invhist_ordnumber',
+                'csvCols[3]' => 'invdetail_qty',
+                'csvCols[4]' => 'invdetail_bydate_qty',
+                'csvCols[5]' => 'invhist_comments',
+                
+                'csvTitles[0]' => 'Date',
+                'csvTitles[1]' => 'Doc number',
+                'csvTitles[2]' => 'Order no.',
+                'csvTitles[3]' => 'Qty',
+                'csvTitles[4]' => 'Qty After',
+                'csvTitles[5]' => 'comments',
+                'start' => 0,
+                'limit' => 9999
+                
+                
+            ));
+            
+            
+            
+            fwrite($fh, "\n\n-- ". $r ." ,,Expecting:, $qty\n");
+                   
+                   
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}hk.php/Roo/invdetail?$args"));
+            fwrite($fh, file_get_contents("http://localhost/xtuple/{$lprefix}sg.php/Roo/invdetail?$args"));
+        */
+            /*
+             $rows = $this->fcsv("http://localhost/xtuple/{$lprefix}hk.php/Roo/invdetail?$args");
+            $head = array_shift($rows);
+            fputcsv($fh, $head);
+            
+            $add = $this->fcsv("http://localhost/xtuple/{$lprefix}sg.php/Roo/invdetail?$args");
+            array_shift($add);
+            $rows += $add;
+            
+            usort($rows, function($a, $b) {
+                $aa =strtotime($a[0]);
+                $bb = strtotime($b[0]);
+                if ($aa == $bb) return 0;
+                return $a < $b ? -1 : 1;
+                
+            });
+            $ltot = 0;
+            foreach($rows as $row)
+            {
+                $ltot += $row[3];
+                $row[4] = $ltot;
+                fputcsv($fh, $row);
+               
+                
+            }
+            */
+            
+        /*    
+                               
+            
+        }
+        
+        */
+        
+        exit;
+        
+        
+        
+        
+        
+        
+        echo '<PRE>';print_r($data);
+        
+        exit;
+        
+    }
+    function fcsv($fn)
+    {
+        $handle = fopen($fn, "r");
+        while (($data = fgetcsv($handle)) !== false) {
+            $ret[] = $data;
+        }
+        return $ret;
+    }
+    
+    function fullTx($loc,$pods) {
+        
+        // old style lists..
+        return array(array('old style tx log'));
+        
+    }
+    
+    /*
+     process:
+     we have a list of location / products that do not match
+     
+     1. load the full tx list from the database. (grouping by day) from both databases.
+     2. load the csv for that.
+     3. compare the day change totals
+     4. any day that does not match
+       - output the tx records from our system
+       - output the tx records from netsuite (csv)
+     
+     
+     
+    */
+     
+    function processMismatch($loc, $prods)
+    {
+        
+        // we need to cache the results from this..
+        $cache = '/tmp/stock-'. $loc . '-' . date('Y-m-d');
+        if (file_exists($cache)) {
+            return unserialize(file_get_contents($cache));
+        }
+        
+        
+        
+        $loc_data  = $this->loadCSV($loc );
+        
+        if (empty($loc_data)) {
+            //echo "SKIP - not data for $loc\n";
+            $ret = array(array("LOCATION: $loc"));
+            foreach($prods as $prod) {
+                $ret[] =  array("-- ONLY XT DATA: $prod");
+                
+                $data =$this->xtData($loc, $prod,false);
+                $head = false;
+                foreach($data as $tx) {
+                        if (!$head) {
+                           $ret[] = array_keys($tx);
+                           $head = true;
+                       }
+                       $ret[] = array_values($tx);
+                   }
+            }
+            file_put_contents($cache,serialize($ret));
+            exit('<meta http-equiv="refresh" content="0; url=' . urldecode('http://'.$_SERVER['HTTP_HOST'].'/xtuple/hk.php/Xtuple/VerifyMigrate?ts='.urlencode($loc)) . '"/>
+                 
+                 Processing more data...... ('. $loc .')
+                 
+                 '); 
+            
+             exit;
+            echo "DONE CACHE $loc\n";exit;
+            return $ret;
+        }
+        
+        
+        $ourtx = $this->txRecords($loc, $prods);
+        
+        $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+        
+         
+        $other = (array) json_decode(file_get_contents(
+                    "http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyMigrate?loc=".urlencode($loc).'&prods='.implode(',', $prods)));
+        
+        // merge them..
+        
+        foreach($other as $prod=>$data) {
+            $data = (array) $data;
+            foreach($data as $day=>$qty) {
+                if (isset($ourtx[$prod][$day])) {
+                    $ourtx[$prod][$day] += $qty;
+                    continue;
+                }
+                $ourtx[$prod][$day] = $qty;
+                
+            }
+            
+        }
+         $ret = array();
+        
+        //print_R($ourtx);exit;
+        // we should now have day summaries for them all.. compare it to the data in the database.
+        
+        foreach($ourtx as $prod=>$data) {
+            if (!isset($loc_data[$prod])) {
+               // $ret[] =  array("NO location data for $loc / $prod");
+               // continue;
+                
+            }
+            $prod_data  = isset($loc_data[$prod]) ? $loc_data[$prod] : array();
+           // echo "$prod\n";
+            $bad_day = array();
+            $prod_changes = $this->dayChanges($prod_data);
+            //echo "XTUPLE:\n";
+            //print_R($data);
+            //echo "NS:\n";
+            //print_R($prod_changes);
+            
+            
+            foreach($prod_changes as $day =>$qty) {
+                if (!isset($data[$day]) || $data[$day] != $qty) {
+                    $ns = isset($data[$day] ) ? $data[$day]  : 0 ;
+                    //echo "$day : XTUPLE: $qty : NS $ns\n";
+                    
+                    
+                    $bad_day[] = $day;
+                }
+            }
+            foreach($data as $day =>$qty) {
+                if (!isset($prod_changes [$day]) || $prod_changes [$day] != $qty) {
+                    $xt  = isset($prod_changes [$day] ) ? $prod_changes [$day]  : 0 ;
+                    //echo "$day : XTUPLE: $xt  : NS $qty\n";
+                    
+                    $bad_day[] = $day;
+                }
+            }
+            
+            $bad_day = array_unique($bad_day);
+            $bad_days[$prod] = $bad_day;
+            
+            //print_R($bad_day);exit;
+            
+            
+        }
+        // we now have a list of bad days for that product..
+        
+        
+       
+       // print_r($bad_days);
+        foreach($bad_days as $prod => $days) {
+            $prod_data  = isset($loc_data[$prod]) ? $loc_data[$prod] : array();
+             $ret[] = array();
+            $ret[] = array('LOCATION : ' . $loc . ' Product : ' . $prod);
+            $ret[] = array("--- NETSUITE: ");
+            $head =false;
+            foreach($days as $day) {
+                
+                
+                $day_data = isset($prod_data[$day]) ? $prod_data[$day] : array();
+                
+                
+                
+                
+                foreach($day_data  as $tx) {
+                    if (!$head) {
+                        $ret[] = array_keys($tx);
+                        $head = true;
+                    }
+                    $ret[] = array_values($tx);
+                }
+                  
+                // now dump the data from 
+                
+            }
+             $ret[]  = array();
+             $ret[] = array("--- MIGRATED:  ");
+              $head =false;
+                
+            foreach($days as $day) {
+                
+                
+                $day_data = isset($prod_data[$day]) ? $prod_data[$day] : array();
+                
+                $data = $this->xtData($loc, $prod, $day);
+                foreach($data as $tx) {
+                     if (!$head) {
+                        $ret[] = array_slice(array_keys($tx), 0,7);
+                        $head = true;
+                    }
+                    $ret[] = array_values($tx);
+                }   
+                
+                // now dump the data from 
+                
+            }
+            $ret[] = array();     
+            $ret[]  = array();
+            
+        }
+        
+        file_put_contents($cache,serialize($ret));
+       exit('<meta http-equiv="refresh" content="0; url=' . urldecode('http://'.$_SERVER['HTTP_HOST'].'/xtuple/hk.php/Xtuple/VerifyMigrate?ts='.urlencode($loc)) . '"/>'); 
+        echo "DONE CACHE $loc\n";exit;
+        return $ret;
+        print_R($ret);
+                
+                exit;
+        
+        exit;
+            
+             
+        
+    }
+    
+    function xtData($loc, $prod,$day) {
+        //var_dump($loc);
+        
+        
+        
+        $locs = $this->txRecordsAll($loc,$prod,$day);
+         $sd = strtoupper(array_pop(explode('xtuple', HTML_FlexyFramework::get()->database)));
+        
+        
+        $lprefix  = preg_match('/(lsg\.php|lhk.php)$/', $this->baseURL) ? 'l' : '';
+        //echo "http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyMigrate?loc=".urlencode($loc).'&prod='.$prod.'&day='.$day;
+        //print_r($loc);exit;
+        $remote =  (array) json_decode(file_get_contents(
+                    "http://localhost/xtuple/{$lprefix}sg.php/Xtuple/VerifyMigrate?loc=".urlencode($loc).'&prod='.$prod . ($day !== false ? ('&day='.$day) : '')));
+        foreach($remote as $line) {
+            $locs[] = (array)$line;
+        }
+        //print_r($locs);exit;
+        $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
+         $GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array();
+        
+        return $locs;
+        
+    }
+    
+    
+    function txRecordsAll($loc, $prod, $day)
+    {
+        $ret = array();
+    
+        //DB_DataObject::debugLevel(1);
+        $d = DB_DataObject::factory('invdetail');
+        $d->autoJoin();
+        $d->applyFilters(array(
+            'query' => array(
+                    'item_number'=> trim($prod),
+                    'location_name'=> trim($loc),
+            ),
+             '_with_item'=>'1',
+             
+             
+             
+        ),$this->authUser, $this);
+        if ($day !== false) {
+            $d->whereAdd("invhist_transdate::date = '$day'");
+        }
+        $d->selectAdd();
+        $d->selectAdd('
+            join_invhist.invhist_transdate,
+            join_invhist.invhist_docnumber,
+            join_invhist.invhist_ordnumber,
+             invdetail_qty  ,
+            invdetail_bydate(invdetail_id) AS  invdetail_bydate_qty ,
+            join_invhist.invhist_comments 
+        ');
+        
+        $d->orderBy('invdetail_id ASC');
+        
+        
+        return $d->fetchAll(false,false, 'toArray');
+        
+        
+    }
+     
+    function txRecords($loc, $prods)
+    {
+        $ret = array();
+        foreach($prods as $prod) {
+           // DB_DataObject::debugLevel(1);
+            $d = DB_DataObject::factory('invdetail');
+            $d->autoJoin();
+            $d->applyFilters(array(
+                'query' => array(
+                        'item_number'=> trim($prod),
+                        'location_name'=> trim($loc),
+                ),
+                 '_with_item'=>'1',
+            ),$this->authUser, $this);
+            $d->orderBy('invhist_transdate ASC');
+            $d->selectAdd();
+            $d->selectAdd('distinct(invhist_transdate::date) as  invhist_transdate, sum(invdetail_qty) as invdetail_qty');
+            $d->groupBy('invhist_transdate');
+            $ret[$prod]  = $d->fetchAll('invhist_transdate', 'invdetail_qty');
+            //exit;
+        }
+        return $ret;
+        
+    }
+    
+    
+    
+    function dayChanges($cvsdata)
+    {
+        
+        
+        foreach($cvsdata as $day => $rows) {
+        
+            $qty = 0;
+            foreach($rows as $row) {
+                $qty += $row['Qty.'];
+            }
+            $ret[$day] = $qty;
+        }
+        return $ret;
+        
+    }
+    
+    // returns array of day -> [ tx, tx, tx ]
+    
+    function loadCSV($loc)
+    {
+     
+    
+        $file = '/home/alan/netsuite_accounts/iad-'. $loc. '.csv';
+        if (!file_exists($file)) {
+           // echo "NO FILE: $file\n";
+            $files[$loc]= array();
+            return array();
+        }
+        
+        $fh = fopen($file ,'r');
+        if (!$fh) {
+            die("failed to open $file\n");
+        }
+        
+        $head = false;
+        $out = array();
+        $product = false;
+        
+        while (false !== ($row = fgetcsv($fh, 4000))) {
+            if ($head === false) {
+                if (trim($row[0]) != 'Item') {
+                    continue;
+                }
+                
+                $head = array();
+                foreach($row as $v) {
+                    $head[] = trim($v);
+                }
+                continue;
+            }
+           // print_R($head);exit;
+            $line = array();
+            // skip the intro line.
+            if ($row[0] == 'Inventory Item') {
+                continue;
+            
+            }
+            if (preg_match('/^Total /', $row[0])) {
+                continue;
+            }
+            if (!strlen(trim($row[1]))) {
+                // then it's a new product.
+                $product = $row[0];
+                $out[$product] = array( );
+                continue;
+            }
+            if (empty($product)) {
+                continue;
+            }
+            
+            // got a normal line.
+            $day = date('Y-m-d', strtotime(implode('-', array_reverse(explode('/', $row[1])))));
+            if (!isset($out[$product][$day])) {
+                $out[$product][$day] = array();
+            }
+            
+            foreach($head as $i=>$k) {
+                if ($k == 'Date') {
+                    $line[$k] = date('Y-m-d', strtotime(implode('-', array_reverse(explode('/', $row[$i])))));
+                    continue;
+                }
+                
+                
+                $line[$k] = trim($row[$i]);
+                    
+            }
+             $out[$product][$day][] = $line;
+             
+            
+        }
+        //print_R($out);exit;
+        return $out;
+        
+        
+    }
+    
+    
+    
+}
diff --git a/colorbrewer.js b/colorbrewer.js
new file mode 100644 (file)
index 0000000..77ebb63
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * This product includes color specifications and designs developed by Cynthia
+ * Brewer (http://colorbrewer.org/).
+ */
+var colorbrewer = {
+YlGn:{3:['rgb(247,252,185)','rgb(173,221,142)','rgb(49,163,84)'],4:['rgb(255,255,204)','rgb(194,230,153)','rgb(120,198,121)','rgb(35,132,67)'],5:['rgb(255,255,204)','rgb(194,230,153)','rgb(120,198,121)','rgb(49,163,84)','rgb(0,104,55)'],6:['rgb(255,255,204)','rgb(217,240,163)','rgb(173,221,142)','rgb(120,198,121)','rgb(49,163,84)','rgb(0,104,55)'],7:['rgb(255,255,204)','rgb(217,240,163)','rgb(173,221,142)','rgb(120,198,121)','rgb(65,171,93)','rgb(35,132,67)','rgb(0,90,50)'],8:['rgb(255,255,229)','rgb(247,252,185)','rgb(217,240,163)','rgb(173,221,142)','rgb(120,198,121)','rgb(65,171,93)','rgb(35,132,67)','rgb(0,90,50)'],9:['rgb(255,255,229)','rgb(247,252,185)','rgb(217,240,163)','rgb(173,221,142)','rgb(120,198,121)','rgb(65,171,93)','rgb(35,132,67)','rgb(0,104,55)','rgb(0,69,41)']},
+YlGnBu:{3:['rgb(237,248,177)','rgb(127,205,187)','rgb(44,127,184)'],4:['rgb(255,255,204)','rgb(161,218,180)','rgb(65,182,196)','rgb(34,94,168)'],5:['rgb(255,255,204)','rgb(161,218,180)','rgb(65,182,196)','rgb(44,127,184)','rgb(37,52,148)'],6:['rgb(255,255,204)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(44,127,184)','rgb(37,52,148)'],7:['rgb(255,255,204)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(29,145,192)','rgb(34,94,168)','rgb(12,44,132)'],8:['rgb(255,255,217)','rgb(237,248,177)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(29,145,192)','rgb(34,94,168)','rgb(12,44,132)'],9:['rgb(255,255,217)','rgb(237,248,177)','rgb(199,233,180)','rgb(127,205,187)','rgb(65,182,196)','rgb(29,145,192)','rgb(34,94,168)','rgb(37,52,148)','rgb(8,29,88)']},
+GnBu:{3:['rgb(224,243,219)','rgb(168,221,181)','rgb(67,162,202)'],4:['rgb(240,249,232)','rgb(186,228,188)','rgb(123,204,196)','rgb(43,140,190)'],5:['rgb(240,249,232)','rgb(186,228,188)','rgb(123,204,196)','rgb(67,162,202)','rgb(8,104,172)'],6:['rgb(240,249,232)','rgb(204,235,197)','rgb(168,221,181)','rgb(123,204,196)','rgb(67,162,202)','rgb(8,104,172)'],7:['rgb(240,249,232)','rgb(204,235,197)','rgb(168,221,181)','rgb(123,204,196)','rgb(78,179,211)','rgb(43,140,190)','rgb(8,88,158)'],8:['rgb(247,252,240)','rgb(224,243,219)','rgb(204,235,197)','rgb(168,221,181)','rgb(123,204,196)','rgb(78,179,211)','rgb(43,140,190)','rgb(8,88,158)'],9:['rgb(247,252,240)','rgb(224,243,219)','rgb(204,235,197)','rgb(168,221,181)','rgb(123,204,196)','rgb(78,179,211)','rgb(43,140,190)','rgb(8,104,172)','rgb(8,64,129)']},
+BuGn:{3:['rgb(229,245,249)','rgb(153,216,201)','rgb(44,162,95)'],4:['rgb(237,248,251)','rgb(178,226,226)','rgb(102,194,164)','rgb(35,139,69)'],5:['rgb(237,248,251)','rgb(178,226,226)','rgb(102,194,164)','rgb(44,162,95)','rgb(0,109,44)'],6:['rgb(237,248,251)','rgb(204,236,230)','rgb(153,216,201)','rgb(102,194,164)','rgb(44,162,95)','rgb(0,109,44)'],7:['rgb(237,248,251)','rgb(204,236,230)','rgb(153,216,201)','rgb(102,194,164)','rgb(65,174,118)','rgb(35,139,69)','rgb(0,88,36)'],8:['rgb(247,252,253)','rgb(229,245,249)','rgb(204,236,230)','rgb(153,216,201)','rgb(102,194,164)','rgb(65,174,118)','rgb(35,139,69)','rgb(0,88,36)'],9:['rgb(247,252,253)','rgb(229,245,249)','rgb(204,236,230)','rgb(153,216,201)','rgb(102,194,164)','rgb(65,174,118)','rgb(35,139,69)','rgb(0,109,44)','rgb(0,68,27)']},
+PuBuGn:{3:['rgb(236,226,240)','rgb(166,189,219)','rgb(28,144,153)'],4:['rgb(246,239,247)','rgb(189,201,225)','rgb(103,169,207)','rgb(2,129,138)'],5:['rgb(246,239,247)','rgb(189,201,225)','rgb(103,169,207)','rgb(28,144,153)','rgb(1,108,89)'],6:['rgb(246,239,247)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(28,144,153)','rgb(1,108,89)'],7:['rgb(246,239,247)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,100,80)'],8:['rgb(255,247,251)','rgb(236,226,240)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,100,80)'],9:['rgb(255,247,251)','rgb(236,226,240)','rgb(208,209,230)','rgb(166,189,219)','rgb(103,169,207)','rgb(54,144,192)','rgb(2,129,138)','rgb(1,108,89)','rgb(1,70,54)']},
+PuBu:{3:['rgb(236,231,242)','rgb(166,189,219)','rgb(43,140,190)'],4:['rgb(241,238,246)','rgb(189,201,225)','rgb(116,169,207)','rgb(5,112,176)'],5:['rgb(241,238,246)','rgb(189,201,225)','rgb(116,169,207)','rgb(43,140,190)','rgb(4,90,141)'],6:['rgb(241,238,246)','rgb(208,209,230)','rgb(166,189,219)','rgb(116,169,207)','rgb(43,140,190)','rgb(4,90,141)'],7:['rgb(241,238,246)','rgb(208,209,230)','rgb(166,189,219)','rgb(116,169,207)','rgb(54,144,192)','rgb(5,112,176)','rgb(3,78,123)'],8:['rgb(255,247,251)','rgb(236,231,242)','rgb(208,209,230)','rgb(166,189,219)','rgb(116,169,207)','rgb(54,144,192)','rgb(5,112,176)','rgb(3,78,123)'],9:['rgb(255,247,251)','rgb(236,231,242)','rgb(208,209,230)','rgb(166,189,219)','rgb(116,169,207)','rgb(54,144,192)','rgb(5,112,176)','rgb(4,90,141)','rgb(2,56,88)']},
+BuPu:{3:['rgb(224,236,244)','rgb(158,188,218)','rgb(136,86,167)'],4:['rgb(237,248,251)','rgb(179,205,227)','rgb(140,150,198)','rgb(136,65,157)'],5:['rgb(237,248,251)','rgb(179,205,227)','rgb(140,150,198)','rgb(136,86,167)','rgb(129,15,124)'],6:['rgb(237,248,251)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(136,86,167)','rgb(129,15,124)'],7:['rgb(237,248,251)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(140,107,177)','rgb(136,65,157)','rgb(110,1,107)'],8:['rgb(247,252,253)','rgb(224,236,244)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(140,107,177)','rgb(136,65,157)','rgb(110,1,107)'],9:['rgb(247,252,253)','rgb(224,236,244)','rgb(191,211,230)','rgb(158,188,218)','rgb(140,150,198)','rgb(140,107,177)','rgb(136,65,157)','rgb(129,15,124)','rgb(77,0,75)']},
+RdPu:{3:['rgb(253,224,221)','rgb(250,159,181)','rgb(197,27,138)'],4:['rgb(254,235,226)','rgb(251,180,185)','rgb(247,104,161)','rgb(174,1,126)'],5:['rgb(254,235,226)','rgb(251,180,185)','rgb(247,104,161)','rgb(197,27,138)','rgb(122,1,119)'],6:['rgb(254,235,226)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(197,27,138)','rgb(122,1,119)'],7:['rgb(254,235,226)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)'],8:['rgb(255,247,243)','rgb(253,224,221)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)'],9:['rgb(255,247,243)','rgb(253,224,221)','rgb(252,197,192)','rgb(250,159,181)','rgb(247,104,161)','rgb(221,52,151)','rgb(174,1,126)','rgb(122,1,119)','rgb(73,0,106)']},
+PuRd:{3:['rgb(231,225,239)','rgb(201,148,199)','rgb(221,28,119)'],4:['rgb(241,238,246)','rgb(215,181,216)','rgb(223,101,176)','rgb(206,18,86)'],5:['rgb(241,238,246)','rgb(215,181,216)','rgb(223,101,176)','rgb(221,28,119)','rgb(152,0,67)'],6:['rgb(241,238,246)','rgb(212,185,218)','rgb(201,148,199)','rgb(223,101,176)','rgb(221,28,119)','rgb(152,0,67)'],7:['rgb(241,238,246)','rgb(212,185,218)','rgb(201,148,199)','rgb(223,101,176)','rgb(231,41,138)','rgb(206,18,86)','rgb(145,0,63)'],8:['rgb(247,244,249)','rgb(231,225,239)','rgb(212,185,218)','rgb(201,148,199)','rgb(223,101,176)','rgb(231,41,138)','rgb(206,18,86)','rgb(145,0,63)'],9:['rgb(247,244,249)','rgb(231,225,239)','rgb(212,185,218)','rgb(201,148,199)','rgb(223,101,176)','rgb(231,41,138)','rgb(206,18,86)','rgb(152,0,67)','rgb(103,0,31)']},
+OrRd:{3:['rgb(254,232,200)','rgb(253,187,132)','rgb(227,74,51)'],4:['rgb(254,240,217)','rgb(253,204,138)','rgb(252,141,89)','rgb(215,48,31)'],5:['rgb(254,240,217)','rgb(253,204,138)','rgb(252,141,89)','rgb(227,74,51)','rgb(179,0,0)'],6:['rgb(254,240,217)','rgb(253,212,158)','rgb(253,187,132)','rgb(252,141,89)','rgb(227,74,51)','rgb(179,0,0)'],7:['rgb(254,240,217)','rgb(253,212,158)','rgb(253,187,132)','rgb(252,141,89)','rgb(239,101,72)','rgb(215,48,31)','rgb(153,0,0)'],8:['rgb(255,247,236)','rgb(254,232,200)','rgb(253,212,158)','rgb(253,187,132)','rgb(252,141,89)','rgb(239,101,72)','rgb(215,48,31)','rgb(153,0,0)'],9:['rgb(255,247,236)','rgb(254,232,200)','rgb(253,212,158)','rgb(253,187,132)','rgb(252,141,89)','rgb(239,101,72)','rgb(215,48,31)','rgb(179,0,0)','rgb(127,0,0)']},
+YlOrRd:{3:['rgb(255,237,160)','rgb(254,178,76)','rgb(240,59,32)'],4:['rgb(255,255,178)','rgb(254,204,92)','rgb(253,141,60)','rgb(227,26,28)'],5:['rgb(255,255,178)','rgb(254,204,92)','rgb(253,141,60)','rgb(240,59,32)','rgb(189,0,38)'],6:['rgb(255,255,178)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(240,59,32)','rgb(189,0,38)'],7:['rgb(255,255,178)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(252,78,42)','rgb(227,26,28)','rgb(177,0,38)'],8:['rgb(255,255,204)','rgb(255,237,160)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(252,78,42)','rgb(227,26,28)','rgb(177,0,38)'],9:['rgb(255,255,204)','rgb(255,237,160)','rgb(254,217,118)','rgb(254,178,76)','rgb(253,141,60)','rgb(252,78,42)','rgb(227,26,28)','rgb(189,0,38)','rgb(128,0,38)']},
+YlOrBr:{3:['rgb(255,247,188)','rgb(254,196,79)','rgb(217,95,14)'],4:['rgb(255,255,212)','rgb(254,217,142)','rgb(254,153,41)','rgb(204,76,2)'],5:['rgb(255,255,212)','rgb(254,217,142)','rgb(254,153,41)','rgb(217,95,14)','rgb(153,52,4)'],6:['rgb(255,255,212)','rgb(254,227,145)','rgb(254,196,79)','rgb(254,153,41)','rgb(217,95,14)','rgb(153,52,4)'],7:['rgb(255,255,212)','rgb(254,227,145)','rgb(254,196,79)','rgb(254,153,41)','rgb(236,112,20)','rgb(204,76,2)','rgb(140,45,4)'],8:['rgb(255,255,229)','rgb(255,247,188)','rgb(254,227,145)','rgb(254,196,79)','rgb(254,153,41)','rgb(236,112,20)','rgb(204,76,2)','rgb(140,45,4)'],9:['rgb(255,255,229)','rgb(255,247,188)','rgb(254,227,145)','rgb(254,196,79)','rgb(254,153,41)','rgb(236,112,20)','rgb(204,76,2)','rgb(153,52,4)','rgb(102,37,6)']},
+Purples:{3:['rgb(239,237,245)','rgb(188,189,220)','rgb(117,107,177)'],4:['rgb(242,240,247)','rgb(203,201,226)','rgb(158,154,200)','rgb(106,81,163)'],5:['rgb(242,240,247)','rgb(203,201,226)','rgb(158,154,200)','rgb(117,107,177)','rgb(84,39,143)'],6:['rgb(242,240,247)','rgb(218,218,235)','rgb(188,189,220)','rgb(158,154,200)','rgb(117,107,177)','rgb(84,39,143)'],7:['rgb(242,240,247)','rgb(218,218,235)','rgb(188,189,220)','rgb(158,154,200)','rgb(128,125,186)','rgb(106,81,163)','rgb(74,20,134)'],8:['rgb(252,251,253)','rgb(239,237,245)','rgb(218,218,235)','rgb(188,189,220)','rgb(158,154,200)','rgb(128,125,186)','rgb(106,81,163)','rgb(74,20,134)'],9:['rgb(252,251,253)','rgb(239,237,245)','rgb(218,218,235)','rgb(188,189,220)','rgb(158,154,200)','rgb(128,125,186)','rgb(106,81,163)','rgb(84,39,143)','rgb(63,0,125)']},
+Blues:{3:['rgb(222,235,247)','rgb(158,202,225)','rgb(49,130,189)'],4:['rgb(239,243,255)','rgb(189,215,231)','rgb(107,174,214)','rgb(33,113,181)'],5:['rgb(239,243,255)','rgb(189,215,231)','rgb(107,174,214)','rgb(49,130,189)','rgb(8,81,156)'],6:['rgb(239,243,255)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(49,130,189)','rgb(8,81,156)'],7:['rgb(239,243,255)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(66,146,198)','rgb(33,113,181)','rgb(8,69,148)'],8:['rgb(247,251,255)','rgb(222,235,247)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(66,146,198)','rgb(33,113,181)','rgb(8,69,148)'],9:['rgb(247,251,255)','rgb(222,235,247)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(66,146,198)','rgb(33,113,181)','rgb(8,81,156)','rgb(8,48,107)']},
+Greens:{3:['rgb(229,245,224)','rgb(161,217,155)','rgb(49,163,84)'],4:['rgb(237,248,233)','rgb(186,228,179)','rgb(116,196,118)','rgb(35,139,69)'],5:['rgb(237,248,233)','rgb(186,228,179)','rgb(116,196,118)','rgb(49,163,84)','rgb(0,109,44)'],6:['rgb(237,248,233)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(49,163,84)','rgb(0,109,44)'],7:['rgb(237,248,233)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(65,171,93)','rgb(35,139,69)','rgb(0,90,50)'],8:['rgb(247,252,245)','rgb(229,245,224)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(65,171,93)','rgb(35,139,69)','rgb(0,90,50)'],9:['rgb(247,252,245)','rgb(229,245,224)','rgb(199,233,192)','rgb(161,217,155)','rgb(116,196,118)','rgb(65,171,93)','rgb(35,139,69)','rgb(0,109,44)','rgb(0,68,27)']},
+Oranges:{3:['rgb(254,230,206)','rgb(253,174,107)','rgb(230,85,13)'],4:['rgb(254,237,222)','rgb(253,190,133)','rgb(253,141,60)','rgb(217,71,1)'],5:['rgb(254,237,222)','rgb(253,190,133)','rgb(253,141,60)','rgb(230,85,13)','rgb(166,54,3)'],6:['rgb(254,237,222)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(230,85,13)','rgb(166,54,3)'],7:['rgb(254,237,222)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(241,105,19)','rgb(217,72,1)','rgb(140,45,4)'],8:['rgb(255,245,235)','rgb(254,230,206)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(241,105,19)','rgb(217,72,1)','rgb(140,45,4)'],9:['rgb(255,245,235)','rgb(254,230,206)','rgb(253,208,162)','rgb(253,174,107)','rgb(253,141,60)','rgb(241,105,19)','rgb(217,72,1)','rgb(166,54,3)','rgb(127,39,4)']},
+Reds:{3:['rgb(254,224,210)','rgb(252,146,114)','rgb(222,45,38)'],4:['rgb(254,229,217)','rgb(252,174,145)','rgb(251,106,74)','rgb(203,24,29)'],5:['rgb(254,229,217)','rgb(252,174,145)','rgb(251,106,74)','rgb(222,45,38)','rgb(165,15,21)'],6:['rgb(254,229,217)','rgb(252,187,161)','rgb(252,146,114)','rgb(251,106,74)','rgb(222,45,38)','rgb(165,15,21)'],7:['rgb(254,229,217)','rgb(252,187,161)','rgb(252,146,114)','rgb(251,106,74)','rgb(239,59,44)','rgb(203,24,29)','rgb(153,0,13)'],8:['rgb(255,245,240)','rgb(254,224,210)','rgb(252,187,161)','rgb(252,146,114)','rgb(251,106,74)','rgb(239,59,44)','rgb(203,24,29)','rgb(153,0,13)'],9:['rgb(255,245,240)','rgb(254,224,210)','rgb(252,187,161)','rgb(252,146,114)','rgb(251,106,74)','rgb(239,59,44)','rgb(203,24,29)','rgb(165,15,21)','rgb(103,0,13)']},
+Greys:{3:['rgb(240,240,240)','rgb(189,189,189)','rgb(99,99,99)'],4:['rgb(247,247,247)','rgb(204,204,204)','rgb(150,150,150)','rgb(82,82,82)'],5:['rgb(247,247,247)','rgb(204,204,204)','rgb(150,150,150)','rgb(99,99,99)','rgb(37,37,37)'],6:['rgb(247,247,247)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(99,99,99)','rgb(37,37,37)'],7:['rgb(247,247,247)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(115,115,115)','rgb(82,82,82)','rgb(37,37,37)'],8:['rgb(255,255,255)','rgb(240,240,240)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(115,115,115)','rgb(82,82,82)','rgb(37,37,37)'],9:['rgb(255,255,255)','rgb(240,240,240)','rgb(217,217,217)','rgb(189,189,189)','rgb(150,150,150)','rgb(115,115,115)','rgb(82,82,82)','rgb(37,37,37)','rgb(0,0,0)']},
+PuOr:{3:['rgb(241,163,64)','rgb(247,247,247)','rgb(153,142,195)'],4:['rgb(230,97,1)','rgb(253,184,99)','rgb(178,171,210)','rgb(94,60,153)'],5:['rgb(230,97,1)','rgb(253,184,99)','rgb(247,247,247)','rgb(178,171,210)','rgb(94,60,153)'],6:['rgb(179,88,6)','rgb(241,163,64)','rgb(254,224,182)','rgb(216,218,235)','rgb(153,142,195)','rgb(84,39,136)'],7:['rgb(179,88,6)','rgb(241,163,64)','rgb(254,224,182)','rgb(247,247,247)','rgb(216,218,235)','rgb(153,142,195)','rgb(84,39,136)'],8:['rgb(179,88,6)','rgb(224,130,20)','rgb(253,184,99)','rgb(254,224,182)','rgb(216,218,235)','rgb(178,171,210)','rgb(128,115,172)','rgb(84,39,136)'],9:['rgb(179,88,6)','rgb(224,130,20)','rgb(253,184,99)','rgb(254,224,182)','rgb(247,247,247)','rgb(216,218,235)','rgb(178,171,210)','rgb(128,115,172)','rgb(84,39,136)'],10:['rgb(127,59,8)','rgb(179,88,6)','rgb(224,130,20)','rgb(253,184,99)','rgb(254,224,182)','rgb(216,218,235)','rgb(178,171,210)','rgb(128,115,172)','rgb(84,39,136)','rgb(45,0,75)'],11:['rgb(127,59,8)','rgb(179,88,6)','rgb(224,130,20)','rgb(253,184,99)','rgb(254,224,182)','rgb(247,247,247)','rgb(216,218,235)','rgb(178,171,210)','rgb(128,115,172)','rgb(84,39,136)','rgb(45,0,75)']},
+BrBG:{3:['rgb(216,179,101)','rgb(245,245,245)','rgb(90,180,172)'],4:['rgb(166,97,26)','rgb(223,194,125)','rgb(128,205,193)','rgb(1,133,113)'],5:['rgb(166,97,26)','rgb(223,194,125)','rgb(245,245,245)','rgb(128,205,193)','rgb(1,133,113)'],6:['rgb(140,81,10)','rgb(216,179,101)','rgb(246,232,195)','rgb(199,234,229)','rgb(90,180,172)','rgb(1,102,94)'],7:['rgb(140,81,10)','rgb(216,179,101)','rgb(246,232,195)','rgb(245,245,245)','rgb(199,234,229)','rgb(90,180,172)','rgb(1,102,94)'],8:['rgb(140,81,10)','rgb(191,129,45)','rgb(223,194,125)','rgb(246,232,195)','rgb(199,234,229)','rgb(128,205,193)','rgb(53,151,143)','rgb(1,102,94)'],9:['rgb(140,81,10)','rgb(191,129,45)','rgb(223,194,125)','rgb(246,232,195)','rgb(245,245,245)','rgb(199,234,229)','rgb(128,205,193)','rgb(53,151,143)','rgb(1,102,94)'],10:['rgb(84,48,5)','rgb(140,81,10)','rgb(191,129,45)','rgb(223,194,125)','rgb(246,232,195)','rgb(199,234,229)','rgb(128,205,193)','rgb(53,151,143)','rgb(1,102,94)','rgb(0,60,48)'],11:['rgb(84,48,5)','rgb(140,81,10)','rgb(191,129,45)','rgb(223,194,125)','rgb(246,232,195)','rgb(245,245,245)','rgb(199,234,229)','rgb(128,205,193)','rgb(53,151,143)','rgb(1,102,94)','rgb(0,60,48)']},
+PRGn:{3:['rgb(175,141,195)','rgb(247,247,247)','rgb(127,191,123)'],4:['rgb(123,50,148)','rgb(194,165,207)','rgb(166,219,160)','rgb(0,136,55)'],5:['rgb(123,50,148)','rgb(194,165,207)','rgb(247,247,247)','rgb(166,219,160)','rgb(0,136,55)'],6:['rgb(118,42,131)','rgb(175,141,195)','rgb(231,212,232)','rgb(217,240,211)','rgb(127,191,123)','rgb(27,120,55)'],7:['rgb(118,42,131)','rgb(175,141,195)','rgb(231,212,232)','rgb(247,247,247)','rgb(217,240,211)','rgb(127,191,123)','rgb(27,120,55)'],8:['rgb(118,42,131)','rgb(153,112,171)','rgb(194,165,207)','rgb(231,212,232)','rgb(217,240,211)','rgb(166,219,160)','rgb(90,174,97)','rgb(27,120,55)'],9:['rgb(118,42,131)','rgb(153,112,171)','rgb(194,165,207)','rgb(231,212,232)','rgb(247,247,247)','rgb(217,240,211)','rgb(166,219,160)','rgb(90,174,97)','rgb(27,120,55)'],10:['rgb(64,0,75)','rgb(118,42,131)','rgb(153,112,171)','rgb(194,165,207)','rgb(231,212,232)','rgb(217,240,211)','rgb(166,219,160)','rgb(90,174,97)','rgb(27,120,55)','rgb(0,68,27)'],11:['rgb(64,0,75)','rgb(118,42,131)','rgb(153,112,171)','rgb(194,165,207)','rgb(231,212,232)','rgb(247,247,247)','rgb(217,240,211)','rgb(166,219,160)','rgb(90,174,97)','rgb(27,120,55)','rgb(0,68,27)']},
+PiYG:{3:['rgb(233,163,201)','rgb(247,247,247)','rgb(161,215,106)'],4:['rgb(208,28,139)','rgb(241,182,218)','rgb(184,225,134)','rgb(77,172,38)'],5:['rgb(208,28,139)','rgb(241,182,218)','rgb(247,247,247)','rgb(184,225,134)','rgb(77,172,38)'],6:['rgb(197,27,125)','rgb(233,163,201)','rgb(253,224,239)','rgb(230,245,208)','rgb(161,215,106)','rgb(77,146,33)'],7:['rgb(197,27,125)','rgb(233,163,201)','rgb(253,224,239)','rgb(247,247,247)','rgb(230,245,208)','rgb(161,215,106)','rgb(77,146,33)'],8:['rgb(197,27,125)','rgb(222,119,174)','rgb(241,182,218)','rgb(253,224,239)','rgb(230,245,208)','rgb(184,225,134)','rgb(127,188,65)','rgb(77,146,33)'],9:['rgb(197,27,125)','rgb(222,119,174)','rgb(241,182,218)','rgb(253,224,239)','rgb(247,247,247)','rgb(230,245,208)','rgb(184,225,134)','rgb(127,188,65)','rgb(77,146,33)'],10:['rgb(142,1,82)','rgb(197,27,125)','rgb(222,119,174)','rgb(241,182,218)','rgb(253,224,239)','rgb(230,245,208)','rgb(184,225,134)','rgb(127,188,65)','rgb(77,146,33)','rgb(39,100,25)'],11:['rgb(142,1,82)','rgb(197,27,125)','rgb(222,119,174)','rgb(241,182,218)','rgb(253,224,239)','rgb(247,247,247)','rgb(230,245,208)','rgb(184,225,134)','rgb(127,188,65)','rgb(77,146,33)','rgb(39,100,25)']},
+RdBu:{3:['rgb(239,138,98)','rgb(247,247,247)','rgb(103,169,207)'],4:['rgb(202,0,32)','rgb(244,165,130)','rgb(146,197,222)','rgb(5,113,176)'],5:['rgb(202,0,32)','rgb(244,165,130)','rgb(247,247,247)','rgb(146,197,222)','rgb(5,113,176)'],6:['rgb(178,24,43)','rgb(239,138,98)','rgb(253,219,199)','rgb(209,229,240)','rgb(103,169,207)','rgb(33,102,172)'],7:['rgb(178,24,43)','rgb(239,138,98)','rgb(253,219,199)','rgb(247,247,247)','rgb(209,229,240)','rgb(103,169,207)','rgb(33,102,172)'],8:['rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(209,229,240)','rgb(146,197,222)','rgb(67,147,195)','rgb(33,102,172)'],9:['rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(247,247,247)','rgb(209,229,240)','rgb(146,197,222)','rgb(67,147,195)','rgb(33,102,172)'],10:['rgb(103,0,31)','rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(209,229,240)','rgb(146,197,222)','rgb(67,147,195)','rgb(33,102,172)','rgb(5,48,97)'],11:['rgb(103,0,31)','rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(247,247,247)','rgb(209,229,240)','rgb(146,197,222)','rgb(67,147,195)','rgb(33,102,172)','rgb(5,48,97)']},
+RdGy:{3:['rgb(239,138,98)','rgb(255,255,255)','rgb(153,153,153)'],4:['rgb(202,0,32)','rgb(244,165,130)','rgb(186,186,186)','rgb(64,64,64)'],5:['rgb(202,0,32)','rgb(244,165,130)','rgb(255,255,255)','rgb(186,186,186)','rgb(64,64,64)'],6:['rgb(178,24,43)','rgb(239,138,98)','rgb(253,219,199)','rgb(224,224,224)','rgb(153,153,153)','rgb(77,77,77)'],7:['rgb(178,24,43)','rgb(239,138,98)','rgb(253,219,199)','rgb(255,255,255)','rgb(224,224,224)','rgb(153,153,153)','rgb(77,77,77)'],8:['rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(224,224,224)','rgb(186,186,186)','rgb(135,135,135)','rgb(77,77,77)'],9:['rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(255,255,255)','rgb(224,224,224)','rgb(186,186,186)','rgb(135,135,135)','rgb(77,77,77)'],10:['rgb(103,0,31)','rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(224,224,224)','rgb(186,186,186)','rgb(135,135,135)','rgb(77,77,77)','rgb(26,26,26)'],11:['rgb(103,0,31)','rgb(178,24,43)','rgb(214,96,77)','rgb(244,165,130)','rgb(253,219,199)','rgb(255,255,255)','rgb(224,224,224)','rgb(186,186,186)','rgb(135,135,135)','rgb(77,77,77)','rgb(26,26,26)']},
+RdYlBu:{3:['rgb(252,141,89)','rgb(255,255,191)','rgb(145,191,219)'],4:['rgb(215,25,28)','rgb(253,174,97)','rgb(171,217,233)','rgb(44,123,182)'],5:['rgb(215,25,28)','rgb(253,174,97)','rgb(255,255,191)','rgb(171,217,233)','rgb(44,123,182)'],6:['rgb(215,48,39)','rgb(252,141,89)','rgb(254,224,144)','rgb(224,243,248)','rgb(145,191,219)','rgb(69,117,180)'],7:['rgb(215,48,39)','rgb(252,141,89)','rgb(254,224,144)','rgb(255,255,191)','rgb(224,243,248)','rgb(145,191,219)','rgb(69,117,180)'],8:['rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,144)','rgb(224,243,248)','rgb(171,217,233)','rgb(116,173,209)','rgb(69,117,180)'],9:['rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,144)','rgb(255,255,191)','rgb(224,243,248)','rgb(171,217,233)','rgb(116,173,209)','rgb(69,117,180)'],10:['rgb(165,0,38)','rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,144)','rgb(224,243,248)','rgb(171,217,233)','rgb(116,173,209)','rgb(69,117,180)','rgb(49,54,149)'],11:['rgb(165,0,38)','rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,144)','rgb(255,255,191)','rgb(224,243,248)','rgb(171,217,233)','rgb(116,173,209)','rgb(69,117,180)','rgb(49,54,149)']},
+Spectral:{3:['rgb(252,141,89)','rgb(255,255,191)','rgb(153,213,148)'],4:['rgb(215,25,28)','rgb(253,174,97)','rgb(171,221,164)','rgb(43,131,186)'],5:['rgb(215,25,28)','rgb(253,174,97)','rgb(255,255,191)','rgb(171,221,164)','rgb(43,131,186)'],6:['rgb(213,62,79)','rgb(252,141,89)','rgb(254,224,139)','rgb(230,245,152)','rgb(153,213,148)','rgb(50,136,189)'],7:['rgb(213,62,79)','rgb(252,141,89)','rgb(254,224,139)','rgb(255,255,191)','rgb(230,245,152)','rgb(153,213,148)','rgb(50,136,189)'],8:['rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)'],9:['rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)'],10:['rgb(158,1,66)','rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)','rgb(94,79,162)'],11:['rgb(158,1,66)','rgb(213,62,79)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(230,245,152)','rgb(171,221,164)','rgb(102,194,165)','rgb(50,136,189)','rgb(94,79,162)']},
+RdYlGn:{3:['rgb(252,141,89)','rgb(255,255,191)','rgb(145,207,96)'],4:['rgb(215,25,28)','rgb(253,174,97)','rgb(166,217,106)','rgb(26,150,65)'],5:['rgb(215,25,28)','rgb(253,174,97)','rgb(255,255,191)','rgb(166,217,106)','rgb(26,150,65)'],6:['rgb(215,48,39)','rgb(252,141,89)','rgb(254,224,139)','rgb(217,239,139)','rgb(145,207,96)','rgb(26,152,80)'],7:['rgb(215,48,39)','rgb(252,141,89)','rgb(254,224,139)','rgb(255,255,191)','rgb(217,239,139)','rgb(145,207,96)','rgb(26,152,80)'],8:['rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(217,239,139)','rgb(166,217,106)','rgb(102,189,99)','rgb(26,152,80)'],9:['rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(217,239,139)','rgb(166,217,106)','rgb(102,189,99)','rgb(26,152,80)'],10:['rgb(165,0,38)','rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(217,239,139)','rgb(166,217,106)','rgb(102,189,99)','rgb(26,152,80)','rgb(0,104,55)'],11:['rgb(165,0,38)','rgb(215,48,39)','rgb(244,109,67)','rgb(253,174,97)','rgb(254,224,139)','rgb(255,255,191)','rgb(217,239,139)','rgb(166,217,106)','rgb(102,189,99)','rgb(26,152,80)','rgb(0,104,55)']}};
\ No newline at end of file
diff --git a/domtemplates/perbrand.html b/domtemplates/perbrand.html
new file mode 100644 (file)
index 0000000..b44bdbd
--- /dev/null
@@ -0,0 +1,35 @@
+<div class="report-group-col report-group-publication">
+    <h3 class="report-subtitle">
+        Sales  by Brand (Office: {office})
+    </h3>
+    <div class="report-graph "></div>
+    <div class="report-data">
+                
+         <table class="report-grid report-grid-country">
+            <tr> 
+                <th><b>Brand</b></th>
+                <th><b>Qty</b></th>
+                <th><b>Sales</b></th>
+                <th><b>Percent</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkey}</td>
+                <td>{qtysold:number(0)}</td>
+                <td align="right">{currency}${rvalue:number(0)}</td>
+                <td align="right">{percent}</td>
+            </tr>
+             
+        </table>
+
+
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        
+        <a href="#download-publication" class="report-select">Download</a>   
+     
+    </span>
+</div>
+
+
diff --git a/domtemplates/percountry.html b/domtemplates/percountry.html
new file mode 100644 (file)
index 0000000..bc7d4ab
--- /dev/null
@@ -0,0 +1,34 @@
+<div class="report-group-col report-group-publication">
+    <h3 class="report-subtitle">
+        Sales by Country (<span roo-if="office != 'Group'">Office: </span>{office})
+    </h3>
+    <div class="report-graph "></div>
+    <div class="report-data">
+         <table class="report-grid report-grid-country">
+            <tr> 
+                <th><b>Country</b></th>
+                <th><b>Qty</b></th>
+                <th><b>Sales</b></th>
+                <th><b>Percent</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkey}</td>
+                <td>{qtysold:number(0)}</td>
+                <td align="right">{currency}${rvalue:number(0)}</td>
+                <td align="right">{percent}</td>
+            </tr>
+             
+        </table>
+
+
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        
+    <!--     <a href="#download-publication" class="report-select">Download</a>   -->
+     
+    </span>
+</div>
+
+
diff --git a/domtemplates/perday.html b/domtemplates/perday.html
new file mode 100644 (file)
index 0000000..fec801e
--- /dev/null
@@ -0,0 +1,60 @@
+
+<div class="report-group-wide report-group report-group-perday">
+    <h3 class="report-subtitle">
+        By Date:
+    </h3>
+    <span class="report-select-group report-no-print">
+        <a href="#perday-type-qty" class="report-select">Qty</a> |
+        <a href="#perday-type-sales" class="report-select">Sales</a> |
+        <a href="#perday-type-profit" class="report-select">profit</a>
+    </span>
+    <span class="report-select-group report-no-print">
+        <a href="#perday-vtype-value" class="report-select">Value</a> |
+        <a  href="#perday-vtype-cumulative" class="report-select">Cumulative</a>
+    </span>
+  
+    
+    <div class="report-graph report-graph-perday"></div>
+    <div class="report-data report-data-perday" style="width: 390px;">
+        
+        <div class="report-group-wide report-group report-group-perday">
+            <h3 class="report-subtitle">
+                By Date:
+            </h3>
+            <span class="report-select-group report-no-print">
+                <a href="#perday-type-qty" class="report-select">Qty</a> |
+                <a href="#perday-type-sales" class="report-select">Sales</a> |
+                <a href="#perday-type-profit" class="report-select">profit</a>
+            </span>
+            <span class="report-select-group report-no-print">
+                <a href="#perday-vtype-value" class="report-select">Value</a> |
+                <a  href="#perday-vtype-cumulative" class="report-select">Cumulative</a>
+            </span>
+          
+            
+            <div class="report-graph report-graph-perday"></div>
+            <div class="report-data report-data-perday" style="width: 390px;"></div>
+            <span class="report-select-footer report-no-print">
+                <a href="#download-perday" class="report-select">Download</a>   
+                <!-- <a href="#view-perday"  class="report-select report-select-detail">View detail Report</a> -->
+                
+            </span>
+            
+        </div>
+        
+        
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        <!--<a href="#download-perday" class="report-select">Download</a>   -->
+        <!-- <a href="#view-perday"  class="report-select report-select-detail">View detail Report</a> -->
+        
+    </span>
+    
+</div>
+
+
+
+
diff --git a/domtemplates/perproduct.html b/domtemplates/perproduct.html
new file mode 100644 (file)
index 0000000..85293bb
--- /dev/null
@@ -0,0 +1,37 @@
+<div class="report-group-col report-group-publication">
+    <h3 class="report-subtitle">
+        Sales by Product (Office: {office})
+    </h3>
+    <div class="report-graph "></div>
+    <div class="report-data">
+                
+         <table class="report-grid report-grid-country">
+            <tr> 
+                <th><b>Item</b></th>
+                <th><b>Description</b></th>
+                <th><b>Qty</b></th>
+                <th><b>Sales</b></th>
+                <th><b>Percent</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkid}</td>
+                <td>{rkey}</td>
+                <td>{qtysold:number(0)}</td>
+                <td align="right">{currency}${rvalue:number(0)}</td>
+                <td align="right">{percent}</td>
+            </tr>
+             
+        </table>
+
+
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        
+        <a href="#download-publication" class="report-select">Download</a>   
+     
+    </span>
+</div>
+
+
diff --git a/domtemplates/profitbycustomer.html b/domtemplates/profitbycustomer.html
new file mode 100644 (file)
index 0000000..e704c7c
--- /dev/null
@@ -0,0 +1,35 @@
+<div class="report-group-col report-group-publication">
+    <h3 class="report-subtitle">
+        Profit by Customer (Office: {office})
+    </h3>
+    <div class="report-graph "></div>
+    <div class="report-data">
+                
+         <table class="report-grid report-grid-country">
+            <tr> 
+                <th><b>Customer</b></th>
+                <th><b>Qty</b></th>
+                <th><b>Profit</b></th>
+                <th><b>Percent</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkey}</td>
+                <td>{qtysold:number(0)}</td>
+                <td align="right">{currency}${rvalue:number(0)}</td>
+                <td align="right">{percent}</td>
+            </tr>
+             
+        </table>
+
+
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        
+        <a href="#download-publication" class="report-select">Download</a>   
+     
+    </span>
+</div>
+
+
diff --git a/domtemplates/revenuebycustomer.html b/domtemplates/revenuebycustomer.html
new file mode 100644 (file)
index 0000000..b017c22
--- /dev/null
@@ -0,0 +1,35 @@
+<div class="report-group-col report-group-publication">
+    <h3 class="report-subtitle">
+        Sales by Customer (Office: {office})
+    </h3>
+    <div class="report-graph "></div>
+    <div class="report-data">
+                
+         <table class="report-grid report-grid-country">
+            <tr> 
+                <th><b>Customer</b></th>
+                <th><b>Qty</b></th>
+                <th><b>Sales</b></th>
+                <th><b>Percent</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkey}</td>
+                <td>{qtysold:number(0)}</td>
+                <td align="right">{currency}${rvalue:number(0)}</td>
+                <td align="right">{percent}</td>
+            </tr>
+             
+        </table>
+
+
+        
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        
+        <a href="#download-publication" class="report-select">Download</a>   
+     
+    </span>
+</div>
+
+
diff --git a/domtemplates/salestrend.html b/domtemplates/salestrend.html
new file mode 100644 (file)
index 0000000..0518875
--- /dev/null
@@ -0,0 +1,58 @@
+
+<div class="report-group-wide report-group report-group-salestrend">
+    <h3 class="report-subtitle">
+        Sales trend:   (Office: {office})
+    </h3>
+    <!--
+    <span class="report-select-group report-no-print">
+        <a href="#salestrend-type-qty" class="report-select">Qty</a> |
+        <a href="#salestrend-type-sales" class="report-select">Sales</a> |
+        <a href="#salestrend-type-profit" class="report-select">profit</a>
+    </span>
+    <span class="report-select-group report-no-print">
+        <a href="#salestrend-vtype-value" class="report-select">Value</a> |
+        <a  href="#salestrend-vtype-cumulative" class="report-select">Cumulative</a>
+    </span>
+   -->
+    
+    <div class="report-graph report-graph-salestrend"></div>
+    <div class="report-data report-data-salestrend" style="width: 390px;">
+        
+<!--     rmove the grid chart from template-->
+<!--          <table class="report-grid" width="80%">
+            <tr>
+                <th><b>Date</b></th>
+                <th><b>Qty Sold</b></th>
+                <th><b>Sales</b></th>
+                <th><b>Profit</b></th>
+                
+            </tr>
+            <tr roo-for="data">
+                <td><a href="#perday-date-{rklink}" class="report-select">{rmonth}</a></td>
+                <td align="right">{rvalue:number(0)}</td>
+                <td align="right">${sales:number(0)}</td>
+                <td align="right">${profit:number(0)}</td>
+                
+            </tr>
+            <tr>
+                <td>Total</td>
+                <td align="right"><b>{rvaluetotal:number(0)}</b></td>
+                <td align="right"><b>${rsalestotal:number(0)}</b></td>
+                <td align="right"><b>{rprofittotal:number(0)}</b></td>
+            </tr>
+             
+        </table>-->
+        
+    </div>
+    <span class="report-select-footer report-no-print">
+        <a href="#download-salestrend" class="report-select">Download</a>   
+        <!-- <a href="#view-salestrend"  class="report-select report-select-detail">View detail Report</a> -->
+        
+    </span>
+    
+</div>
+
+
+
+
diff --git a/domtemplates/slowmoving.html b/domtemplates/slowmoving.html
new file mode 100644 (file)
index 0000000..bd44e91
--- /dev/null
@@ -0,0 +1,31 @@
+<div class="report-group-col report-group-slowmoving">
+    <h3 class="report-subtitle">
+        Slow Moving (Office: {office})
+    </h3>
+    <!-- <div class="report-graph "></div> -->
+    <div class="report-data">
+                
+         <table class="report-grid report-grid-slowmoving">
+            <tr> 
+                <th><b>SKU</b></th>
+                <th><b>Item</b></th>
+                <th><b>Months to Sell</b></th>
+                <th><b>Stock</b></th>
+                <th><b>Average Sales/month</b></th>
+            </tr>
+            <tr roo-for="data">
+                <td>{rkid}</td>
+                <td>{rkey}</td>
+                <td align="right">{rvalue:number(1)}</td>
+                <td align="right">{cstock:number(0)}</td>
+                <td align="right">{avsales:number(1)}</td>
+                
+            </tr>
+             
+        </table>
+        
+    </div> 
+</div>
+
+
diff --git a/domtemplates/summary.html b/domtemplates/summary.html
new file mode 100644 (file)
index 0000000..4726837
--- /dev/null
@@ -0,0 +1,399 @@
+<style>
+    
+
+
+.report-page
+{
+    font-family: Arial;
+    margin-left:auto;
+    margin-right:auto;
+    margin-top: 10px;
+    width: 990px;
+}
+.report-title {
+    margin-left: 10px;
+    
+}
+/** --- box elements--*/
+.report-group-mediatype,
+.report-group-publication,
+.report-group-perday
+
+{
+   /* height: 250px; */
+}
+
+
+.report-group-percountry
+{
+    height: 590px;
+} 
+.report-group-keywords
+{
+    height: 600px;
+}
+
+.report-group-wide
+{
+    border: 1px solid #ccc;
+    width: 440px;
+    margin : 10px;
+    padding: 10px;
+    float: left;
+    clear: both;
+}
+.report-group-col
+{
+    width: 440px;
+    float: left;
+    border: 1px solid #ccc;
+    margin: 5px;
+    padding: 10px;
+}
+
+.report-group-clear
+{
+    clear:both;
+ }
+
+.report-group-col .report-grid {
+    clear: both;
+}
+
+.report-group,
+.report-filter {
+    border: 1px solid #ccc;
+    margin : 5px;
+    padding: 10px;
+}
+
+
+
+/** --- box elements detail--*/
+.report-subtitle {
+    font-weight: bold;
+    font-size: 12px;
+    display: block;
+}
+
+.report-select-group,
+.report-select-footer
+{
+    font-size: 10px;
+    margin-left: 20px;
+}
+.report-select-footer
+{
+    margin-top: 10px;
+    display: inline-block;
+    clear: both;
+    float: left;
+    width: 100%;
+    margin-left: 0px;
+}
+
+.report-select-perday,
+.report-select-detail
+{
+    float:right;
+}
+.report-select {
+    cursor: pointer;
+    color: #666;
+}
+.report-selected {
+    cursor: default;
+    text-decoration: none;
+    color: #000;
+    font-weight: bold;
+}
+
+.report-selected-on {
+    text-decoration: none;
+    color: red;
+    font-weight: bold;
+}
+
+/** ----- graphs ---- */
+.report-graph {
+    width: 440px;
+    height: 250px;
+    background-color: #f8f8f8;
+    margin-top: 10px;
+    float: left;
+}
+.report-graph-keywords {
+    height: 550px;
+    width:  600px;
+}
+.report-graph-perday {
+    width: 500px;
+}
+/** ----- grids ---- */
+.report-data {
+/*    width: 200px;
+    height: 200px;
+*/
+    width:95%;
+    margin-top: 10px;
+    margin-left: 10px;
+    float: left;
+}
+
+  
+
+table.report-grid
+{
+        width                 :100%;
+/*     border                :none;*/
+       border                :1px solid #CCC;
+  
+}
+
+table.report-grid,
+table.report-grid td
+{
+       border               : 1px solid #CCC;
+       border-collapse      : collapse;
+    font                 : 10px "Tahoma", "Bitstream Vera Sans", Verdana, Helvetica, sans-serif;
+}
+
+table.report-grid thead th,
+table.report-grid  tbody th
+{
+       /*background            : #FFF url(th_bck.gif) repeat-x; */
+  color                 : #666;  
+       padding               : 0px 10px;
+  border-left           : 1px solid #CCC;
+}
+table.report-grid  tbody th
+{
+  background            : #fafafb;
+  border-top            : 1px solid #CCC;
+  text-align            : left;
+  font-weight           : normal;
+}
+table.report-grid  tbody tr td
+{
+       padding               : 0px 10px;
+  color                 : #666;
+}
+table.report-grid  tbody tr:hover
+{
+  /* background            : #FFF url(tr_bck.gif) repeat; */
+  background-color: #eee;
+}
+
+table.report-grid  tbody tr:hover td
+{
+  color                 : #454545;
+}
+table.report-grid  tfoot td,
+table.report-grid  tfoot th
+{
+  border-left           : none;
+  border-top            : 1px solid #CCC;
+       padding               : 4px;
+  /*background            : #FFF url(foot_bck.gif) repeat; */
+  color                 : #666;
+}
+table.report-grid  caption
+{
+       text-align            : left;
+       font-size             : 120%;
+       padding               : 10px 0;
+       color                 : #666;
+}
+table.report-grid  table a:link
+{
+       color                 : #666;
+}
+table.report-grid  table a:visited
+{
+       color                 : #666;
+}
+table.report-grid  table a:hover
+{
+       color                 : #003366;
+       text-decoration       : none;
+}
+table.report-grid  table a:active
+{
+       color                 : #003366;
+}
+
+/*
+table.report-grid-country   td
+{
+    font                 : 8px "Tahoma", "Bitstream Vera Sans", Verdana, Helvetica, sans-serif;
+}
+*/
+.report-filter
+{
+   width: 160px;
+   float: left;
+}
+.report-filter a.option
+{
+    display:block;
+    clear:both;
+    font-size: 12px;
+    color : #666;
+    text-decoration: none;
+    background: transparent url(./roojs1/images/default/menu/chk-sprite.gif) no-repeat scroll 0 0;
+    height: 16px;
+    padding-left: 20px;
+}
+
+.report-filter a.option-selected {
+    background-position: 0 -16px;
+}
+
+
+/** --- top block --*/
+.report-top-block,
+.report-group-summary-sg
+
+{
+    display: inline-block;
+    float:left;
+}
+.report-top-block .report-bignum {
+    font-size: 20px;
+    font-weight: bold;
+     clear:both;
+    display: block;
+}
+.report-top-block .report-bignum-subtext {
+    font-size: 10px;
+    font-style: italic;
+    clear:both;
+    display: block;
+}
+
+.left {
+    float: left;
+}
+.report-group-row {
+    width:100%;
+}
+</style>
+
+<style media="print">
+.report-subtitle {
+    font-weight: bold;
+    font-size: 14px;
+}
+     
+</style>
+
+<div class="report-page">
+    
+    <div class="report-title">Report for <B>{curdates.date.format:("d M Y")} to {curdates.dateto.format:("d M Y")} </B>
+        <span roo-for="breadcrumbs" class="report-breadcrumbs">
+            &gt; <b>{btitle}</b> 
+        </span>
+    </div>
+     
+    <div style="display:none;"><br/><br/><br/><br/><br/></div>
+        
+        
+    <div class="report-top-summary">
+        <div class="report-group-totals-all report-group-totals"></div>
+        <div class="report-group-totals-hk report-group-totals"></div>
+        <div class="report-group-totals-sg report-group-totals"></div>
+        <div class="report-group-totals-my report-group-totals"></div>
+        <div class="report-group-totals-cn report-group-totals"></div>
+        <div class="report-group-totals-au-0 report-group-totals"></div>
+        <div class="report-group-totals-au-1 report-group-totals"></div>
+    </div>
+      
+    <div class="report-group-row report-group-clear">  
+        <div class="left report-group-salestrend-hk"></div>
+        <div class="left report-group-salestrend-sg"></div>
+<div class="left report-group-salestrend-my"></div>
+<div class="left report-group-salestrend-cn"></div>
+<div class="left report-group-salestrend-au"></div>
+
+    </div>     
+    <div style="display:none"><br/><br/><br/><br/><br/></div>
+     
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-percountry report-group-percountry-all"></div>
+         <div class="left report-group-percountry report-group-percountry-hk"></div>
+         <div class="left report-group-percountry report-group-percountry-sg"></div>
+         <div class="left report-group-percountry report-group-percountry-my"></div>
+         <div class="left report-group-percountry report-group-percountry-cn"></div>
+         <div class="left report-group-percountry report-group-percountry-au"></div>
+         
+     </div>
+     
+     <div style="display:none"><br/><br/><br/><br/><br/></div>
+      
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-revenuebycustomer-hk"></div>
+         <div class="left report-group-revenuebycustomer-sg"></div>
+         <div class="left report-group-revenuebycustomer-my"></div>
+         <div class="left report-group-revenuebycustomer-cn"></div>
+         <div class="left report-group-revenuebycustomer-au"></div>
+
+     </div>
+      
+     <div style="display:none"><br/><br/><br/><br/><br/></div>
+      
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-profitbycustomer-hk"></div>
+         <div class="left report-group-profitbycustomer-sg"></div>
+        <div class="left report-group-profitbycustomer-my"></div>
+        <div class="left report-group-profitbycustomer-cn"></div>
+        <div class="left report-group-profitbycustomer-au"></div>
+     </div>
+      
+      
+      <div style="display:none"><br/><br/><br/><br/><br/></div>
+      
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-perbrand-hk"></div>
+        <div class="left report-group-perbrand-sg"></div>
+        <div class="left report-group-perbrand-my"></div>
+        <div class="left report-group-perbrand-cn"></div>
+        <div class="left report-group-perbrand-au"></div>
+
+     </div>
+      
+      
+      
+      <div style="display:none"><br/><br/><br/><br/><br/></div>
+      
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-perproduct-hk"></div>
+         <div class="left report-group-perproduct-sg"></div>
+         <div class="left report-group-perproduct-my"></div>
+         <div class="left report-group-perproduct-cn"></div>
+         <div class="left report-group-perproduct-au"></div>
+     </div>
+      
+       
+     <div style="display:none"><br/><br/><br/><br/><br/></div>
+      
+      <div class="report-group-row report-group-clear">
+         <div class="left report-group-slowmoving-hk"></div>
+         <div class="left report-group-slowmoving-sg"></div>
+<div class="left report-group-slowmoving-my"></div>
+<div class="left report-group-slowmoving-cn"></div>
+<div class="left report-group-slowmoving-au"></div>
+     </div>
+       
+       
+    </div>
+    
+    
+    
+    
+    
+</div>
diff --git a/domtemplates/totals.html b/domtemplates/totals.html
new file mode 100644 (file)
index 0000000..7c72d98
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="report-top-block report-group">
+    <span class="report-bignum">{office} <span roo-if="office != 'Group'">Office{total_type}</span></span>
+    <span roo-for="data" >
+        <span class="report-bignum">Sales: {currency}{soldat_hkd:number(0)}</span>
+       <!-- <span class="report-bignum-subtext" style="color:red">Sales in Current Months include unshipped orders</span> -->
+        <span class="report-bignum-subtext">{qtysold:number(0)} Items Sold</span>
+<!--        <span class="report-bignum">Net Profit {currency}{net_profit_hkd:number(0)}</span>
+        <span class="report-bignum-subtext" style="color:red">Excludes end of this month expenses</span>
+    -->    <!--<span class="report-bignum-subtext">Revenue: {currency}{revenue_hkd:number(0)} / Expenses: HK${expenses_hkd:number(0)}</span> -->
+        
+    </span>
+</div>
+    
+
diff --git a/dumpAccnt.php b/dumpAccnt.php
new file mode 100644 (file)
index 0000000..ea3ac94
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * -- Dump accnt and backaccnt from HK
+ * 
+ *
+ */
+require_once 'Pman.php';
+class Pman_Xtuple_dumpAccnt extends Pman
+{
+    static $cli_desc = "Dump accnt and backaccnt from HK";
+    
+    var $cli = false;
+    
+    function getAuth() {
+        
+        
+        $ff = HTML_FlexyFramework::get();
+        if (!empty($ff->cli)) {
+            $this->cli = true;
+            return true;
+        }
+        die("NOT ALLOWED");
+    }
+    
+    function get()
+    {
+        
+        $accnt = DB_DataObject::factory('accnt');
+        $accnt->joinAddBankaccnt();
+        $accnt->SelectAdd("
+            (SELECT curr_abbr FROM curr_symbol WHERE curr_id = accnt_curr_id) AS accnt_curr_abbr,
+            (SELECT curr_abbr FROM curr_symbol WHERE curr_id = bankaccnt_curr_id) AS bankaccnt_curr_abbr
+        ");
+        $accnt->find();
+        $accnts = array();
+        while ($accnt->fetch()){
+            $line = $accnt->toArray();
+            foreach($line as $k=>$v) {
+                if (is_string($v) && !strlen($v)) {
+                    unset($line[$k]);
+                }
+                
+            }
+            
+            $accnts[] = json_encode($line);
+        }
+        echo "[\n". implode(",\n", $accnts) . "]";
+        
+        exit;
+    }
+    
+    
+    
+}
\ No newline at end of file
diff --git a/pgsql/apaging.sql b/pgsql/apaging.sql
new file mode 100644 (file)
index 0000000..f1464e0
--- /dev/null
@@ -0,0 +1,221 @@
+-- Function: apaging(date, boolean)
+
+-- fixed to include correct apply currency 
+
+-- DROP FUNCTION apaging(date, boolean);
+
+CREATE OR REPLACE FUNCTION apaging(pAsOfDate date, pUseDocDate boolean)
+  RETURNS SETOF apaging AS
+$BODY$
+DECLARE
+  
+  _row apaging%ROWTYPE;
+  _x RECORD;
+  _returnVal INTEGER;
+  _asOfDate DATE;
+BEGIN
+
+  _asOfDate := COALESCE(pAsOfDate,current_date);
+
+  FOR _x IN
+        SELECT
+        --report uses currency rate snapshot to convert all amounts to base based on apopen_docdate to ensure the same exchange rate
+        
+        
+        --- aptarget_paid - may be in a different currency
+        --- if the target != the apopen...
+        
+        
+                
+                
+        
+
+        --today and greater base:
+        CASE WHEN((apopen.apopen_duedate >= DATE(_asOfDate)))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS cur_val,
+
+        --0 to 30 base
+        CASE WHEN((apopen.apopen_duedate >= DATE(_asOfDate)-30) AND (apopen.apopen_duedate < DATE(_asOfDate)))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS thirty_val,
+
+        --30-60 base
+        CASE WHEN((apopen.apopen_duedate >= DATE(_asOfDate)-60) AND (apopen.apopen_duedate < DATE(_asOfDate) - 30 ))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS sixty_val,
+
+        --60-90 base
+        CASE WHEN((apopen.apopen_duedate >= DATE(_asOfDate)-90) AND (apopen.apopen_duedate < DATE(_asOfDate) - 60))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS ninety_val,
+
+        --greater than 90 base:
+        CASE WHEN((apopen.apopen_duedate > DATE(_asOfDate)-10000) AND (apopen.apopen_duedate < DATE(_asOfDate) - 90))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS plus_val,
+
+        --total amount base:
+        CASE WHEN((apopen.apopen_duedate > DATE(_asOfDate)-10000))
+        THEN ((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+        CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS total_val,
+
+        --AR Open Amount base
+        CASE WHEN apopen.apopen_doctype IN ('C', 'R') 
+        THEN (apopen.apopen_amount * -1) / apopen.apopen_curr_rate
+        ELSE apopen.apopen_amount / apopen.apopen_curr_rate END AS apopen_amount,
+        
+       
+        apopen.apopen_docdate,
+        apopen.apopen_duedate,
+        apopen.apopen_ponumber,
+        apopen.apopen_invcnumber,
+        apopen.apopen_docnumber,
+        apopen.apopen_doctype,
+        vend_id,
+        vend_name,
+        vend_number,
+        vend_vendtype_id,
+        vendtype_code,
+        terms_descrip,
+         apopen.apopen_id::text as apopen_id
+
+        FROM vendinfo, vendtype, apopen
+          LEFT OUTER JOIN terms ON (apopen.apopen_terms_id=terms_id)
+          LEFT OUTER JOIN apapply ON (((apopen.apopen_id=apapply_target_apopen_id)
+                                    OR (apopen.apopen_id=apapply_source_apopen_id))
+                                   AND (apapply_postdate >=_asOfDate))
+          LEFT OUTER JOIN apopen target_ap
+            ON apapply_target_apopen_id = target_ap.apopen_id
+                
+        WHERE ( (apopen.apopen_vend_id = vend_id)
+        AND (vend_vendtype_id=vendtype_id)
+        AND (CASE WHEN (pUseDocDate) THEN apopen.apopen_docdate ELSE apopen.apopen_distdate END <= _asOfDate)
+        AND (COALESCE(apopen.apopen_closedate,_asOfDate)>=_asOfDate) 
+        -- VOID ???
+        AND
+        apopen.apopen_docnumber NOT IN (
+                                SELECT 
+                                                        apopen_docnumber
+                                                FROM
+                                                        apopen
+                                                WHERE
+                                                        apopen_notes LIKE 'Void Voucher%'
+                                                    AND
+                                                        apopen_discount
+                                )
+        
+        )
+        GROUP BY apopen.apopen_id,apopen.apopen_docdate,apopen.apopen_duedate,apopen.apopen_ponumber, apopen.apopen_invcnumber, apopen.apopen_docnumber,apopen.apopen_doctype,apopen.apopen_paid,
+                 apopen.apopen_curr_id,apopen.apopen_amount,vend_id,vend_name,vend_number,vend_vendtype_id,vendtype_code,terms_descrip,
+                 apopen.apopen_curr_rate
+        
+        UNION
+         SELECT
+            0 as cur_val,
+            0 as thirty_val,
+            0 as sixty_val,
+            0 as ninety_val,
+            0 as plus_val,
+            -- we should use checkitem_docdate rather than apapply_postdate..
+            CASE WHEN checkhead_void THEN
+                checkhead_amount / checkhead_curr_rate * -1
+            ELSE
+                apapply_target_paid / apopen_curr_rate * -1
+            END AS total_val,
+
+            CASE WHEN checkhead_void THEN
+                checkhead_amount / checkhead_curr_rate * -1
+            ELSE
+                apapply_target_paid / apopen_curr_rate * -1
+            END AS apopen_amount,
+
+            
+            checkhead_checkdate as apopen_docdate,
+            checkhead_checkdate as apopen_duedate,
+            '' as apopen_ponumber,
+            '' as apopen_invcnumber,
+            checkhead_number::text as apopen_docnumber,
+            'CK' as apopen_doctype,
+            vend_id,
+            vend_name,
+            vend_number,
+            vend_vendtype_id,
+            vendtype_code,
+            '' as terms_descrip,
+             checkhead_id::text as apopen_id
+             
+            FROM
+                    checkhead
+                 LEFT JOIN
+                    apapply
+                ON
+                    apapply_journalnumber = checkhead_journalnumber
+                    AND
+                    checkhead_id = apapply_checkhead_id
+                LEFT JOIN 
+                         apopen
+                ON
+                         apopen_id = apapply_target_apopen_id
+
+               LEFT JOIN
+                   vendinfo
+                   ON
+                    checkhead_recip_id = vend_id
+
+               LEFT JOIN
+                    vendtype 
+               ON
+                   vend_vendtype_id=vendtype_id
+
+            WHERE (
+                   checkhead_recip_type = 'V'
+             --   AND NOT checkhead_deleted  
+                AND
+                   (
+                        (NOT checkhead_void AND apapply_postdate >= _asOfDate)
+                        OR
+                        (checkhead_void AND checkhead_voided > _asOfDate)
+                    )  
+
+                AND
+                   (checkhead_checkdate <= _asOfDate) 
+
+                 )
+                
+        ORDER BY
+        
+        
+          vend_number, apopen_duedate
+  LOOP
+        _row.apaging_docdate := _x.apopen_docdate;
+        _row.apaging_duedate := _x.apopen_duedate;
+        _row.apaging_ponumber := _x.apopen_ponumber;
+        _row.apaging_invcnumber := _x.apopen_invcnumber;
+        _row.apaging_docnumber := _x.apopen_docnumber;
+        _row.apaging_doctype := _x.apopen_doctype;
+        _row.apaging_vend_id := _x.vend_id;
+        _row.apaging_vend_number := _x.vend_number;
+        _row.apaging_vend_name := _x.vend_name;
+        _row.apaging_vend_vendtype_id := _x.vend_vendtype_id;
+        _row.apaging_vendtype_code := _x.vendtype_code;
+        _row.apaging_terms_descrip := _x.terms_descrip;
+        _row.apaging_apopen_amount := _x.apopen_amount;
+        _row.apaging_cur_val := _x.cur_val;
+        _row.apaging_thirty_val := _x.thirty_val;
+        _row.apaging_sixty_val := _x.sixty_val;
+        _row.apaging_ninety_val := _x.ninety_val;
+        _row.apaging_plus_val := _x.plus_val;
+        _row.apaging_total_val := _x.total_val;
+        _row.apaging_reference := _x.apopen_id::text;
+        RETURN NEXT _row;
+  END LOOP;
+  RETURN;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100
+  ROWS 1000;
+ALTER FUNCTION apaging(date, boolean)
+  OWNER TO admin;
diff --git a/pgsql/coitem_delete_trigger.sql b/pgsql/coitem_delete_trigger.sql
new file mode 100644 (file)
index 0000000..bbd2d3f
--- /dev/null
@@ -0,0 +1,34 @@
+-- idea is to prevent deletion of coitems if there is 
+
+
+CREATE OR REPLACE FUNCTION coitem_delete_trigger() RETURNS trigger 
+AS $BODY$
+DECLARE
+     v_tmp_id INT;
+BEGIN
+         
+    IF (
+            (OLD.coitem_qtyshipped > 0)
+            AND
+            (OLD.coitem_qtyreturned !=  OLD.coitem_qtyshipped)
+    ) THEN
+        RAISE EXCEPTION 'You can not delete order lines that have already been shipped';
+    END IF;
+    
+   RETURN OLD;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  coitem_delete_trigger()
+  OWNER TO admin;
+
+
+GRANT ALL ON FUNCTION coitem_delete_trigger() TO xtrole;
+
+CREATE TRIGGER _coitem_delete_trigger 
+    BEFORE DELETE  ON  coitem
+        FOR EACH ROW EXECUTE PROCEDURE coitem_delete_trigger();
+        
\ No newline at end of file
diff --git a/pgsql/createapcreditmemoapplication.sql b/pgsql/createapcreditmemoapplication.sql
new file mode 100644 (file)
index 0000000..cbb94f6
--- /dev/null
@@ -0,0 +1,58 @@
+-- updated to match recent version
+-- added roudning on currtocurr...
+
+
+CREATE OR REPLACE FUNCTION createAPCreditMemoApplication(pSourceApopenId INTEGER,
+                                                         pTargetApopenId INTEGER,
+                                                         pAmount NUMERIC,
+                                                         pCurrId INTEGER) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _apCreditApplyId     INTEGER;
+
+BEGIN
+  IF (pAmount > ROUND((SELECT currToCurr(apopen_curr_id, pCurrId, ROUND(apopen_amount - apopen_paid, 2), apopen_docdate)
+                 FROM apopen
+                 WHERE (apopen_id=pTargetApopenId)),2)) THEN
+    RETURN -1;
+  END IF;
+
+  IF (pAmount > (SELECT ROUND((apopen_amount - apopen_paid) - 
+                      COALESCE(SUM(currToCurr(apcreditapply_curr_id,
+                                               apopen_curr_id, 
+                                               apcreditapply_amount, 
+                                               apopen_docdate)), 0), 2)
+             FROM apopen LEFT OUTER JOIN apcreditapply 
+               ON ((apcreditapply_source_apopen_id=apopen_id) 
+              AND (apcreditapply_target_apopen_id<>pTargetApopenId)) 
+             WHERE (apopen_id=pSourceApopenId) 
+             GROUP BY apopen_amount, apopen_paid)) THEN
+      RETURN -2;
+    END IF;
+
+  SELECT apcreditapply_id INTO _apCreditApplyId
+    FROM apcreditapply
+   WHERE ((apcreditapply_source_apopen_id=pSourceApopenId)
+     AND  (apcreditapply_target_apopen_id=pTargetApopenId));
+
+  IF (FOUND) THEN
+    UPDATE apcreditapply SET apcreditapply_amount=pAmount,
+                            apcreditapply_curr_id=pCurrId
+    WHERE (apcreditapply_id=_apCreditApplyId);
+  ELSE
+    INSERT INTO apcreditapply (
+      apcreditapply_source_apopen_id,
+      apcreditapply_target_apopen_id,
+      apcreditapply_amount, apcreditapply_curr_id
+    ) VALUES (
+      pSourceApopenId,
+      pTargetApopenId,
+      pAmount, pCurrId)
+    RETURNING apcreditapply_id INTO _apCreditApplyId;
+  END IF;
+
+  RETURN _apCreditApplyId;
+
+END;
+$$ LANGUAGE 'plpgsql';
\ No newline at end of file
diff --git a/pgsql/enterporeturn.sql b/pgsql/enterporeturn.sql
new file mode 100644 (file)
index 0000000..f7e8bca
--- /dev/null
@@ -0,0 +1,65 @@
+-- modified to allow dates to be set..
+
+
+-- Function: enterporeturn(integer, numeric, integer)
+
+-- DROP FUNCTION enterporeturn(integer, numeric, integer);
+
+CREATE OR REPLACE FUNCTION enterporeturn(integer, numeric, integer, date)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pPoitemid ALIAS FOR $1;
+  pQty ALIAS FOR $2;
+  pRjctcodeid ALIAS FOR $3;
+  v_reject_date ALIAS FOR $4;
+  _porejectid INTEGER;
+
+BEGIN
+
+    SELECT NEXTVAL('poreject_poreject_id_seq') INTO _porejectid;
+
+    INSERT INTO poreject
+    (
+        poreject_id, poreject_date,
+        poreject_ponumber, poreject_poitem_id,
+        
+        poreject_trans_username, poreject_agent_username,
+        poreject_itemsite_id, poreject_vend_id,
+        
+        poreject_vend_item_number, poreject_vend_item_descrip,
+        poreject_vend_uom,   poreject_qty,
+        
+        poreject_rjctcode_id, poreject_posted,
+        poreject_invoiced
+    ) SELECT
+            _porejectid, v_reject_date,
+            pohead_number, poitem_id,
+            
+            getEffectiveXtUser(),         pohead_agent_username,
+            poitem_itemsite_id,         pohead_vend_id,
+            
+            poitem_vend_item_number, poitem_vend_item_descrip,
+            poitem_vend_uom, pQty,
+            
+            pRjctcodeid, FALSE,
+            FALSE
+        FROM
+            pohead, poitem
+        WHERE
+            (
+                (poitem_pohead_id=pohead_id)
+            AND
+                (poitem_id=pPoitemid)
+            );
+
+    RETURN _porejectid;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION enterporeturn(integer, numeric, integer, date)
+  OWNER TO admin;
diff --git a/pgsql/explodekit.sql b/pgsql/explodekit.sql
new file mode 100644 (file)
index 0000000..6dcac9b
--- /dev/null
@@ -0,0 +1,262 @@
+
+-- code to handle updating kit parts better...
+
+
+CREATE OR REPLACE FUNCTION explodekitmustdelete(integer, integer, integer, integer)
+ RETURNS integer AS
+$BODY$
+DECLARE
+     pSoheadid ALIAS FOR $1;
+  pLinenumber ALIAS FOR $2;
+  pSubnumber ALIAS FOR $3;
+  pItemsiteid ALIAS FOR $4;
+  _warehousid INTEGER;
+  _itemid INTEGER;
+  _revid INTEGER;
+
+  _ret INTEGER;
+  
+BEGIN
+    
+  SELECT getActiveRevId('BOM',itemsite_item_id), itemsite_warehous_id, itemsite_item_id
+    INTO _revid, _warehousid, _itemid
+    FROM itemsite
+   WHERE(itemsite_id=pItemsiteid);
+  IF(NOT FOUND) THEN
+    RAISE EXCEPTION 'No Item Site for the specified line was found.';
+  END IF;
+    
+    SELECT count(itemsite_id) INTO _ret
+  
+        FROM bomitem JOIN item ON (item_id=bomitem_item_id)
+             LEFT OUTER JOIN itemsite ON ((itemsite_item_id=item_id) AND (itemsite_warehous_id=_warehousid))
+        WHERE((bomitem_parent_item_id=_itemid)
+            AND (bomitem_rev_id=_revid)
+            AND (CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1)))
+            AND  itemsite_createsopr = true 
+            AND itemsite_createsopo = true 
+            AND itemsite_createwo = true;
+             
+    if (_ret > 0) THEN
+        RETURN _ret;
+    END IF;
+    
+    SELECT count(coitem_id) INTO _ret
+        FROM
+            coitem
+        WHERE
+            coitem_cohead_id = pSoheadid
+            AND 
+            coitem_linenumber = pLinenumber
+            AND 
+            coitem_subnumber > 0
+            AND
+            coitem_order_type IS NOT NULL
+        LIMIT 1;
+    
+    RETURN _ret;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION explodekitmustdelete(integer, integer, integer, integer)
+  OWNER TO admin;
+
+
+-- Function: explodekit(integer, integer, integer, integer, numeric, date, date, text)
+
+-- DROP FUNCTION explodekit(integer, integer, integer, integer, numeric, date, date, text);
+
+CREATE OR REPLACE FUNCTION explodekit(integer, integer, integer, integer, numeric, date, date, text)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pSoheadid ALIAS FOR $1;
+  pLinenumber ALIAS FOR $2;
+  pSubnumber ALIAS FOR $3;
+  pItemsiteid ALIAS FOR $4;
+  pQty ALIAS FOR $5;
+  pScheddate ALIAS FOR $6;
+  pPromdate ALIAS FOR $7;
+  pMemo ALIAS FOR $8;
+  _subnumber INTEGER := COALESCE(pSubnumber,0);
+  _revid INTEGER;
+  _itemid INTEGER;
+  _warehousid INTEGER;
+  _item RECORD;
+  _type TEXT;
+  _coitemid INTEGER;
+  _count INTEGER;
+  _orderid INTEGER := 0;
+  _itemsrcid INTEGER;
+  _hascreates INTEGER;
+BEGIN
+
+  SELECT getActiveRevId('BOM',itemsite_item_id), itemsite_warehous_id, itemsite_item_id
+    INTO _revid, _warehousid, _itemid
+    FROM itemsite
+   WHERE(itemsite_id=pItemsiteid);
+  IF(NOT FOUND) THEN
+    RAISE EXCEPTION 'No Item Site for the specified line was found.';
+  END IF;
+
+-- if any of the items have    itemsite_createsopr or itemsite_createsopo
+-- then we have to trash all the items before starting..
+  
+    
+     
+
+  FOR _item IN
+  SELECT bomitem_id, 
+         itemsite_id,
+         itemsite_warehous_id,
+         COALESCE((itemsite_active AND item_active), false) AS active,
+         COALESCE((itemsite_sold AND item_sold), false) AS sold,
+         item_id,
+         item_type,
+         item_price_uom_id,
+         itemsite_createsopr,itemsite_createwo,itemsite_createsopo, itemsite_dropship,
+         bomitem_uom_id,
+         itemuomtouomratio(item_id, bomitem_uom_id, item_inv_uom_id) AS invuomratio,
+         roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id),(bomitem_qtyfxd + bomitem_qtyper * pQty) * (1 + bomitem_scrap)) AS qty
+    FROM bomitem JOIN item ON (item_id=bomitem_item_id)
+                  LEFT OUTER JOIN itemsite ON ((itemsite_item_id=item_id) AND (itemsite_warehous_id=_warehousid))
+   WHERE((bomitem_parent_item_id=_itemid)
+     AND (bomitem_rev_id=_revid)
+     AND (CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1)))
+   ORDER BY bomitem_seqnumber LOOP
+   
+    IF (NOT _item.active) THEN
+      RAISE EXCEPTION 'One or more of the components for the kit is inactive for the selected item site.';
+    ELSIF (NOT _item.sold) THEN
+      RAISE EXCEPTION 'One or more of the components for the kit is not sold for the selected item site.';
+    ELSIF (_item.item_type='F') THEN
+      -- not sure what this does?? F=???
+      
+    
+      SELECT explodeKit(pSoheadid, pLinenumber, _subnumber, _item.itemsite_id, _item.qty)
+        INTO _subnumber;
+    ELSE
+      IF (_item.itemsite_createsopr) THEN
+        _type := 'R';
+      ELSIF (_item.itemsite_createsopo) THEN
+        _type := 'P';
+      ELSIF (_item.itemsite_createwo) THEN
+        _type := 'W';
+      ELSE
+        _type := NULL;
+      END IF;
+      _subnumber := _subnumber + 1;
+      
+      -- IF THE LINE EXISTS.. then update. it..
+      
+      SELECT coitem_id FROM coitem INTO _coitemid WHERE 
+        coitem_cohead_id = pSoheadid
+        AND 
+        coitem_linenumber = pLinenumber
+        AND 
+        coitem_subnumber = _subnumber
+        LIMIT 1;
+     
+      IF (NOT FOUND) THEN 
+      
+        
+        _coitemid = nextval('coitem_coitem_id_seq');
+        raise notice 'coitem id: %',_coitemid;
+        INSERT INTO coitem
+              (coitem_id, coitem_cohead_id,
+               coitem_linenumber, coitem_subnumber,
+               coitem_itemsite_id, coitem_status,
+               coitem_scheddate, coitem_promdate,
+               coitem_qtyord, coitem_qty_uom_id, coitem_qty_invuomratio,
+               coitem_qtyshipped, coitem_qtyreturned,
+               coitem_unitcost, coitem_custprice,
+               coitem_price, coitem_price_uom_id, coitem_price_invuomratio,
+               coitem_order_type, coitem_order_id,
+               coitem_custpn, coitem_memo,
+               coitem_prcost)
+        VALUES (_coitemid, pSoheadid,
+               pLinenumber, _subnumber,
+               _item.itemsite_id, 'O',
+               pScheddate, pPromdate,
+               _item.qty, _item.bomitem_uom_id, _item.invuomratio,
+               0, 0,
+               stdCost(_item.item_id), 0,
+               0, _item.item_price_uom_id, 1,
+               _type, -1,
+               '', pMemo,
+               0);
+     ELSE
+        IF (_type IS NOT NULL) THEN
+        
+            RAISE EXCEPTION 'can not update coitems - use explodekitcanupdate to check first';
+        END IF;
+      
+        UPDATE coitem SET
+       
+               coitem_itemsite_id = _item.itemsite_id    , 
+               coitem_status =   'O', 
+               coitem_scheddate =  pScheddate  ,
+               coitem_promdate =   pPromdate ,
+               coitem_qtyord = _item.qty   ,
+               coitem_qty_uom_id =  _item.bomitem_uom_id   ,
+               coitem_qty_invuomratio =   _item.invuomratio  ,
+               coitem_qtyshipped =  0  ,
+               coitem_qtyreturned = 0   ,
+               coitem_unitcost = stdCost(_item.item_id)   ,
+               coitem_custprice = 0   ,
+               coitem_price =  0 ,
+               coitem_price_uom_id =   _item.item_price_uom_id   ,
+               coitem_price_invuomratio =   1 ,
+               coitem_order_type =  _type  ,
+               coitem_order_id =  -1  ,
+               coitem_custpn =   '' ,
+               coitem_memo =  pMemo  ,
+               coitem_prcost = 0
+               
+         WHERE coitem_id = _coitemid;
+      
+      END IF;
+       
+      
+      IF (_item.itemsite_createsopr) THEN
+        SELECT createPR(cohead_number::INTEGER, 'S', _coitemid) INTO _orderid
+            FROM cohead
+            WHERE (cohead_id=pSoheadid);
+        IF (_orderid > 0) THEN
+          UPDATE coitem SET coitem_order_id=_orderid
+            WHERE (coitem_id=_coitemid);
+        ELSE
+          RAISE EXCEPTION 'Could not explode kit. CreatePR failed, result=%', _orderid; 
+        END IF;
+      END IF;
+
+      IF (_item.itemsite_createsopo) THEN
+        SELECT itemsrc_id INTO _itemsrcid
+        FROM itemsrc
+        WHERE ((itemsrc_item_id=_item.item_id)
+        AND (itemsrc_default));
+
+        GET DIAGNOSTICS _count = ROW_COUNT;
+        IF (_count > 0) THEN
+          PERFORM createPurchaseToSale(_coitemid, _itemsrcid, _item.itemsite_dropship);
+        ELSE
+          RAISE EXCEPTION 'Could not explode kit.  One or more items are flagged as purchase-to-order for this site, but no default item source is defined.';
+        END IF;
+      END IF;
+     
+    END IF;
+  END LOOP;
+
+  RETURN _subnumber;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION explodekit(integer, integer, integer, integer, numeric, date, date, text)
+  OWNER TO admin;
+
+
+
diff --git a/pgsql/fetchinvnumber.sql b/pgsql/fetchinvnumber.sql
new file mode 100644 (file)
index 0000000..b879d94
--- /dev/null
@@ -0,0 +1,52 @@
+-- modified to fix dupe invoices being created.
+
+-- Function: fetchinvcnumber()
+
+-- DROP FUNCTION fetchinvcnumber();
+
+CREATE OR REPLACE FUNCTION fetchinvcnumber()
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _invcNumber INTEGER;
+  _test INTEGER;
+
+BEGIN
+
+  LOOP
+
+    SELECT orderseq_number INTO _invcNumber
+    FROM orderseq
+    WHERE (orderseq_name='InvcNumber');
+
+    UPDATE orderseq
+    SET orderseq_number = (orderseq_number + 1)
+    WHERE (orderseq_name='InvcNumber');
+
+    SELECT invchead_id INTO _test
+    FROM invchead
+    WHERE invchead_invcnumber = _invcNumber::text;
+    IF FOUND THEN
+        CONTINUE;
+    END IF;
+
+    SELECT cobmisc_id INTO _test
+    FROM cobmisc
+    WHERE (cobmisc_invcnumber=_invcNumber);
+
+    IF (NOT FOUND) THEN
+      EXIT;
+    END IF;
+
+  END LOOP;
+
+  RETURN _invcNumber;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION fetchinvcnumber()
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/fifo-testing/fifo-test-1.sql b/pgsql/fifo-testing/fifo-test-1.sql
new file mode 100644 (file)
index 0000000..6092755
--- /dev/null
@@ -0,0 +1,49 @@
+--
+
+
+-- Testing to see if fifo works.
+
+-- take FTBL in OLL...
+
+-- item = 1354
+-- itemsite=  1559
+-- location_id = 127
+
+-- see the progression of value and qty.
+
+--SELECT invfifo_update_from_invdetail(11609) ;
+SELECT invfifo_update_from_invdetail(55708) ;      
+         
+
+SELECT  invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+        invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 127
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 100;
+    
+      
+SELECT invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+    invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 127
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty < 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 100;
diff --git a/pgsql/fifo-testing/fifo-test-2.sql b/pgsql/fifo-testing/fifo-test-2.sql
new file mode 100644 (file)
index 0000000..ba826d8
--- /dev/null
@@ -0,0 +1,42 @@
+
+
+-- 55122 RL
+
+SELECT invfifo_update_from_invdetail(55121) ; 
+
+
+SELECT invfifo_update_from_invdetail(55122) ;
+
+
+
+    
+
+SELECT  invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+        invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 127
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 10;
+
+SELECT  invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+        invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 124
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 10;
diff --git a/pgsql/fifo-testing/fifo-test-3.sql b/pgsql/fifo-testing/fifo-test-3.sql
new file mode 100644 (file)
index 0000000..1a055ce
--- /dev/null
@@ -0,0 +1,45 @@
+
+-- this should result in a zero value before..
+--
+--SELECT invfifo_update_from_invdetail(11598);
+--
+--SELECT * from invdetailview where invdetail_id = 11598;
+--
+--
+---- test of Inventory transfer in (get's value from outvalue..)
+--SELECT invfifo_update_from_invdetail(49268);
+--
+--SELECT * from invdetailview where invdetail_id = 49268;
+--
+---- test of Inventory transfer out ( based on current stock value... to sell this..)
+--
+--SELECT invfifo_update_from_invdetail(94009);
+--
+--SELECT * from invdetailview where invdetail_id = 94009;
+--
+---- misc adju increase..
+--
+--SELECT invfifo_update_from_invdetail(11605);
+--SELECT * from invdetailview where invdetail_id = 11605;
+--
+----- transfer out..
+--
+--SELECT invfifo_update_from_invdetail(24135);
+--SELECT * from invdetailview where invdetail_id = 24135;
+--
+--
+----- transfer out..
+--
+--SELECT invfifo_update_from_invdetail(3406);
+--SELECT * from invdetailview where invdetail_id = 3406;
+--
+--
+----- transfer out..
+--
+--SELECT invfifo_update_from_invdetail(54919);
+--SELECT * from invdetailview where invdetail_id = 54919;
+
+--- adjust in
+
+SELECT invfifo_update_from_invdetail(19060);
+SELECT * from invdetailview where invdetail_id = 19060;
diff --git a/pgsql/fifo-testing/fifo-test-fill-all.sql b/pgsql/fifo-testing/fifo-test-fill-all.sql
new file mode 100644 (file)
index 0000000..0026de4
--- /dev/null
@@ -0,0 +1,17 @@
+SELECT invfifo_fill(invdetail_id) FROM (SELECT invdetail_id fROM invdetailview
+   
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+ LIMIT 10000) x;
+RAISE NOTICE '5000';
+ SELECT invfifo_fill(invdetail_id) FROM (SELECT invdetail_id fROM invdetailview
+   
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+ LIMIT 5000 OFFSET 5000) x;
+RAISE NOTICE '10000';
diff --git a/pgsql/fifo-testing/fifo-test-fill.sql b/pgsql/fifo-testing/fifo-test-fill.sql
new file mode 100644 (file)
index 0000000..a610ceb
--- /dev/null
@@ -0,0 +1,28 @@
+SELECT invfifo_fill(invdetail_id) FROM (SELECT invdetail_id fROM invdetailview
+    WHERE
+       
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+ ) x;
+SELECT  invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+        invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 124
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty < 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 100;
diff --git a/pgsql/fifo-testing/fifo-test-update.sql b/pgsql/fifo-testing/fifo-test-update.sql
new file mode 100644 (file)
index 0000000..d144154
--- /dev/null
@@ -0,0 +1,54 @@
+
+
+-- order this can be updated
+-- PO's first.
+-- adjustment in (uses previous prices..)
+
+-- RL (transfer out) -- to work out price
+-- RL (transfer in)
+
+-- testing incomming prices first.
+
+
+-- 55122 RL
+
+
+
+SELECT invfifo_update_from_invdetail(invdetail_id) FROM (SELECT invdetail_id fROM invdetailview
+    WHERE
+       
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+ ) x;
+    
+SELECT invfifo_update_from_invdetail(invdetail_id) FROM (SELECT invdetail_id fROM invdetailview
+    WHERE
+       
+        invhist_itemsite_id = 1559
+   
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+   ) x;
+    
+      
+    
+
+SELECT  invdetail_id, invfifo_qty_before, invfifo_qty_after,  invfifo_cost_before, invfifo_cost_after, invdetail_qty,
+        invhist_transtype, invhist_ordtype
+    FROM invdetailview
+    WHERE
+        invdetail_location_id = 127
+    AND
+        invhist_itemsite_id = 1559
+    AND
+        invdetail_qty > 0
+    ORDER BY
+        invhist_transdate ASC,
+        invdetail_id ASC
+    
+    LIMIT 10;
diff --git a/pgsql/fixes/apopen_distdate.sql b/pgsql/fixes/apopen_distdate.sql
new file mode 100644 (file)
index 0000000..3ae9c50
--- /dev/null
@@ -0,0 +1,35 @@
+
+update apopen set apopen_distdate =
+     
+(select
+     gltrans_date 
+        FROM
+        gltrans
+        INNER JOIN
+                        apaccnt
+                    ON
+                            apaccnt_ap_accnt_id = gltrans_accnt_id
+                        AND
+                            apaccnt_vendtype ='.*'
+        WHERE
+        apopen_journalnumber = gltrans_journalnumber
+        and
+        gltrans_docnumber = apopen_docnumber
+        )
+where apopen_id IN (
+    select apopen_id 
+            from
+            apopen
+            left join
+            gltrans
+            on
+            apopen_journalnumber = gltrans_journalnumber and gltrans_docnumber = apopen_docnumber
+            INNER JOIN
+                            apaccnt
+                        ON
+                                apaccnt_ap_accnt_id = gltrans_accnt_id
+                            AND
+                                apaccnt_vendtype ='.*'
+            
+            where gltrans_date != apopen_distdate 
+);
diff --git a/pgsql/fixes/invhist_transfer_salesrep_id.sql b/pgsql/fixes/invhist_transfer_salesrep_id.sql
new file mode 100644 (file)
index 0000000..21a4848
--- /dev/null
@@ -0,0 +1,36 @@
+UPDATE
+    invhist_transfer
+SET
+
+    invhist_transfer_salesrep_id =  
+(SELECT
+    salesrep_id
+    FROM
+        events
+        
+    LEFT JOIN
+        emp
+    ON
+        emp_number =  'p-' || person_id
+    LEFT JOIN
+        salesrep
+    ON
+        salesrep_emp_id = emp_id
+        
+    WHERE
+        events.on_table = 'invhist_transfer'
+    AND
+        events.on_id = invhist_transfer_id
+    LIMIT 1)
+WHERE
+
+    invhist_transfer_id IN (
+        SELECT distinct(on_id) FROM events WHERE
+             events.on_table = 'invhist_transfer'
+     
+    )
+    ;
+    
+
+
\ No newline at end of file
diff --git a/pgsql/fixes/x-dragon-apapply_txdate.sql b/pgsql/fixes/x-dragon-apapply_txdate.sql
new file mode 100644 (file)
index 0000000..54e4d9e
--- /dev/null
@@ -0,0 +1,92 @@
+-- DROP FUNCTION deletesoitem(integer);
+
+CREATE OR REPLACE FUNCTION apapply_txdate(text,text,integer)
+  RETURNS date AS
+$BODY$
+DECLARE
+  i_doctype    ALIAS FOR $1;
+  i_tx ALIAS FOR $2;
+  i_id ALIAS FOR $3;
+  _result       date
+
+BEGIN
+-- Get coitem
+
+    if (i_id != -1) THEN
+        SELECT apopen_docdate  INTO v_ret from apopen where apopen_id = i_id
+    END IF;
+    
+    
+    RAISE EXCEPTION 'Can be done';
+
+   
+    RETURN _result;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION apapply_txdate((text,text,integer)
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION arapply_txdate(text,text,integer,text)
+  RETURNS date AS
+$BODY$
+DECLARE
+  i_doctype    ALIAS FOR $1;
+  i_tx ALIAS FOR $2;
+  i_id ALIAS FOR $3;
+  i_ref ALIAS FOR $4;
+  v_ret       date;
+
+BEGIN
+-- Get coitem
+
+    if (i_id != -1) THEN
+        SELECT aropen_docdate  INTO v_ret from aropen where aropen_id = i_id;
+        RETURN v_ret;
+    END IF;
+    
+    if (i_doctype = 'I') THEN
+        SELECT invchead_invcdate INTO  v_ret from invchead  where invchead_number  = i_tx;
+        RETURN v_ret;
+    END IF;
+    
+    if (i_doctype = 'C') THEN
+        SELECT cmhead INTO v_ret from cmhead where cmhead_number  = i_tx;
+        RETURN v_ret;
+    END IF;
+    
+    -- arapply_source_doctype
+    if (i_doctype = 'K') THEN
+            select cashrcpt_docdate INTO v_ret from cashrcpt where cashrcpt_number =  i_tx;
+            RETURN v_ret;
+    --    SELECT invchead_invcdate v_ret from invchead  where invchead_number  = i_tx;
+     END IF;
+     
+    if (i_doctype = 'Misc.') THEN
+        select cashrcpt_docdate INTO v_ret from cashrcpt where cashrcpt_docnumber =  i_ref;
+        RETURN v_ret;
+    --    SELECT invchead_invcdate v_ret from invchead  where invchead_number  = i_tx;
+    END IF;
+     
+    RAISE EXCEPTION 'Can be done %', i_doctype;
+
+   
+    RETURN v_ret;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION arapply_txdate(text,text,integer,text)
+  OWNER TO admin;
+
+SELECT arapply_txdate(arapply_target_doctype, arapply_target_docnumber, arapply_target_aropen_id, arapply_refnumber) as src_dt FROM arapply;
+
+SELECT arapply_txdate(arapply_source_doctype, arapply_source_docnumber, arapply_source_aropen_id, arapply_refnumber) as src_dt FROM arapply;
diff --git a/pgsql/fixes/x-dragon-shipping-asset-report.sql b/pgsql/fixes/x-dragon-shipping-asset-report.sql
new file mode 100644 (file)
index 0000000..d344dc7
--- /dev/null
@@ -0,0 +1,51 @@
+
+-- not needed-- appears to be correct...
+
+
+-- shipping asset is 96.
+ create  index gltrans_notes_idx on gltrans  (gltrans_notes); 
+ create  index gltrans_docnumber_idx on gltrans  (gltrans_docnumber); 
+
+drop table gltrans_ship_totals;
+create temporary table gltrans_ship_totals AS
+
+ (SELECT
+        gltrans_docnumber,
+        
+        CASE WHEN gltrans_notes LIKE 'Recall%' OR  gltrans_notes   LIKE 'Ship Order%' THEN
+            1 ELSE 0 END as is_ship,
+        
+        COALESCE(SUM( gltrans_amount  ),0) as gltrans_amount_total
+        
+        FROM gltrans
+        WHERE
+            gltrans_accnt_id  = 96
+             AND
+                gltrans_posted
+        AND
+         
+            gltrans_source = 'S/R'
+        GROUP by
+            gltrans_docnumber,
+            is_ship
+    );
+
+CREATE INDEX ON gltrans_ship_totals(gltrans_docnumber, is_ship);
+
+-- can we add the coheads to
+alter table gltrans_ship_totals add column cohead_id INT;
+
+UPDATE gltrans_ship_totals SET cohead_id = COALESCE((
+    SELECT cohead_id from cohead where cohead_number = split_part(gltrans_docnumber, '-', 1)
+    ), 0); 
+
+UPDATE gltrans_ship_totals SET cohead_id =  COALESCE((
+    SELECT shiphead_order_id from shiphead where shiphead_number = split_part(gltrans_docnumber, '-', 1)
+ ), 0)  WHERE is_ship = 1 AND cohead_id  =0 OR cohead_id   IS NULL;
+
+
+SELECT cohead_id, sum(gltrans_amount_total) as gltrans_total FROM gltrans_ship_totals GROUP BY cohead_id;
\ No newline at end of file
diff --git a/pgsql/fixes/x-dragon-shipping-report-run.sql b/pgsql/fixes/x-dragon-shipping-report-run.sql
new file mode 100644 (file)
index 0000000..29efa55
--- /dev/null
@@ -0,0 +1,51 @@
+-- fill in the missing records...  
+select
+        x_dragon_shipping_report(coitem_id)
+    FROM
+        coitem
+    where
+        coitem_cohead_id NOT IN (SELECT distinct(xshipmess_cohead_id) FROM xshipmess)  ;
+
+
+-- find anything that was not reported.
+SELECT
+        x_dragon_shipping_report_miss(invdetail_id)
+    FROM
+        invdetailview
+    WHERE
+        invhist_ordtype = 'SO';
+          
+SELECT * 
+    FROM xshipmess
+    WHERE
+        xshipmess_qty_shipped_off + xshipmess_qty_returned_off != 0;
+        
+
+
+
+
+-- report I want to see on the UI..
+
+-- List of products shipped for that order.
+
+--- when you pick on that list, it shows you all the transactions..
+--- (eg. what's recorded (in coitem), and also what occured..')
+
+--- will also want to see the financial transactions related to it..
+
+
+
+SELECT distinct(cohead_number)  
+      FROM xshipmess
+      LEFT JOIN
+      cohead 
+      ON
+        xshipmess_cohead_id = cohead_id
+    WHERE
+        xshipmess_qty_shipped_off  != 0 
+        OR
+        xshipmess_qty_returned_off != 0;
+        
+
+
diff --git a/pgsql/fixes/x-dragon-shipping-report.sql b/pgsql/fixes/x-dragon-shipping-report.sql
new file mode 100644 (file)
index 0000000..0672ce7
--- /dev/null
@@ -0,0 +1,335 @@
+-- work out where shipments have gone astray..
+
+
+-- basically our invdetail view for a shipment qty's should match the coitem data.
+
+
+CREATE SEQUENCE xshipmess_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE xshipmess_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE xshipmess_id_seq TO admin;
+GRANT ALL ON TABLE xshipmess_id_seq TO xtrole;
+
+
+CREATE TABLE xshipmess
+(
+    xshipmess_id integer NOT NULL DEFAULT nextval(('xshipmess_id_seq'::text)::regclass),
+    xshipmess_cohead_id INTEGER,
+    xshipmess_itemsite_id INTEGER,
+    xshipmess_qty_shipped_off NUMERIC,
+    xshipmess_qty_returned_off NUMERIC,
+  
+    CONSTRAINT xshipmess_pkey PRIMARY KEY (xshipmess_id )
+    
+)
+WITH (
+  OIDS=FALSE
+);
+
+
+
+CREATE INDEX xshipmess_itemsite_id_ix  ON invadj  USING btree  (xshipmess_itemsite_id);
+CREATE INDEX xshipmess_cohead_id_ix  ON invadj  USING btree  (xshipmess_cohead_id);
+
+
+
+ALTER TABLE xshipmess
+  OWNER TO admin;
+GRANT ALL ON TABLE xshipmess TO admin;
+GRANT ALL ON TABLE xshipmess TO xtrole;
+COMMENT ON TABLE xshipmess
+  IS 'Shipment mess';
+  
+
+
+CREATE OR REPLACE FUNCTION x_dragon_shipping_report(INTEGER)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  i_coitem_id ALIAS FOR $1;
+  
+  r_coitem RECORD;
+  
+  v_id INTEGER;
+  v_qty_returned  NUMERIC;
+  v_real_returned NUMERIC;
+  v_qty_shipped NUMERIC;
+  v_real_shipped NUMERIC;
+  
+BEGIN
+
+-- first determine
+  
+    -- next apply fix to 'Ship order'
+    
+    -- find the shipment that was actually shipped..
+    select
+            *
+        INTO
+            r_coitem
+        FROM
+            coitem
+        LEFT JOIN
+            cohead
+        ON
+            cohead_id = coitem_cohead_id
+        WHERE
+            coitem_id = i_coitem_id;
+            
+    
+    -- what's the totals for this order...
+    SELECT
+            SUM(COALESCE(coitem_qtyreturned,0)), 
+            SUM(coitem_qtyshipped)  * -1
+        INTO
+            v_qty_returned,
+            v_qty_shipped
+        FROM
+            coitem
+        WHERE
+            coitem_cohead_id  = r_coitem.cohead_id
+            AND
+            coitem_itemsite_id  = r_coitem.coitem_itemsite_id;
+            
+    
+    
+    -- return shipments.
+    SELECT
+            COALESCE(SUM(invdetail_qty),0)
+        INTO
+            v_real_returned
+        FROM
+            invdetailview
+        WHERE
+            invhist_transtype = 'RS'
+        AND
+            invhist_ordtype  = 'SO'
+        AND
+            invhist_itemsite_id = r_coitem.coitem_itemsite_id
+        AND
+            invhist_ordnumber like r_coitem.cohead_number|| '-%';
+    
+    -- shipments
+    SELECT
+            COALESCE(SUM(invdetail_qty),0)
+        INTO
+            v_real_shipped
+        FROM
+            invdetailview
+        WHERE
+            invhist_transtype = 'SH'
+        AND
+            invhist_ordtype  = 'SO'
+        AND
+            invhist_itemsite_id = r_coitem.coitem_itemsite_id
+        AND
+            invhist_ordnumber like r_coitem.cohead_number || '-%';
+            
+    
+    -- update our refence table.
+    
+    SELECT
+            xshipmess_id
+        INTO
+            v_id
+        FROM
+            xshipmess
+        WHERE
+            xshipmess_cohead_id = r_coitem.cohead_id
+            AND
+            xshipmess_itemsite_id = r_coitem.coitem_itemsite_id;
+    
+    IF NOT FOUND THEN
+    
+        INSERT INTO xshipmess (
+            xshipmess_cohead_id, xshipmess_itemsite_id,
+            xshipmess_qty_shipped_off, xshipmess_qty_returned_off
+        ) VALUES (
+            r_coitem.cohead_id, r_coitem.coitem_itemsite_id,
+            v_qty_shipped - v_real_shipped , v_qty_returned- v_real_returned
+        );
+    
+    ELSE
+          -- RAISE NOTICE 'log shipment %  returned % != % , shipped % != %',
+          --r_coitem.cohead_number,
+          -- v_qty_returned ,v_real_returned, v_qty_shipped ,v_real_shipped;
+          -- 
+           
+           
+        UPDATE
+            xshipmess
+        SET
+            xshipmess_qty_shipped_off = v_qty_shipped - v_real_shipped ,
+            xshipmess_qty_returned_off = v_qty_returned- v_real_returned
+        WHERE
+            xshipmess_id = v_id;
+    END IF;
+    --        
+    --        
+    --        )
+    --IF (v_qty_returned != v_real_returned) OR (v_qty_shipped != v_real_shipped ) THEN
+    --    
+    --    RAISE NOTICE 'bad shipment %  returned % != % , shipped % != %',
+    --        r_coitem.cohead_number,
+    --        v_qty_returned ,v_real_returned, v_qty_shipped ,v_real_shipped;
+    --END IF;
+    --
+    RETURN  v_qty_shipped  - v_real_shipped;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_dragon_shipping_report(integer)
+  OWNER TO admin;
+  
+--  
+--SELECT x_dragon_shipping_report(coitem_id)
+--    FROM coitem
+--    WHERE
+--        coitem_qtyshipped !=0
+--    OR
+--        coitem_qtyreturned !=0
+--    ORDER BY
+--        coitem_id DESC
+--    ;
+
+
+
+
+--- next see if we have any shipment transactions that do not reference any coitem.
+
+
+
+CREATE OR REPLACE FUNCTION x_dragon_shipping_report_miss(INTEGER)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+    i_invdetail_id ALIAS FOR $1;
+  
+    
+    v_id INTEGER;
+    v_cohead_id  INTEGER;
+  v_itemsite_id INTEGER;
+  v_mismatch NUMERIC;
+    v_number TEXT;
+    v_cohead_number TEXT;
+  v_shipped NUMERIC;
+  v_returned NUMERIC;
+BEGIN
+      
+    SELECT
+            invhist_itemsite_id,
+            invhist_ordnumber
+        INTO
+            v_itemsite_id,
+            v_number
+        FROM
+            invdetailview
+        WHERE
+            invhist_ordtype = 'SO'
+            AND
+            invdetail_id = i_invdetail_id;
+    
+        
+    -- fetch the order..      
+    SELECT split_part(v_number, '-', 1) INTO v_cohead_number;
+    
+    SELECT
+            cohead_id
+        INTO
+            v_cohead_id
+        FROM
+            cohead
+        WHERE
+            cohead_number = v_cohead_number;
+    
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'can not find order %', v_cohead_number;
+        RETURN 0;
+    END IF;
+    
+    -- do I have a reference of it in my messs..
+    
+    SELECT
+            xshipmess_id
+        INTO
+            v_id
+        FROM
+            xshipmess
+        WHERE
+            xshipmess_cohead_id = v_cohead_id
+            AND
+            xshipmess_itemsite_id = v_itemsite_id;
+
+    IF NOT FOUND THEN
+        -- see if it was returned anyway -- so no need to bother with it..
+        
+        SELECT
+                COALESCE(SUM(invdetail_qty),0),
+                COALESCE(SUM(
+                    CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+                ),0),
+                COALESCE(SUM(
+                    CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+                ),0)
+            INTO
+                v_mismatch,
+                v_shipped,
+                v_returned
+            FROM
+                invdetailview
+            WHERE
+                invhist_ordtype = 'SO'
+                AND
+                invhist_itemsite_id  = v_itemsite_id
+                AND
+                invhist_ordnumber LIKE v_cohead_number || '-%';
+        
+        IF v_mismatch = 0.0 THEN
+            RETURN 0;
+        END IF;
+            
+        -- insert the data
+        
+        RAISE NOTICE 'can not find mess ref to  % itemsite=%', v_cohead_number, v_itemsite_id;
+        
+       
+        
+        
+        
+        INSERT INTO xshipmess (
+            xshipmess_cohead_id, xshipmess_itemsite_id,
+            xshipmess_qty_shipped_off, xshipmess_qty_returned_off
+        ) VALUES (
+            v_cohead_id, v_itemsite_id,
+            v_shipped * -1, v_returned * -1
+        );
+    
+        
+        
+        RAISE NOTICE 'can not find mess ref to  % itemsite=%', v_cohead_number, v_itemsite_id;
+    END IF;
+    RETURN 0;
+
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_dragon_shipping_report_miss(integer)
+  OWNER TO admin;
+  
+  
+
+    
diff --git a/pgsql/fixes/x-dragon-shippingasset-fix.sql b/pgsql/fixes/x-dragon-shippingasset-fix.sql
new file mode 100644 (file)
index 0000000..b2379e8
--- /dev/null
@@ -0,0 +1,511 @@
+--- this is due to bugs with the voiding of shippments.
+
+
+
+
+CREATE OR REPLACE FUNCTION x_dragon_shippingasset_fix(text)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  i_ordernumber ALIAS FOR $1;
+  v_adjust NUMERIC := 0;
+  v_reverse_total NUMERIC := 0;
+  v_invoiced_number TEXT;
+  v_dt DATE;
+    v_glsequence INTEGER;
+  v_result INTEGER;
+BEGIN
+
+-- first determine
+  
+    -- next apply fix to 'Ship order'
+    
+    -- find the shipment that was actually shipped..
+    select
+    
+        distinct(shiphead_number)
+            INTO
+            v_invoiced_number
+        from
+            shipitem
+            LEFT JOIN
+                shiphead
+            ON
+                shiphead_id = shipitem_shiphead_id
+            where
+                shiphead_number like i_ordernumber || '-%' AND shipitem_invoiced 
+        LIMIT 1;
+    
+    -- we now have the invoice that was shipped
+     IF NOT FOUND THEN
+        RAISE NOTICE 'could not find shipment that was invoiced';
+        return 0;
+    END IF;
+    
+    -- find the total transaction value that was not attributted to this one.
+    
+    SELECT
+            SUM(gltrans_amount),
+            MIN(gltrans_date)
+        INTO
+            v_reverse_total,
+            v_dt
+        FROM
+            gltrans
+        WHERE
+                gltrans_posted
+            AND
+                gltrans_accnt_id = 96
+            AND
+                (
+                    gltrans_notes like  'Ship Order%'
+                    OR
+                    gltrans_notes like  'Recall%'
+                )
+                 
+            AND
+                gltrans_docnumber != v_invoiced_number 
+            AND
+               (
+                    gltrans_docnumber like  i_ordernumber || '-%'
+                    OR
+                    gltrans_docnumber  = i_ordernumber 
+               )
+             ;
+               
+    IF NOT FOUND THEN
+        RAISE NOTICE 'could not find Ship order value';
+        return 0;
+    END IF;
+    
+    
+     IF v_reverse_total = 0.0 THEN
+        RAISE NOTICE 'total change would be 0.0';
+        return 0;
+    END IF;
+    
+    
+    
+    RAISE NOTICE 'Ship/Recal adjustment is %', v_reverse_total;
+    
+    
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        i_ordernumber, 
+                        96, -- shipping asset
+                        v_reverse_total * -1.0,
+                       v_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+    END IF;
+    
+
+
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                         i_ordernumber,  
+                        149,  -- cogs
+                         v_reverse_total  ,
+                       v_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+    END IF;
+    
+
+    UPDATE glseries
+                SET glseries_notes='Ship Order Fix due to bug in fullfillment for ' || i_ordernumber
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+
+    
+
+    RETURN 0;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION x_dragon_shippingasset_fix(text)
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION x_dragon_shippingasset_fix_lines(text)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  i_ordernumber ALIAS FOR $1;
+  v_adjust NUMERIC := 0;
+  v_reverse_total NUMERIC := 0;
+  v_invoiced_number TEXT;
+  v_dt DATE;
+    v_glsequence INTEGER;
+  v_result INTEGER;
+BEGIN
+
+-- first determine
+    SELECT
+       
+         SUM(x_dragon_shippingasset_fix_line(gltrans_docnumber)) INTO v_adjust FROM
+      
+          (SELECT distinct(gltrans_docnumber) as gltrans_docnumber
+              FROM
+                  gltrans
+                  WHERE
+                        gltrans_posted
+                        AND
+                      gltrans_accnt_id = 96
+                  AND
+                      (
+                          gltrans_notes = 'Return from Shipping'
+                          or
+                          gltrans_notes  like 'Issue%'
+                          or
+                          -- our fix
+                          gltrans_notes  like 'Fix Shipping Asset%'
+                      )
+                  AND
+                      gltrans_docnumber like  i_ordernumber || '-%'
+          ) x;
+             
+    RAISE NOTICE  'Applied issue/return adjustment of %', v_adjust;
+    RETURN v_adjust;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION x_dragon_shippingasset_fix_lines(text)
+  OWNER TO admin;
+
+    
+DROP FUNCTION x_dragon_shippingasset_fix_line(text);
+CREATE OR REPLACE FUNCTION x_dragon_shippingasset_fix_line(text)
+  RETURNS NUMERIC AS
+$BODY$
+DECLARE
+  i_docnumber ALIAS FOR $1;
+  v_correcttotal  NUMERIC ;
+  v_curtotal  NUMERIC ;
+  v_dt DATE;  
+  v_diff NUMERIC;
+  v_glsequence INTEGER;
+  v_result INTEGER;
+BEGIN
+
+    -- eg. get US10000-1
+
+-- first determine what our current value is:
+    SELECT
+            SUM(gltrans_amount)
+        INTO
+            v_curtotal
+        FROM
+            gltrans
+        WHERE
+            gltrans_posted
+            AND
+            gltrans_accnt_id = 96
+            AND
+                (
+                    gltrans_notes = 'Return from Shipping'
+                    or
+                    gltrans_notes  like 'Issue%'
+                    or
+                    -- our fix
+                    gltrans_notes  like 'Fix Shipping Asset%'
+                )
+            AND
+                gltrans_docnumber = i_docnumber;
+        
+    -- now determine what the value should have been.
+    IF (NOT FOUND) THEN
+        RAISE NOTICE 'invalid docnumber : %', i_docnumber;
+        RETURN 0;
+    END IF;
+    
+    SELECT
+            MIN(gltrans_amount),
+            MIN(gltrans_date)
+        INTO
+            v_correcttotal,
+            v_dt
+        FROM
+            
+            gltrans
+        WHERE
+             gltrans_posted
+            AND
+            gltrans_accnt_id = 96
+            AND
+            gltrans_notes  like 'Issue%'
+            AND
+            gltrans_docnumber = i_docnumber;
+             
+    -- now create a general ledger entry to fix the crap.
+    
+    -- now determine what the value should have been.
+    IF (NOT FOUND) THEN
+        RAISE NOTICE 'invalid docnumber : %', i_docnumber;
+        RETURN 0;
+    END IF;
+    
+    --RAISE NOTICE 'curr %, correct %', v_curtotal, v_correcttotal;
+    
+    
+    v_diff := v_curtotal - v_correcttotal;
+    if (v_diff = 0.0) THEN
+        RETURN 0.0;
+    END IF;
+    --RAISE NOTICE 'apply diff of %', v_diff;
+    
+     
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        i_docnumber, 
+                        96,
+                        v_diff * -1.0,
+                       v_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+    END IF;
+    
+
+
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                         i_docnumber,  
+                        148,  -- inventory asset
+                         v_diff  ,
+                       v_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+    END IF;
+    
+
+    UPDATE glseries
+                SET glseries_notes='Fix Shipping Asset Due to bug in fullfillment for ' || i_docnumber
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    return v_Diff;
+
+
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION x_dragon_shippingasset_fix_line(text)
+  OWNER TO admin;
+
+
+
+
+
+
+
+
+
+
+
+-- The final fix should be sorting out the stock balances..
+
+
+DROP FUNCTION x_dragon_shippingasset_fix_return(text);
+
+CREATE OR REPLACE FUNCTION x_dragon_shippingasset_fix_return(text)
+  RETURNS BOOLEAN AS
+$BODY$
+DECLARE
+  i_docnumber ALIAS FOR $1;
+  v_correcttotal  NUMERIC ;
+  v_curtotal  NUMERIC ;
+  v_dt DATE;  
+  v_diff NUMERIC;
+  v_itemlocseries INTEGER;
+  v_result BOOLEAN;
+BEGIN
+    
+    
+    SELECT SUM(invdetail_qty) INTO v_curtotal FROM  invdetailview where
+                invhist_ordnumber like i_docnumber || '%'
+          ;
+    
+    IF v_curtotal = 0.0 THEN
+        RAISE NOTICE 'no change - already voided';
+        RETURN false;
+    END IF;
+    
+    SELECT NEXTVAL('itemloc_series_seq')::integer into  v_itemlocseries;
+
+    PERFORM postInvTrans(
+                    invhist_itemsite_id,
+                    'RS'::text,
+                    abs(invdetail_qty)::numeric,
+                    'S/R'::text,
+                    'SO'::text,
+                    i_docnumber, --formatSoNumber({$this->shipitem_orderitem_id}),
+                    invhist_ordnumber, 
+                    'Return from Shipping'::text,
+                    149, -- cogs
+                    96, -- ship asset
+                    v_itemlocseries,
+                    invhist_transdate ,
+                    invhist_unitcost * invdetail_qty,
+                    invhist_id
+                ) 
+        FROM 
+            invdetailview where
+                invhist_ordnumber like i_docnumber || '%'
+          ;
+    
+    
+     
+    SELECT postItemlocseries(v_itemlocseries) into v_result;
+    
+    IF  NOT v_result  THEN
+        RAISE EXCEPTION 'postItemlocseries return %', v_result;
+    END IF;
+    
+    RETURN v_result;
+       
+
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION x_dragon_shippingasset_fix_return(text)
+  OWNER TO admin;
+
+SELECT x_dragon_shippingasset_fix_return('NSHK68760000083330');
+
+
+
+--SELECT x_dragon_shippingasset_fix('NS66380000084087'); << this looks ok - total tx is 0.0 over time.
+
+-- in this case
+
+
+-- fix_lines ::  Retuyn/issue totals
+-- fix  ::  Ship/Recall
+SELECT   x_dragon_shippingasset_fix('US10000') ; -- << needs stock fix..
+SELECT   x_dragon_shippingasset_fix_lines('US10000') ;
+SELECT x_dragon_shippingasset_fix('US10070')
+SELECT x_dragon_shippingasset_fix_lines('US10070')
+
+
+-- for this one it has been Issed to shipping, but the return never happened..
+
+-- the real tx is to return to shipping based on the gl trans..
+SELECT x_dragon_shippingasset_fix('HK10023');
+SELECT x_dragon_shippingasset_fix_lines('HK10023');  -- << needs stock fix
+
+SELECT x_dragon_shippingasset_fix_lines('US10141');  -- stock is ok. (check if this applies correct)
+
+
+US10141
+
+select  gltrans_notes, sum(gltrans_amount)
+        from gltrans
+            where  gltrans_accnt_id = 96 and gltrans_deleted = false and
+                gltrans_posted = true and gltrans_docnumber like 'NS66380000084087%'
+        group by gltrans_notes order sby gltrans_notes  ASC;
+
+
+
+select * from invdetailview where invhist_ordnumber like 'NS66380000084087%';
+
+
+-- specific day
+
+
+select sum(gltrans_amount)
+        from gltrans
+            where  gltrans_accnt_id = 96 and gltrans_deleted = false and
+                gltrans_posted = true and gltrans_date = '2012-08-31'  ;
+                
+select split_part(gltrans_docnumber, '-', 1), gltrans_source, sum(gltrans_amount)
+        from gltrans
+            where  gltrans_accnt_id = 96 and gltrans_deleted = false and
+                gltrans_posted = true and gltrans_date =  '2012-08-31'
+        group by split_part(gltrans_docnumber, '-', 1), gltrans_source order by abs(sum(gltrans_amount)) ASC;
+
+
+
+--- what's up
+
+select
+        gltrans_date, sum(gltrans_amount), count(gltrans_id)
+        from gltrans where
+            gltrans_accnt_id = 96 and
+            gltrans_date >= '2012-05-01'
+            and gltrans_date < '2012-12-01'
+            and gltrans_deleted = false and
+            gltrans_posted = true group by gltrans_date order by gltrans_date ASC;
+
+
+
+
diff --git a/pgsql/investigations/ar_mismatch.sql b/pgsql/investigations/ar_mismatch.sql
new file mode 100644 (file)
index 0000000..4babee9
--- /dev/null
@@ -0,0 +1,209 @@
+ar not balancing?
+
+
+-- it's probably best to do some kind of report on this.
+
+
+Day 
+    List AR transactions                      +or -ve            GL Transactions     ACCOUNT      
+
+
+
+
+-- real AR is AR - Customer Deposits
+
+
+SELECT
+    COALESCE(sum(gltrans_amount),0) FROM gltrans where 
+        
+        gltrans_accnt_id = 159 AND  gltrans_doctype = 'JE'
+        AND
+        NOT gltrans_deleted;
+    166K has been applied as adjustments.
+
+
+SELECT
+    COALESCE(sum(gltrans_amount),0) FROM gltrans where 
+        
+        gltrans_accnt_id = 296 AND  gltrans_doctype = 'JE'
+        AND
+        NOT gltrans_deleted;
+  166K has been applied as adjustments...
+  
+
+using period 
+- find out the sum of invoices in that period
+- find out the sum of gl trans in that period.
+
+
+
+SELECT 
+    period_start,
+    ROUND(gltrans_amount,2) as gltrans_amount,
+    ROUND(gltrans_cdamount,2)  as gltrans_cdamount,
+    ROUND( aropen_amount,2) as aropen_amount,
+    cashrcpt_amount,
+    ship
+    ROUND(gltrans_amount + gltrans_cdamount + aropen_amount - cashrcpt_amount,2) as ardiff
+
+    
+
+
+    FROM
+ (
+SELECT 
+    period_start,
+    (SELECT COALESCE(sum(gltrans_amount),0) FROM gltrans where 
+        gltrans_date >= period_start AND gltrans_date <= period_end
+        AND
+        gltrans_accnt_id = 159 AND  gltrans_doctype IN ('IN', 'CR', 'CM')
+        AND
+        NOT gltrans_deleted
+    ) as gltrans_amount,
+    
+    (SELECT COALESCE(sum(gltrans_amount),0) FROM gltrans where 
+        gltrans_date >= period_start AND gltrans_date <= period_end
+        AND
+        gltrans_accnt_id = 296 AND gltrans_doctype IN ('CD')
+        AND
+        NOT gltrans_deleted
+    ) as gltrans_cdamount,
+    
+    (SELECT 
+         COALESCE(sum(currtobase(aropen_curr_id, (CASE WHEN aropen_doctype = 'C' OR  aropen_doctype = 'D' THEN -1 ELSE 1 END) * aropen_amount, aropen_distdate)), 0)
+         FROM aropen
+        WHERE
+            aropen_distdate >= period_start AND aropen_distdate <= period_end
+            AND
+            aropen_doctype IN('I'  , 'C', 'D')
+    ) as aropen_amount,
+     (SELECT 
+        sum(COALESCE(currtobase(cashrcpt_curr_id, cashrcpt_amount, cashrcpt_distdate), 0)) 
+        FROM cashrcpt
+        WHERE
+            -- might be apply date..
+            cashrcpt_applydate >= period_start AND cashrcpt_applydate <= period_end
+            AND
+            NOT cashrcpt_void AND cashrcpt_posted
+    ) as cashrcpt_amount
+
+
+
+    FROM
+        period
+    ORDER BY 
+        period_start ASC 
+) x;
+
+select daterange('2012-08-01', '2012-09-01');
+ 2012-08-01   | -5651090.20 |  7085182.21 | 1434092.01
+
+select * FROM  generate_series('2012-08-01', '2012-09-01', interval '1 day')
+
+
+SELECT 
+    period_start,
+    gltrans_txnum,
+    aropen_txnum,
+    cashrcpt_txnum,
+
+    ROUND(gltrans_amount,2) as gltrans_amount,
+   ROUND(gltrans_cdamount,2)  as gltrans_cdamount,
+    ROUND( aropen_amount,2) as aropen_amount,
+    ROUND( cashrcpt_amount,2) as cashrcpt_amount,
+     ROUND(gltrans_amount + gltrans_cdamount + aropen_amount - cashrcpt_amount,2) as ardiff
+    
+
+
+
+    FROM
+ (
+SELECT 
+   generate_series::date as period_start,
+
+    (SELECT count(gltrans_id) FROM gltrans where 
+        gltrans_date = generate_series::date
+        AND
+        gltrans_accnt_id = 159 AND gltrans_doctype IN ('IN', 'CR', 'CM', 'CD')
+        AND
+        NOT gltrans_deleted
+    ) as gltrans_txnum,
+  
+    (SELECT COALESCE(sum(gltrans_amount)) FROM gltrans where 
+        gltrans_date = generate_series::date
+        AND
+        gltrans_accnt_id = 159 AND gltrans_doctype IN ('IN', 'CR', 'CM')
+        AND
+        NOT gltrans_deleted
+    ) as gltrans_amount,
+    
+    (SELECT COALESCE(sum(gltrans_amount),0) FROM gltrans where 
+         gltrans_date = generate_series::date
+        AND
+        gltrans_accnt_id = 296 AND gltrans_doctype IN ('CD')
+        AND
+        NOT gltrans_deleted
+    ) as gltrans_cdamount,
+    
+    
+    (SELECT 
+        COALESCE(sum(currtobase(cashrcpt_curr_id, cashrcptitem_amount, cashrcpt_distdate)), 0)
+        FROM
+            cashrcptitem
+        LEFT JOIN
+            cashrcpt
+        ON
+            cashrcptitem_cashrcpt_id = cashrcpt_id
+        WHERE
+            -- might be apply date..
+            cashrcpt_applydate = generate_series::date
+            AND
+            NOT cashrcpt_void AND cashrcpt_posted
+    ) as cashrcpt_amount,
+    
+    (SELECT 
+         COALESCE(sum(currtobase(aropen_curr_id, (CASE WHEN aropen_doctype = 'C' OR  aropen_doctype = 'D' THEN -1 ELSE 1 END) * aropen_amount, aropen_distdate)), 0)
+       
+        FROM aropen
+        WHERE
+            aropen_distdate =  generate_series::date
+            AND
+            aropen_doctype IN ('I'  , 'C', 'D')
+    ) as aropen_amount,
+
+   (SELECT 
+        count( aropen_id) 
+        FROM aropen
+        WHERE
+            aropen_distdate =  generate_series::date
+            AND
+            aropen_doctype IN ('I'  , 'C', 'D')
+    ) as aropen_txnum,
+    (SELECT 
+        count(cashrcpt_id) 
+        FROM cashrcpt
+        WHERE
+            -- might be apply date..
+            cashrcpt_applydate = generate_series::date
+            AND
+            NOT cashrcpt_void AND cashrcpt_posted
+    ) as cashrcpt_txnum
+    
+
+
+
+    FROM
+       generate_series('2013-01-01', '2013-02-01', interval '1 day') 
+) x;
+
+
+period_start | gltrans_txnum | aropen_txnum | cashrcpt_txnum | gltrans_amount | gltrans_cdamount | aropen_amount | cashrcpt_amount |  ardiff  
+2013-01-25   |            40 |           31 |              9 |     -134860.42 |         -5343.00 |     230792.98 |       108502.91 |  -17913.35
+
+
+
+
+
+
+
diff --git a/pgsql/investigations/shipasset_query.sql b/pgsql/investigations/shipasset_query.sql
new file mode 100644 (file)
index 0000000..0bfba33
--- /dev/null
@@ -0,0 +1,86 @@
+
+       
+CREATE OR REPLACE FUNCTION x_dragon_tests_cohead(integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_id  ALIAS FOR $1;
+   
+    v_ret NUMERIC;
+    v_cohead_number TEXT;
+    
+BEGIN
+
+    SELECT cohead_number INTO v_cohead_number FROM cohead WHERE cohead_id = i_cohead_id;
+
+    SELECT count(invhist_itemsite_id) into v_ret
+      FROM
+     (
+    
+            SELECT 
+                invhist_itemsite_id,
+                join_item.item_number as item_number,
+                
+                    COALESCE ((SELECT SUM(COALESCE(coitem_qtyreturned,0)) FROM coitem WHERE coitem_cohead_id = i_cohead_id and coitem_itemsite_id = invhist_itemsite_id
+                ) ,0)  +
+                
+                (COALESCE ((SELECT SUM(coitem_qtyshipped) FROM coitem WHERE coitem_cohead_id = i_cohead_id and coitem_itemsite_id = invhist_itemsite_id
+                ), 0)  * -1 )  as rec_total,
+                
+                
+                COALESCE(SUM(
+    CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+    ),0) as tx_shipped,
+    
+    COALESCE(SUM(
+    CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+    ),0) as tx_returned,
+    
+                COALESCE(SUM(invdetail_qty),0) as tx_total 
+                
+                
+                
+                
+                FROM invdetail 
+            
+                LEFT JOIN invhist AS join_invhist ON
+                    invdetail.invdetail_invhist_id = join_invhist.invhist_id
+                LEFT JOIN invfifo AS join_invfifo ON
+                    invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id
+                LEFT JOIN itemsite AS join_itemsite ON
+                    join_invhist.invhist_itemsite_id = join_itemsite.itemsite_id
+                LEFT JOIN item AS join_item ON
+                    join_itemsite.itemsite_item_id = join_item.item_id 
+                WHERE ( 
+                    invhist_ordtype = 'SO'
+                    AND 
+                    (
+                        invhist_ordnumber LIKE v_cohead_number || '-%'
+                        OR
+                        invhist_ordnumber = v_cohead_number
+                    )
+                ) 
+                GROUP BY invhist_itemsite_id, join_item.item_number 
+            
+                ORDER BY join_item.item_number ASC
+                
+     ) x
+     WHERE
+        tx_total != rec_total;
+    
+    return v_ret;
+                           
+        RETURN v_ret;        
+     END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_dragon_tests_cohead(integer)
+  OWNER TO admin;
+  
+  
+SELECT cohead_number,  x_dragon_tests_cohead(cohead_id)  from cohead;
\ No newline at end of file
diff --git a/pgsql/investigations/stock_imbalances.txt b/pgsql/investigations/stock_imbalances.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pgsql/migration/expense-migrate.sql b/pgsql/migration/expense-migrate.sql
new file mode 100644 (file)
index 0000000..4af1e41
--- /dev/null
@@ -0,0 +1,151 @@
+--needs the sql files in download..
+
+
+INSERT INTO expcat (
+    
+expcat_code,
+expcat_descrip,
+expcat_exp_accnt_id,
+expcat_liability_accnt_id,
+expcat_active,              
+expcat_purchprice_accnt_id ,
+expcat_freight_accnt_id
+)
+SELECT 
+    accnt_descrip,
+    accnt_descrip,
+    accnt_id,
+    95,
+    true,
+    126,
+    98
+FROM
+    accnt
+
+    WHERE accnt_id = 198
+    AND
+    (SELECT count(expcat_id) FROM expcat where expcat_exp_accnt_id = 198) = 0;
+
+
+
+INSERT INTO expense (
+  --  expense_id  
+    
+    
+    expense_accnt_id ,
+    expense_emp_id ,
+    
+    expense_number ,
+    
+    expense_trandate ,
+    expense_created ,
+    expense_modified,
+    expense_duedate ,
+    
+    expense_memo  ,
+    
+    expense_status ,
+    
+    expense_advance ,
+    expense_amount ,
+    
+    expense_tax ,
+    expense_total  
+)
+
+
+SELECT
+    accnt_id,
+    emp_id,
+    'EXP-' || tranid,
+    trandate,
+    createddate,
+    lastmodifieddate,
+    duedate,
+    memo,
+    status,
+    advance,
+    amount,
+    tax1amt,
+    total
+    FROM
+    netsuite_expensereport
+    LEFT JOIN
+        netsuite_user ON netsuite_user.id = entity
+    LEFT JOIN
+        emp ON emp_name = netsuite_user.name
+    LEFT JOIN
+        accnt ON accnt_id = account
+        
+    WHERE
+        emp_id IS NOT NULL
+        AND
+        -- HK only..
+        netsuite_expensereport.id IN (SELECT expensereport_id FROM  netsuite_expensereportexpense where department = 1);
+
+
+
+
+
+INSERT INTO expitem
+(
+  
+  
+  expitem_expense_id  ,
+  expitem_curr_id  ,
+  expitem_expcat_id  ,
+
+  expitem_row  ,
+  
+  
+  expitem_amount ,
+  expitem_amount_fc,
+  expitem_tax  ,
+  expitem_total  ,
+  --grossAmt decimal(12,3) DEFAULT '0.000',
+  -- expense cat?
+  
+  expitem_date  ,
+  --exchangeRate decimal(12,5) DEFAULT NULL,
+  
+  
+  expitem_is_billable  ,
+  
+  expitem_memo
+)
+SELECT
+    expense_id,
+    basecurrid(),
+    expcat_id,
+    
+    line,
+    
+    netsuite_expensereportexpense.amount,
+    -- we are ignoring forigne currency.. and just using our local one..
+    netsuite_expensereportexpense.amount,
+    netsuite_expensereportexpense.tax1amt,
+    grossamt,
+    
+    expensedate,
+    isbillable,
+    netsuite_expensereportexpense.memo
+    
+    FROM
+        netsuite_expensereportexpense
+    LEFT JOIN
+        netsuite_expensereport ON  netsuite_expensereport.id  = netsuite_expensereportexpense.expensereport_id
+    LEFT JOIN
+        expense ON 'EXP-' || netsuite_expensereport.tranid = expense_number 
+    LEFT JOIN
+        netsuite_expensecategory ON   category = netsuite_expensecategory.id
+    LEFT JOIN
+        accnt ON accnt_number  = netsuite_expensecategory.expenseacct || ''
+    LEFT JOIN
+        expcat ON expcat_exp_accnt_id = accnt_id
+    WHERE
+        netsuite_expensereportexpense.department = 1
+        AND
+        expense_id IS NOT NULL;
\ No newline at end of file
diff --git a/pgsql/migration/x-dragon-bankrec.sql b/pgsql/migration/x-dragon-bankrec.sql
new file mode 100644 (file)
index 0000000..205bdbd
--- /dev/null
@@ -0,0 +1,276 @@
+
+-- remove the misc. bank account.
+-- update cashrcpt set  cashrcpt_bankaccnt_id = 13 where cashrcpt_id = 607;
+-- update cashrcpt set  cashrcpt_bankaccnt_id = 13 where cashrcpt_bankaccnt_id = 25;
+-- delete from bankaccnt where bankaccnt_id = 24;
+-- delete from bankaccnt where bankaccnt_id = 25;
+
+
+
+-- failing on accnt id = 178 (alot) 180=(tiny)
+-- 212 (small)
+
+-- UPDATE bankrec set bankrec_posted = false; DELETE from bankrecitem; DELETE FROM bankrec;
+-- SELECT * from bankrec;
+--SELECT dragon_bankrecfill( '2011-09-30');
+
+
+--SELECT dragon_bankrecfill_accnt( 296, '2011-09-30');
+
+--SELECT dragon_bankrecfill_accnt( 212, '2011-09-30');
+--SELECT dragon_bankrecfill_accnt( 178, '2011-09-30'); -- c/a bloom?
+
+CREATE OR REPLACE FUNCTION dragon_bankrecfill(date)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  i_date ALIAS FOR $1;
+  
+
+BEGIN
+    -- fix the broken sequence...
+
+    PERFORM setval('bankrec_bankrec_id_seq', (SELECT MAX(bankrec_id) FROM bankrec));
+
+   -- UPDATE bankaccnt SET bankaccnt_curr_id = (SELECT accnt_curr_id FROM accnt WHERE accnt_id = bankaccnt_accnt_id);
+    PERFORM dragon_bankrecfill_accnt(bankaccnt_accnt_id, i_date) FROM
+        bankaccnt ;
+         
+
+  RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION dragon_bankrecfill(date)
+  OWNER TO admin;
+  
+  
+-------- this function should be useless coz we have change the bankrec working flow..  
+
+CREATE OR REPLACE FUNCTION dragon_bankrecfill_accnt(integer, date)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  i_accnt_id ALIAS FOR $1;
+  i_date ALIAS FOR $2;
+  
+  v_bank_id INTEGER;
+  v_id INTEGER;
+  v_lastdate DATE;
+   v_curr_id INTEGER;
+  v_currbase_id INTEGER;
+  v_balance NUMERIC;
+  
+
+BEGIN
+    -- find the last posted
+    SELECT
+            bankaccnt_id,
+            bankaccnt_curr_id,
+            basecurrid()
+        INTO
+            v_bank_id,
+            v_curr_id,
+            v_currbase_id
+        FROM
+            bankaccnt
+        WHERE
+            bankaccnt_accnt_id = i_accnt_id;
+            
+        
+    IF (NOT FOUND) THEN
+        RAISE NOTICE 'BAnk not found accnt_id = %', i_accnt_id;
+        RETURN false;
+    END IF;
+    
+    
+    -- find the last date.
+    
+    SELECT
+            bankrec_id, bankrec_enddate
+        INTO
+            v_id, v_lastdate
+        FROM
+            bankrec
+        WHERE
+            bankrec_bankaccnt_id = v_bank_id
+        AND
+            bankrec_posted = true
+        ORDER BY
+            bankrec_enddate DESC;
+            
+            
+            
+    IF (NOT FOUND) THEN
+        v_lastdate := '2006-01-01';
+    ELSE
+    
+        IF (v_lastdate >= i_date) THEN
+            RAISE NOTICE 'account % has already been posted for %', i_accnt_id, v_lastdate;
+            RETURN false;
+        END IF;
+    
+        SELECT v_lastdate + INTERVAL '1 DAY' INTO v_lastdate ;
+    END IF;
+    
+    -- see if there is a current unposted
+    
+    
+     SELECT
+            bankrec_id 
+        INTO
+            v_id
+        FROM
+            bankrec
+        WHERE
+            bankrec_bankaccnt_id = v_bank_id
+        AND
+            bankrec_posted = false
+        ORDER BY
+            bankrec_enddate ASC;
+            
+      
+              
+    IF (NOT FOUND) THEN
+        INSERT INTO  bankrec (
+            bankrec_created       , bankrec_username ,
+            bankrec_bankaccnt_id , bankrec_opendate ,
+            
+            bankrec_enddate , bankrec_openbal ,
+            bankrec_endbal , bankrec_posted ,
+            
+            bankrec_postdate 
+        ) VALUES (
+            NOW(), 'admin',
+            v_bank_id, v_lastdate,
+            
+            i_date, 0.0,
+            0.0, false, null
+        );
+        
+        
+        SELECT
+            bankrec_id 
+        INTO
+            v_id
+        FROM
+            bankrec
+        WHERE
+            bankrec_bankaccnt_id = v_bank_id
+        AND
+            bankrec_posted = false
+        ORDER BY
+            bankrec_enddate ASC;
+            
+        
+        
+        
+    ELSE
+        UPDATE bankrec SET
+            
+            bankrec_opendate = v_lastdate,
+            
+            bankrec_enddate = i_date,
+            bankrec_openbal = 0.0,
+            bankrec_endbal = 0.0
+        WHERE
+            bankrec_id = v_id;
+            
+    
+    
+    END IF;
+    
+    
+    -- we now have the v_id being the bankrec id..
+    -- let's trash all the bankrecitems that relate to it.
+    DELETE FROM bankrecitem WHERE bankrecitem_bankrec_id = v_id;
+    
+    -- fill it in with all the transactions from gltrans.
+    RAISE NOTICE 'doing bank %', v_bank_id;
+    PERFORM
+            setbankreccleared(v_id, 'GL', gltrans_id, true)
+        FROM
+            gltrans
+        WHERE
+            gltrans_accnt_id = i_accnt_id
+        AND
+            gltrans_date <= i_date
+        AND
+            gltrans_posted = true
+        AND
+            gltrans_deleted = false;
+    
+    -- database should now be clean...
+
+    SELECT
+            COALESCE(SUM(bankrecitem_curr_rate * gltrans_amount)  * -1.0,0)
+            INTO
+                v_balance
+            FROM
+               bankrecitem
+            LEFT JOIN
+               gltrans
+            ON
+               bankrecitem_source_id = gltrans_id
+            AND
+               bankrecitem_source = 'GL'
+            WHERE
+              bankrecitem_bankrec_id = v_id;
+    
+    SELECT COALESCE(v_balance, 0) INTO v_balance;
+    
+    RAISE NOTICE 'got balance of %', v_balance;
+    
+    IF FOUND AND v_balance IS NOT NULL THEN 
+    
+        UPDATE bankrec SET
+            bankrec_endbal =  v_balance
+        WHERE
+            bankrec_id = v_id;
+    
+    -- fails on these
+    END IF;
+    
+     
+     
+    
+    RAISE NOTICE ' checking if base currency: % ?= %', v_curr_id , v_currbase_id;
+    IF (v_curr_id = v_currbase_id) THEN
+        PERFORM postBankReconciliation(v_id);
+    END IF;
+
+    
+  RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  dragon_bankrecfill_accnt(integer, date)
+  OWNER TO admin;
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
\ No newline at end of file
diff --git a/pgsql/migration/x-fifo-remove-eoy.sql b/pgsql/migration/x-fifo-remove-eoy.sql
new file mode 100644 (file)
index 0000000..f8fae36
--- /dev/null
@@ -0,0 +1,133 @@
+
+
+
+-- first remove all the 'new ones..'
+ --5500         | Currency Gain Loss            |       -0.010
+ --206          | Inventory Adjustments (HK HQ) |   638069.450
+ --121          | Cost of Goods Sold            |  4218962.960
+ --53           | Opening Balance               |  -220484.470
+ --1260         | Shipping Asset                |  1476822.370
+ --120          | Inventory Asset               | -6113370.300
+--SELECT deleteGlSeries(seq_id,  'Revereted after FIFO on ' || to_char(NOW(), 'Day Mon DD YYY') ) FROM (
+--    SELECT
+--            distinct(gltrans_sequence) as seq_id
+--        FROM
+--            gltrans
+--        WHERE
+--            gltrans_docnumber LIKE 'NS-EOYJEFIX-%'
+--        AND
+--            gltrans_date >= (
+--                    SELECT period_start  FROM period
+--                    WHERE NOT period_closed AND NOT period_freeze ORDER BY period_start ASC LIMIT 1
+--            )
+--        AND
+--            gltrans_accnt_id IN (SELECT accnt_id FROM accnt where accnt_number::integer IN (206,121,53,1260,120))
+--        AND
+--            NOT gltrans_deleted
+--    ) x;
+
+CREATE OR REPLACE FUNCTION xfifo_fix_remove_old_gl()
+    RETURNS  boolean
+
+AS $BODY$
+    DECLARE
+    v_glsequence INTEGER;
+    v_result integer;
+    v_date DATE;
+BEGIN
+    SELECT fetchGLSequence() INTO v_glsequence;
+    SELECT period_start  INTO v_date
+            FROM period
+            WHERE NOT period_closed AND NOT period_freeze ORDER BY period_start ASC LIMIT 1;
+   
+    SELECT SUM(CASE WHEN res < 1 THEN res - 1 ELSE 0 END) INTO v_result FROM
+        (
+
+      SELECT insertIntoGLSeries(
+                                    v_glsequence,
+                                    'G/L',
+                                    'JE',
+                                    'NS-REOYJEFIX' || , 
+                                    accnt_id, -- adjustment account
+                                    adjust,
+                                   v_date ) as res
+                FROM (
+                
+                 SELECT
+                            gltrans_accnt_id as accnt_id, sum(gltrans_amount) * -1 as adjust
+                        FROM
+                            gltrans
+                        WHERE
+                            gltrans_docnumber LIKE 'NS-EOYJEFIX-%'
+                        AND
+                            gltrans_date < v_date
+                        AND
+                            gltrans_accnt_id IN (SELECT accnt_id FROM accnt where accnt_number::integer IN (206,121,53,1260,120))
+                        AND
+                            NOT gltrans_deleted GROUP BY gltrans_accnt_id 
+                 ) x
+        ) y;
+                 
+                 
+    if (v_result < 0) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries all failed';
+    END IF;
+    
+ -- apply the differed sum to                 
+             SELECT insertIntoGLSeries(
+                                    v_glsequence,
+                                    'G/L',
+                                    'JE',
+                                    'NS-REOYJEFIX-' || (
+                                                SELECT period_start  FROM period
+                                                WHERE NOT period_closed AND NOT period_freeze ORDER BY period_start ASC LIMIT 1
+                                        ), 
+                                    fetchMetricValue('CurrencyGainLossAccount')::integer, 
+                                    adjust,
+                                    v_date) into v_result
+                                        
+                                        
+                                        FROM ( 
+                                   
+                                    SELECT
+                                                sum(gltrans_amount) * -1 as adjust
+                                           FROM
+                                               gltrans
+                                           WHERE
+                                               gltrans_docnumber LIKE 'NS-EOYJEFIX-%'
+                                           AND
+                                               gltrans_date < v_date
+                                           AND
+                                               gltrans_accnt_id IN (SELECT accnt_id FROM accnt where accnt_number::integer IN (206,121,53,1260,120))
+                                           AND
+                                               NOT gltrans_deleted  
+                                    ) x
+                 ; 
+             
+    if (v_result < 0) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries adj  failed';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='reverse old adjustment applications'
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+    --RAISE NOTICE 'postGLSeriesNoSumm(%,COALESCE(NULL,fetchJournalNumber(''G/L''))) ', v_glsequence;
+    
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed %', v_result;
+    END IF;
+    RETURN true;
+    END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;  
+        
+SELECT xfifo_fix_remove_old_gl();
+        
+        
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-createitemsrc.sql b/pgsql/migration/x-netsuite-createitemsrc.sql
new file mode 100644 (file)
index 0000000..9886ce4
--- /dev/null
@@ -0,0 +1,112 @@
+
+INSERT INTO
+        itemsrc
+    (
+        itemsrc_item_id   ,
+        itemsrc_vend_id    ,
+        itemsrc_vend_item_number   ,
+        itemsrc_vend_item_descrip ,
+        
+        itemsrc_vend_uom      ,      
+        itemsrc_invvendoruomratio   ,
+        itemsrc_minordqty           ,
+        itemsrc_multordqty          ,
+                                    
+        itemsrc_leadtime            ,
+        itemsrc_ranking             ,
+        itemsrc_active              ,
+        itemsrc_default             
+    )     
+SELECT
+    DISTINCT(itemsite_item_id) as itemsite_item_id,
+    highbuy(itemsite_id),
+    item_number,
+    item_descrip1,
+    
+    'EA',
+    1.0000000000,
+    0.000000,
+    0.000000,
+    
+    9,
+    1,
+    true,
+    true
+    
+    FROM
+        poitem
+    LEFT JOIN
+        itemsite
+    ON
+        poitem_itemsite_id = itemsite_id
+    LEFT JOIN
+        item
+    ON
+        itemsite_item_id = item_id
+    LEFT JOIN
+        pohead
+    ON
+        pohead_id = poitem_pohead_id
+    WHERE
+       COALESCE(
+            (SELECT
+                    count(itemsrc_id)
+                FROM
+                    itemsrc
+                WHERE
+                    itemsrc_item_id = itemsite_item_id
+                    AND
+                    itemsrc_vend_id = highbuy(itemsite_id)
+            ), 0
+        ) < 1
+        
+        AND
+        item_type = 'P'
+        AND
+        highbuy(itemsite_id) > 0
+        
+        AND 1= 0
+          
+    GROUP BY
+       itemsite_id, itemsite_item_id, pohead_vend_id, item_number,item_descrip1;
+        
+        
+        
+         
+CREATE OR REPLACE FUNCTION highbuy(integer )
+  RETURNS integer AS
+$BODY$
+DECLARE
+   i_itemsite_id ALIAS FOR $1;
+   v_ret INTEGER;
+BEGIN
+    v_ret = 0;
+    SELECT
+                    pohead_vend_id
+                INTO
+                    v_ret
+                FROM
+                    poitem 
+                LEFT JOIN
+                    pohead 
+                ON
+                    pohead_id = poitem_pohead_id
+                WHERE
+                    poitem_itemsite_id = i_itemsite_id
+                GROUP BY
+                    pohead_vend_id                     
+                ORDER BY
+                    count(poitem_qty_received) DESC
+             
+                LIMIT 1;
+        IF NOT FOUND THEN
+            RETURN 0;
+        END IF;
+        RETURN v_ret;
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;  
+   
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-discounttaxfix.sql b/pgsql/migration/x-netsuite-discounttaxfix.sql
new file mode 100644 (file)
index 0000000..dd1b03a
--- /dev/null
@@ -0,0 +1,49 @@
+
+
+-- aim to find the invoices that have had tax applied before discount, when it should have been after.
+
+-- need to see
+-- total discount
+-- total tax.
+
+select * from Netsuite_Invoice where department  =1 AND tranId = 'Invoice #2053';
+
+-- our system said tax was subtotal * 0.07
+
+
+taxTotal: 16.410
+discountTotal: -16.290
+subTotal: 250.660
+total: 250.780
+
+So look for
+
+     
+    subTotal * 0.07 != taxTotal;
+select id, tranId, subTotal,  taxTotal,  discountTotal, total
+     from Netsuite_Invoice
+     where
+        department  =1
+      
+        AND
+            taxTotal != 0.0
+        AND
+            discountTotal != 0.0
+        LIMIT 10;
+
+select count(id)
+     from Netsuite_Invoice
+     where
+        department  =1
+      
+        AND
+            taxTotal != 0.0
+        AND
+            discountTotal != 0.0
+        AND
+            tranDate > '2011-08-01';
+
+-- we are talking about 306 lines. where date > 2011-08-01..
+
+       
+SELECT amount, grossAmt, tax1Amt FROM Netsuite_InvoiceItem where Invoice_id = 16139;
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix-based.sql b/pgsql/migration/x-netsuite-eoy-fix-based.sql
new file mode 100644 (file)
index 0000000..4c67389
--- /dev/null
@@ -0,0 +1,388 @@
+-- closing account at end of year.
+
+-- SELECT netsuite_eoyfix( '2010-08-31, accnt_id, 1000.0, 'SG');
+
+
+
+-- final eoy figures
+-- ASSETS 'A' / LIABILITIES 'L'  & 'Q' EQUEITY = based on totals, not EOY
+
+
+
+CREATE OR REPLACE FUNCTION netsuite_eoyfix_based( date , int , text, int)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  i_dt ALIAS FOR $1;
+  i_accnt_id ALIAS FOR $2;
+  i_dep ALIAS FOR $3;
+  v_fact ALIAS FOR $4;
+  v_curr_basename TEXT;
+  
+  
+  v_nsamount DECIMAL (18,3);
+  v_acctype  TEXT;
+  v_acctype_top TEXT;
+  
+  v_gainloss_id  INTEGER;
+  v_oldseries INTEGER;
+  v_transdate DATE;
+  v_amount DECIMAL (18,3);
+  v_ap_amount DECIMAL (18,3);
+  v_change DECIMAL (18,3);
+
+
+  v_docnumber TEXT;
+  v_glsequence INTEGER;
+  v_result INTEGER;
+  v_resultbool BOOLEAN;
+  
+  v_r RECORD;
+  
+BEGIN
+
+
+    -- verify it's being applied to right database.
+    SELECT curr_name INTO v_curr_basename From curr_symbol where  curr_base = true;
+    
+    IF i_dep = 'SG' THEN
+        IF  v_curr_basename != 'SGD' THEN
+            RAISE EXCEPTION 'base is not sgd.';
+        END IF;
+    ELSE
+        IF i_dep = 'HK' THEN
+            IF v_curr_basename != 'HKD' THEN
+                RAISE EXCEPTION 'base is not HKD.';
+            END IF;
+        ELSE
+            RAISE EXCEPTION 'invalid department.';
+        END IF;
+    END IF;
+
+    
+    
+    SELECT
+        accnt_subaccnttype_code,
+        accnt_type
+        INTO
+        v_acctype,
+        v_acctype_top
+        
+        FROM
+        accnt
+        WHERE
+        accnt_id = i_accnt_id;
+        
+        
+    if v_acctype = 'A' THEN
+        v_fact = -1.0;
+    END IF;
+
+    -- what is the eoy balance in netsuite;
+    SELECT
+            CASE WHEN v_acctype_top  IN ('L', 'R', 'Q') THEN  
+            ROUND(
+                COALESCE(base_close  * v_fact * -1, 0.0)
+                ,2)
+            ELSE 
+            ROUND(
+                COALESCE(base_close  * v_fact , 0.0)
+                ,2)
+            END
+        INTO
+            v_nsamount
+        FROM
+            netsuite_balance
+        LEFT JOIN
+            period
+        ON
+            netsuite_balance.period_id = period.period_id
+            
+        WHERE
+            period_end = i_dt
+            AND
+            accnt_id = i_accnt_id
+        LIMIT 1;
+    
+     
+     
+    
+    IF NOT FOUND THEN
+        --RAISE NOTICE 'NO DATE netsuite_balance found for % %', i_dt , (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id);
+        v_nsamount := 0.0;
+        
+        
+        --RETURN 0;
+    END IF;
+    
+    
+     SELECT accnt_id INTO v_gainloss_id FROM accnt where accnt_number = '5500';
+    -- pos or neg???
+    -- skip  curr gain loss account..
+    IF v_gainloss_id  = i_accnt_id THEN
+        RETURN 0;
+    END IF;
+    
+    -- this follows a few rules:
+    -- Is the account based on the EOY value, or the total value..
+    -- A= Assets / L=Liabilities / Q=EQUITY = total all time..
+    -- E= Expesnses R=Revenue = EOY
+    
+    
+    SELECT
+    
+        CASE WHEN accnt_type IN ('E','R','Q') THEN
+            -- EOY
+            (SELECT ROUND(COALESCE (trialbal_ending    , 0.0),2)  
+                FROM
+                    trialbal
+                LEFT JOIN
+                    period
+                ON
+                    period_id = trialbal_period_id
+                WHERE
+                    trialbal_accnt_id=accnt_id
+                    AND
+                    period_end = i_dt
+            )
+            
+        ELSE
+            -- All time.
+            (SELECT 
+                ROUND(COALESCE(       SUM(trialbal_ending -  trialbal_beginning)  * v_fact * -1.0, 0.0),2)
+                
+                FROM
+                    trialbal
+                LEFT JOIN
+                    period
+                ON
+                    period_id = trialbal_period_id
+                WHERE
+                    trialbal_accnt_id=accnt_id
+                    AND
+                    period_start <= i_dt
+            )
+        END AS amount
+        
+        INTO 
+           v_amount
+           
+        FROM
+            accnt
+        WHERE
+              accnt_id=i_accnt_id
+             ;
+     
+    
+     
+    
+    
+    IF NOT FOUND THEN
+        v_amount := 0.0;
+    END IF;
+    
+    v_change := v_amount - v_nsamount;
+    
+    
+     
+    
+    
+     -- already fixed..
+      IF (v_change = 0.00) THEN
+        RAISE NOTICE '(FIXED) % NETSUITE EOY : ID(%) %,     NS: %  DR: %                   DIFF: %  ',
+            i_dt,
+            i_accnt_id,
+          (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id),
+            v_nsamount,
+            v_amount,
+            v_change;
+        RETURN 0;
+    END IF;
+    
+    
+       -- have we done the fix.
+
+    
+    SELECT
+            gltrans_sequence
+        INTO
+            v_result
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text
+            AND
+            gltrans_deleted = false
+        LIMIT 1 ;
+        
+    IF FOUND THEN
+        --RAISE NOTICE 'Already processed';
+        --RETURN 0;
+        SELECT deleteGlSeries(v_result ,  'Journal edited by alan on ' || to_char(NOW(), 'Day Mon DD YYY') ) INTO v_resultbool;
+    
+    END IF;
+            
+    
+    
+    
+    -- what is our gl balance...
+    SELECT 
+        CASE WHEN accnt_type IN ('E','R', 'Q') THEN
+            -- EOY
+            (SELECT ROUND(COALESCE (trialbal_ending  , 0.0),2)  
+                FROM
+                    trialbal
+                LEFT JOIN
+                    period
+                ON
+                    period_id = trialbal_period_id
+                WHERE
+                    trialbal_accnt_id=accnt_id
+                    AND
+                    period_end = i_dt
+            )
+            
+        ELSE
+            -- All time.
+            (SELECT 
+                ROUND(COALESCE(       SUM(trialbal_ending -  trialbal_beginning)  * v_fact * -1.0, 0.0),2)
+                
+                FROM
+                    trialbal
+                LEFT JOIN
+                    period
+                ON
+                    period_id = trialbal_period_id
+                WHERE
+                    trialbal_accnt_id=accnt_id
+                    AND
+                    period_start <= i_dt
+            )
+        END AS amount
+        
+        INTO 
+           v_amount
+           
+        FROM
+            accnt
+        WHERE
+              accnt_id=i_accnt_id
+             ;
+     
+     
+     
+    
+    IF NOT FOUND THEN
+        v_amount := 0.0;
+    END IF;
+    
+    v_change := v_amount - v_nsamount;
+    
+    
+
+    RAISE NOTICE 'NETSUITE EOY : %    NS: %  DR: %                   DIFF: %  ',
+        (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id),
+            v_nsamount,
+            v_amount,
+            v_change;
+    
+    --RETURN 0;
+    IF (v_change = 0.00) THEN
+        RETURN 0;
+    END IF;
+    
+
+  
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text,
+                        (SELECT accnt_id FROM accnt where accnt_number = '5500'),
+                        v_change  * v_fact * -1.0,
+                       i_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries  failed';
+    END IF;
+    
+
+
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text,
+                        i_accnt_id,
+                        v_change * v_fact ,
+                       i_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries  failed';
+    END IF;
+    
+    
+    
+    
+
+    
+    --  Prepaid Account - Purchasing  (100) + 63  + (63 - 70)
+     
+    -- Currency Gain Loss (122) - 126
+    
+    -- validate it...
+     SELECT
+            sum(glseries_amount)
+        INTO
+            v_change
+        FROM
+            glseries
+        WHERE
+            glseries_sequence = v_glsequence;
+            
+            
+    RAISE NOTICE 'apply Change % ', v_change;
+    
+    if (v_change != 0.0) THEN
+        
+    
+        RAISE EXCEPTION 'change is not valid';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fix import end of year ' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+     
+    
+     
+    RETURN v_result;
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
diff --git a/pgsql/migration/x-netsuite-eoy-fix-based2011.sql b/pgsql/migration/x-netsuite-eoy-fix-based2011.sql
new file mode 100644 (file)
index 0000000..f90940d
--- /dev/null
@@ -0,0 +1,38 @@
+
+----
+
+
+---- includes reatined earnings...
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+
+
+
+--
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP' ORDER BY accnt_descrip ASC;
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXPV' ORDER BY accnt_descrip ASC;
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', 1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'IN';
+
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+--
+-- any CAS..
+-- Paypal USD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '416';
+--- HKD transfer
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+-- c/a joanna bush
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '285';
+--DBS current
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '283';
+-- DBS USD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '288';
+
+
+--paypal SGD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '415';
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix.sql b/pgsql/migration/x-netsuite-eoy-fix.sql
new file mode 100644 (file)
index 0000000..672b0db
--- /dev/null
@@ -0,0 +1,349 @@
+-- closing account at end of year.
+
+-- SELECT netsuite_eoyfix( '2010-08-31, accnt_id, 1000.0, 'SG');
+
+
+CREATE OR REPLACE FUNCTION netsuite_eoyfix( date , int , text, int)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  i_dt ALIAS FOR $1;
+  i_accnt_id ALIAS FOR $2;
+  i_dep ALIAS FOR $3;
+  i_fact ALIAS FOR $4; -- ignored..
+  v_curr_basename TEXT;
+  
+  v_fact INTEGER;
+  v_nsamount DECIMAL (18,3);
+  v_acctype  TEXT;
+  v_acctype_top  TEXT;
+  
+  v_gainloss_id  INTEGER;
+  v_oldseries INTEGER;
+  v_transdate DATE;
+  v_amount DECIMAL (18,3);
+  v_ap_amount DECIMAL (18,3);
+  v_change DECIMAL (18,3);
+
+
+  v_docnumber TEXT;
+  v_glsequence INTEGER;
+  v_result INTEGER;
+  v_resultbool BOOLEAN;
+  
+  v_r RECORD;
+  
+BEGIN
+
+
+    v_fact :=    1;
+
+
+    -- verify it's being applied to right database.
+    SELECT curr_name INTO v_curr_basename From curr_symbol where  curr_base = true;
+    
+    IF i_dep = 'SG' THEN
+        IF  v_curr_basename != 'SGD' THEN
+            RAISE EXCEPTION 'base is not sgd.';
+        END IF;
+    ELSE
+        IF i_dep = 'HK' THEN
+            IF v_curr_basename != 'HKD' THEN
+                RAISE EXCEPTION 'base is not HKD.';
+            END IF;
+        ELSE
+            RAISE EXCEPTION 'invalid department.';
+        END IF;
+    END IF;
+
+    
+    
+    SELECT
+        accnt_subaccnttype_code,
+        accnt_type
+        INTO
+        v_acctype,
+        v_acctype_top
+        FROM
+        accnt
+        WHERE
+        accnt_id = i_accnt_id;
+        
+        
+    if (v_acctype_top = 'A') THEN
+        v_fact :=   -1;
+    END IF;
+
+    -- what is the eoy balance in netsuite;
+    SELECT
+            COALESCE( ROUND(
+                CASE WHEN v_acctype  = 'CA' THEN
+                currtobase(getcurrid('HKD'), hkd_ending, i_dt)
+                ELSE
+                base_ending -- currtobase(getcurrid('HKD'), hkd_ending, i_dt)
+                END
+                ,2) ,0)
+        INTO
+            v_nsamount
+        FROM
+            netsuite_balance
+        LEFT JOIN
+            period
+        ON
+            netsuite_balance.period_id = period.period_id
+        WHERE
+            period_end = i_dt
+            AND
+            accnt_id = i_accnt_id
+        LIMIT 1;
+    
+     
+     
+    
+    IF NOT FOUND THEN
+        --RAISE NOTICE 'NO DATE netsuite_balance found for % %', i_dt , (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id);
+        v_nsamount := 0.0;
+        
+        
+        --RETURN 0;
+    END IF;
+    
+    
+     SELECT accnt_id INTO v_gainloss_id FROM accnt where accnt_number = '5500';
+    -- pos or neg???
+    -- skip  curr gain loss account..
+    IF v_gainloss_id  = i_accnt_id THEN
+        RETURN 0;
+    END IF;
+    
+    
+    
+    SELECT      
+           ROUND(COALESCE(       SUM(trialbal_ending -  trialbal_beginning)  * v_fact  , 0.0),2)
+          
+        
+        INTO 
+           v_amount
+           
+        FROM
+            trialbal
+        LEFT JOIN
+           period
+        ON
+           period_id = trialbal_period_id
+        LEFT JOIN
+            accnt
+        ON
+            accnt_id = trialbal_accnt_id
+            
+        WHERE
+               trialbal_accnt_id=i_accnt_id
+        AND
+                period_start <= i_dt ;
+     
+    
+     
+    
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'balance not found, using zero';
+        v_amount := 0.0;
+    END IF;
+    
+    v_change := (v_amount - v_nsamount)  ;
+    
+    
+    
+     -- already fixed..
+      IF (v_change = 0.00) THEN
+        RAISE NOTICE '(FIXED ALREADY) % NETSUITE EOY : FACT: % ID(%) %,     NS: %  DR: %                   DIFF: %  ',
+            i_dt,
+            v_fact,
+            i_accnt_id,
+          (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id),
+            v_nsamount,
+            v_amount,
+            v_change;
+        RETURN 0;
+    END IF;
+    
+    
+       -- have we done the fix.
+
+    
+    RAISE NOTICE 'BEFORE DELETE OLD TX: FACT:%   ACC: %    NS: %  DR: %                   DIFF: %  ',
+        v_fact,
+        (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id),
+            v_nsamount,
+            v_amount,
+            v_change;
+    
+    SELECT
+            gltrans_sequence
+        INTO
+            v_result
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text
+            AND
+            gltrans_deleted = false
+        LIMIT 1 ;
+        
+    IF FOUND THEN
+        --RAISE NOTICE 'Already processed';
+        --RETURN 0;
+        
+        RAISE NOTICE 'Deleteing old attempt';
+        
+        SELECT deleteGlSeries(v_result ,  'Journal edited by alan on ' || to_char(NOW(), 'Day Mon DD YYY') ) INTO v_resultbool;
+    
+    END IF;
+            
+    
+    
+    
+    -- what is our gl balance...
+    
+     SELECT      
+            
+           ROUND(COALESCE(       SUM(trialbal_ending -  trialbal_beginning)  * v_fact , 0.0),2)
+          
+        
+        INTO 
+           v_amount
+           
+        FROM
+            trialbal
+        LEFT JOIN
+           period
+        ON
+           period_id = trialbal_period_id
+        LEFT JOIN
+            accnt
+        ON
+            accnt_id = trialbal_accnt_id
+            
+        WHERE
+               trialbal_accnt_id=i_accnt_id
+        AND
+                period_start <= i_dt ;
+     
+     
+    
+    IF NOT FOUND THEN
+        v_amount := 0.0;
+    END IF;
+    
+    v_change := (v_amount - v_nsamount) ;
+    
+    
+    
+
+    RAISE NOTICE 'NETSUITE EOY : FACT:%   ACC: %    NS: %  DR: %                   DIFF: %  ',
+        v_fact,
+        (SELECT accnt_number || ' ' || accnt_descrip  from accnt where accnt_id = i_accnt_id),
+            v_nsamount,
+            v_amount,
+            v_change;
+    
+    --RETURN 0;
+    IF (v_change = 0.00) THEN
+        RETURN 0;
+    END IF;
+    
+
+  
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text,
+                        (SELECT accnt_id FROM accnt where accnt_number = '5500'),
+                        v_change  * v_fact ,
+                       i_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries  failed';
+    END IF;
+    
+
+
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                        'NS-EOYJEFIX-' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text,
+                        i_accnt_id,
+                        v_change * v_fact * -1.0,
+                       i_dt ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries  failed';
+    END IF;
+    
+    
+    
+    
+
+    
+    --  Prepaid Account - Purchasing  (100) + 63  + (63 - 70)
+     
+    -- Currency Gain Loss (122) - 126
+    
+    -- validate it...
+     SELECT
+            sum(glseries_amount)
+        INTO
+            v_change
+        FROM
+            glseries
+        WHERE
+            glseries_sequence = v_glsequence;
+            
+            
+    RAISE NOTICE 'ENSURE transactions result in ZERO % ', v_change;
+    
+    if (v_change != 0.0) THEN
+        
+    
+        RAISE EXCEPTION 'change is not valid';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fix import end of year ' || to_char(i_dt, 'YYYY-MM-DD') || '-' || i_accnt_id::text
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+     
+    
+     
+    RETURN v_result;
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
diff --git a/pgsql/migration/x-netsuite-eoy-fix2009.sql b/pgsql/migration/x-netsuite-eoy-fix2009.sql
new file mode 100644 (file)
index 0000000..a036204
--- /dev/null
@@ -0,0 +1,43 @@
+
+--
+--
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+        where period_end <= '2008-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+        where period_end <= '2008-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+        
+SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2008-04-30';
+--
+--
+--
+----
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'AP';
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'AR';
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+
+
+
+SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+
+
+--SELECT netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+----
+--SELECT  netsuite_eoyfix( '2009-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '394';
+--
+--
+--
+--
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2009-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+--    
+---- try a couple of times
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2009-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2009-04-30';
+
+--
+-- 
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix2010.sql b/pgsql/migration/x-netsuite-eoy-fix2010.sql
new file mode 100644 (file)
index 0000000..c4d0108
--- /dev/null
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'AR';
+
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+--SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_subaccnttype_code = 'IN';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '273';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '271';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '402';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '280';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '147';
+SELECT  netsuite_eoyfix( '2010-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '131';
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2010-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+------ try a couple of times
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2010-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+----    
+--SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2010-04-30';
+--
+-- 
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix2011.sql b/pgsql/migration/x-netsuite-eoy-fix2011.sql
new file mode 100644 (file)
index 0000000..7f9cfae
--- /dev/null
@@ -0,0 +1,53 @@
+
+
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+--        (  'AR'  )  ;
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+--        (  'AP'  )  ;
+
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where 
+--      accnt_number  IN ('402') ;
+--
+
+SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+        
+        
+        
+SELECT  netsuite_eoyfix( '2011-06-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+        
+SELECT  netsuite_eoyfix( '2011-07-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-08-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+        
+SELECT  netsuite_eoyfix( '2011-10-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-11-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-12-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+
+SELECT  netsuite_eoyfix( '2012-01-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2012-02-29'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2012-03-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+        
+  
+        
+        --select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2011-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+-------- try a couple of times
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2011-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+------    
+--SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2011-04-30';
+--
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix2011sg.sql b/pgsql/migration/x-netsuite-eoy-fix2011sg.sql
new file mode 100644 (file)
index 0000000..0a8e451
--- /dev/null
@@ -0,0 +1,50 @@
+-- run: PAGER=cat psql -Uadmin sandboxsg -f Pman/Xtuple/psql/migration/x-netsuite-eoy-fix2011sg.sql
+
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+--        (  'AR'  )  ;
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code  IN
+--        (  'AP'  )  ;
+
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'HK', -1) from accnt where 
+--      accnt_number  IN ('402') ;
+--
+--SELECT  netsuite_eoyfix( '2010-10-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE', 'EXPTAX', 'OI', 'EXPV' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--         
+--        
+--SELECT  netsuite_eoyfix( '2010-11-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE', 'EXPTAX', 'OI', 'EXPV' ) OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--        
+--SELECT  netsuite_eoyfix( '2010-12-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA','SHIPSTORE'  , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--SELECT  netsuite_eoyfix( '2011-01-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN','FA'  ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--SELECT  netsuite_eoyfix( '2011-02-28'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA','SHIPSTORE'  , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--        
+--SELECT  netsuite_eoyfix( '2011-03-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN','FA' ,'SHIPSTORE'  , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--SELECT  netsuite_eoyfix( '2011-04-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+--SELECT  netsuite_eoyfix( '2011-05-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+--        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+
+SELECT  netsuite_eoyfix( '2011-06-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-07-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+SELECT  netsuite_eoyfix( '2011-08-31'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',     'EDC',  'COGS',  'CAS', 'CL', 'IN' ,'FA' ,'SHIPSTORE' , 'EXPTAX', 'OI', 'EXPV') OR  accnt_number   IN ( '394', '402', '278', '279', '280','147', '131');
+        
+  
+        
+        --select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2011-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+-------- try a couple of times
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2012-08-31' and period_closed = false and period_freeze = false order by period_start ASC;
+------    
+--SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2011-04-30';
+--
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-eoy-fix2012.sql b/pgsql/migration/x-netsuite-eoy-fix2012.sql
new file mode 100644 (file)
index 0000000..2a96263
--- /dev/null
@@ -0,0 +1,38 @@
+
+
+
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK', -1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'AR';
+
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_subaccnttype_code = 'IN';
+
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '402';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '278';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '279';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '280';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '147';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '131';
+
+
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_number  = '442';
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   1) from accnt where accnt_number  = '451';
+
+SELECT  netsuite_eoyfix_based( '2012-04-30'::date, accnt_id,  'HK',   -1) from accnt where accnt_number  = '201';
+
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2012-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+-------- try a couple of times
+--select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+--    where period_end <= '2012-04-30' and period_closed = false and period_freeze = false order by period_start ASC;
+------    
+--SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2012-04-30';
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-fixap.sql b/pgsql/migration/x-netsuite-fixap.sql
new file mode 100644 (file)
index 0000000..189010e
--- /dev/null
@@ -0,0 +1,382 @@
+
+
+
+
+  
+CREATE OR REPLACE FUNCTION netsuite_fix_ar(i_id INTEGER ) RETURNS VOID 
+AS $BODY$
+
+DECLARE
+    v_id INTEGER;
+    
+
+    v_docdate DATE;
+    v_vend_id INTEGER;
+    v_curr_id INTEGER;
+    v_amount numeric(12,2);
+    v_target_curr_id INTEGER;
+    v_target_amount numeric(12,2);
+    
+    v_matches INTEGER;
+    v_result INTEGER;
+    v_docnumber TEXT;
+    
+BEGIN
+   
+   -- find the credit memo ap..
+   SELECT
+            apopen_docdate,
+            apopen_curr_id,
+            apopen_amount,
+            apopen_vend_id
+        INTO
+            v_docdate,
+            v_curr_id,
+            v_amount,
+            v_vend_id
+        FROM 
+            apopen
+        WHERE
+            apopen_id = i_id
+            AND
+            apopen_paid = 0.0
+            AND
+            apopen_doctype = 'C';
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'SKIP - apopen_id = % NOT FOUND', i_id;
+        RETURN;
+    END IF;
+    
+    -- next find the voucher..
+    
+    SELECT
+            count(apopen_id)
+        INTO
+            v_matches
+        FROM
+            apopen  
+        WHERE
+            apopen_doctype = 'V'
+            AND 
+            apopen_docdate = v_docdate
+            AND
+            (
+                (
+                    apopen_curr_id = v_curr_id
+                    AND
+                    apopen_amount = v_amount
+                )
+                OR
+                (
+                    apopen_curr_id != v_curr_id
+                    AND
+                    ROUND(currtocurr(apopen_curr_id, v_curr_id, apopen_amount , v_docdate),2) = v_amount
+                )
+            )
+            
+            AND
+            apopen_paid = 0.0
+            AND
+            apopen_vend_id = v_vend_id;
+            
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'SKIP  Voucher not found for - apopen_id = % ', i_id;
+        RETURN;
+    END IF;
+            
+    IF v_matches < 1 THEN
+        RAISE NOTICE 'SKIP found % matches for - apopen_id = %  USING (%,%,%)', v_matches,
+                i_id, v_docdate, v_curr_id, v_amount; 
+        RETURN;
+    END IF;
+    
+    
+         
+    SELECT
+            apopen_id,
+            apopen_curr_id,
+            apopen_amount
+        INTO
+            v_id,
+            v_target_curr_id,
+            v_target_amount
+        FROM
+            apopen  
+        WHERE
+            apopen_doctype = 'V'
+            AND 
+            apopen_docdate = v_docdate
+            AND
+            (
+                (
+                    apopen_curr_id = v_curr_id
+                    AND
+                    apopen_amount = v_amount
+                )
+                OR
+                (
+                    apopen_curr_id != v_curr_id
+                    AND
+                    ROUND(currtocurr(apopen_curr_id, v_curr_id, apopen_amount , v_docdate),2) = v_amount
+                )
+            )
+            AND
+            apopen_paid = 0.0
+            AND
+            apopen_vend_id = v_vend_id
+             
+        LIMIT 1;
+    
+    -- first try and create...
+     RAISE NOTICE 'createapcreditmemoapplication(%, % , %, %) ',
+                i_id,
+                v_id,
+                v_target_amount,
+                v_target_curr_id;
+
+
+    -- numbers should be the target currency...                
+    SELECT createapcreditmemoapplication(
+                i_id,
+                v_id,
+                v_target_amount,
+                v_target_curr_id
+                ) 
+            INTO
+                v_result;
+        
+    IF v_result < 0 THEN
+        RAISE EXCEPTION 'createapcreditmemoapplication(%, % , %, %) returned %',
+                i_id,
+                v_id,
+                v_amount,
+                v_curr_id, v_result;
+    END IF;
+    
+    RAISE NOTICE 'postapcreditmemoapplication(%, % ) ',
+               i_id,
+                v_docdate;
+                  
+    SELECT postapcreditmemoapplication(
+                i_id,
+                v_docdate
+                ) 
+            INTO
+                v_result;
+        
+    IF v_result < 0 THEN
+        RAISE EXCEPTION 'postapcreditmemoapplication(%, % ) returned %',
+                i_id,
+                v_docdate,
+                v_result;
+    END IF;
+    RAISE NOTICE 'FIXED   apopen_id = % ', i_id;
+    
+    RETURN;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+--SELECT  netsuite_fix_ar(2170);
+
+  
+-- SELECT  netsuite_fix_ar(apopen_id) FROM apopen WHERE  apopen_paid = 0.0 AND apopen_doctype = 'C' ;
+    
+
+  
+CREATE OR REPLACE FUNCTION netsuite_fix_ar_staff(i_id INTEGER ) RETURNS VOID 
+AS $BODY$
+
+DECLARE
+    v_id INTEGER;
+    
+
+    v_docdate DATE;
+    v_vend_id INTEGER;
+    v_curr_id INTEGER;
+    v_amount numeric(12,2);
+    
+    v_target_curr_id INTEGER;
+    v_target_amount numeric(12,2);
+    v_apply_amount numeric(12,2);
+    v_matches INTEGER;
+    v_result INTEGER;
+    v_docnumber TEXT;
+    
+BEGIN
+   RAISE NOTICE 'TRY  apopen_id = % ', i_id;
+   -- find the credit memo ap..
+   SELECT
+            apopen_docdate,
+            apopen_curr_id,
+            apopen_amount - apopen_paid,
+            apopen_vend_id
+        INTO
+            v_docdate,
+            v_curr_id,
+            v_amount,
+            v_vend_id
+        FROM 
+            apopen
+        WHERE
+            apopen_id = i_id
+            AND
+            apopen_paid  < apopen_amount
+            AND
+            apopen_doctype = 'C'
+            AND
+            apopen_vend_id = 688;
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'SKIP - apopen_id = % NOT FOUND', i_id;
+        RETURN;
+    END IF;
+    
+    -- next find the voucher..
+    
+    LOOP 
+    
+        -- do we have any potential matches?
+        SELECT
+                count(apopen_id)
+            INTO
+                v_matches
+            FROM
+                apopen  
+            WHERE
+                apopen_doctype = 'V'
+                
+                AND
+                apopen_curr_id = v_curr_id
+                      
+                AND
+                apopen_paid < apopen_amount
+                AND
+                apopen_vend_id = v_vend_id;
+                
+        
+        IF NOT FOUND THEN
+            RAISE NOTICE 'SKIP  Voucher not found for - apopen_id = % ', i_id;
+            RETURN;
+        END IF;
+                
+        IF v_matches < 1 THEN
+            RAISE NOTICE 'SKIP found % matches for - apopen_id = %  USING (%,%,%)', v_matches,
+                    i_id, v_docdate, v_curr_id, v_amount; 
+            RETURN;
+        END IF;
+        
+        -- now find the earliest match.. it may even be after...
+             
+        SELECT
+                apopen_id,
+                apopen_curr_id,
+                apopen_amount - apopen_paid
+            INTO
+                v_id,
+                v_target_curr_id,
+                v_target_amount
+            FROM
+                apopen  
+            WHERE
+                apopen_doctype = 'V'
+               
+                AND
+                apopen_curr_id = v_curr_id
+                     
+                AND
+                apopen_paid  < apopen_amount
+                AND
+                apopen_vend_id = v_vend_id
+                
+                ORDER BY
+                    apopen_doctype ASC
+                 
+            LIMIT 1;
+        
+        
+        -- work out how much to apply
+        v_apply_amount := v_target_amount;
+        IF (v_target_amount > v_amount) THEN
+           v_apply_amount := v_amount;
+        END IF;
+        
+        v_amount := v_amount - v_apply_amount;
+        
+        RAISE NOTICE 'APPLY : %   NOW REMAINING %', v_apply_amount , v_amount;
+        -- first try and create...
+         RAISE NOTICE 'createapcreditmemoapplication(%, % , %, %) ',
+                    i_id,
+                    v_id,
+                    v_apply_amount,
+                    v_target_curr_id;
+    
+    
+        -- numbers should be the target currency...                
+        SELECT createapcreditmemoapplication(
+                    i_id,
+                    v_id,
+                    v_apply_amount,
+                    v_target_curr_id
+                    ) 
+                INTO
+                    v_result;
+            
+        IF v_result < 0 THEN
+            RAISE EXCEPTION 'createapcreditmemoapplication(%, % , %, %) returned %',
+                    i_id,
+                    v_id,
+                    v_apply_amount,
+                    v_curr_id, v_result;
+        END IF;
+        
+        RAISE NOTICE 'postapcreditmemoapplication(%, % ) ',
+                   i_id,
+                    v_docdate;
+                      
+        SELECT postapcreditmemoapplication(
+                    i_id,
+                    v_docdate
+                    ) 
+                INTO
+                    v_result;
+            
+        IF v_result < 0 THEN
+            RAISE EXCEPTION 'postapcreditmemoapplication(%, % ) returned %',
+                    i_id,
+                    v_docdate,
+                    v_result;
+        END IF;
+        
+        
+        IF (v_amount <= 0.0) THEN
+            RAISE NOTICE 'FIXED   apopen_id = % ', i_id;
+    
+            RETURN;
+        END IF;    
+    
+    END LOOP;
+    
+    RAISE NOTICE 'FIXED   apopen_id = % ', i_id;
+    
+    RETURN;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+  
+--SELECT  netsuite_fix_ar_staff(apopen_id) FROM apopen WHERE
+
+--    apopen_paid < apopen_amount
+    --AND
+    --apopen_doctype = 'C'
+    --AND
+    --apopen_vend_id = 688
+    --ORDER BY
+    --apopen_docdate ASC;  
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-fixap2.sql b/pgsql/migration/x-netsuite-fixap2.sql
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pgsql/migration/x-netsuite-fixflipje.sql b/pgsql/migration/x-netsuite-fixflipje.sql
new file mode 100644 (file)
index 0000000..37b9f29
--- /dev/null
@@ -0,0 +1,189 @@
+-- caused by je being done backwards..
+
+
+CREATE OR REPLACE FUNCTION fixflipje(text )
+  RETURNS integer AS
+$BODY$
+DECLARE
+  i_oldtx ALIAS FOR $1;
+  
+  v_oldseries INTEGER;
+  v_transdate DATE;
+  v_amount DECIMAL (18,3);
+  v_ap_amount DECIMAL (18,3);
+  v_change DECIMAL (18,3);
+   
+  v_docnumber TEXT;
+  v_glsequence INTEGER;
+  v_result INTEGER;
+  v_resultbool BOOLEAN;
+  
+  v_r RECORD;
+  
+BEGIN
+
+
+    SELECT 
+        COUNT(DISTINCT(gltrans_sequence))
+    INTO
+        v_oldseries 
+    
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = i_oldtx;
+            
+        
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Missing tx %',i_oldtx;
+
+    END IF;
+    
+    IF v_oldseries != 1 THEN
+        RAISE EXCEPTION 'More than one match for  tx %',i_oldtx;
+    -- fixed already..
+    END IF;
+    
+    SELECT 
+            gltrans_sequence
+        INTO
+            v_oldseries 
+    
+        FROM
+            
+            gltrans
+        WHERE
+            gltrans_docnumber = i_oldtx
+            AND
+            gltrans_deleted = false
+        LIMIT 1;
+        
+    IF NOT FOUND THEN
+        RAISE NOTICE 'ALREADY DELETED %',i_oldtx;
+        RETURN 0;
+    END IF;
+    
+    
+    
+    -- have we done the fix.
+
+    
+    SELECT
+            gltrans_id
+        INTO
+            v_result
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'NS-VCJEFIX-' || i_oldtx
+            AND
+            gltrans_deleted = false
+        LIMIT 1 ;
+        
+    IF FOUND THEN
+        RAISE NOTICE 'Already processed';
+        RETURN 0;
+    END IF;
+            
+
+
+
+
+
+
+
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    
+    
+    FOR v_r IN
+        SELECT
+                *
+            FROM 
+                gltrans
+            WHERE
+                gltrans_sequence = v_oldseries
+                
+        LOOP
+           
+                
+    
+        
+    
+    
+            SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCJEFIX-' || i_oldtx,
+                                v_r.gltrans_accnt_id,
+                               v_r.gltrans_amount * -1.0,
+                               v_r.gltrans_date) INTO v_result;
+    
+            if (v_result < 1) THEN
+                
+            
+                RAISE EXCEPTION 'insertIntoGLSeries  failed';
+            END IF;
+    
+    
+     END LOOP;
+    
+    --  Prepaid Account - Purchasing  (100) + 63  + (63 - 70)
+     
+    -- Currency Gain Loss (122) - 126
+    
+    -- validate it...
+     SELECT
+            sum(glseries_amount)
+        INTO
+            v_change
+        FROM
+            glseries
+        WHERE
+            glseries_sequence = v_glsequence;
+            
+            
+    RAISE NOTICE 'Change % ', v_change;
+    
+    if (v_change != 0.0) THEN
+        
+    
+        RAISE EXCEPTION 'change is not valid';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fix import issues with Vendor Credit Adjustment: '  || i_oldtx
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+    SELECT deleteGlSeries(v_oldseries ,  'Journal edited by alan on ' || to_char(NOW(), 'Day Mon DD YYY') ) INTO v_resultbool;
+    
+    
+    if (v_resultbool = false) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+     
+    RETURN v_result;
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+SELECT  fixflipje('NS-JE-VC-EXP-5769-749-749');
+SELECT  fixflipje('NS-JE-VC-EXP-5769-748-748');
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-fixvendorcredit.sql b/pgsql/migration/x-netsuite-fixvendorcredit.sql
new file mode 100644 (file)
index 0000000..19d821c
--- /dev/null
@@ -0,0 +1,217 @@
+
+CREATE OR REPLACE FUNCTION fixvendorcredit(integer, text)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  i_oldid ALIAS FOR $1;
+  i_tranid ALIAS FOR $2;
+  
+  
+  v_transdate DATE;
+  v_full_credit_amount DECIMAL (18,3);
+  v_full_debit_amount  DECIMAL (18,3);
+  v_adj_amount DECIMAL (18,3);
+  
+  v_change DECIMAL (18,3);
+  
+  v_glsequence INTEGER;
+  v_result INTEGER;
+  
+BEGIN
+
+    SELECT
+            gltrans_id
+        INTO
+            v_result
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'NS-VCFIX-' || i_tranid || '-' ||  i_oldid::text
+            AND
+            gltrans_deleted = false
+        LIMIT 1 ;
+        
+    IF FOUND THEN
+        RAISE EXCEPTION 'Already processed';
+    END IF;
+            
+
+
+    SELECT
+            gltrans_amount,
+            gltrans_date
+        INTO
+            v_full_credit_amount,
+            v_transdate
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'VC-' || i_tranid || '-' ||  i_oldid::text
+            AND
+            gltrans_doctype = 'CM'
+            AND
+            gltrans_accnt_id = 100;
+        
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find it   VC-%-%', i_oldid::text , i_tranid;
+    END IF;
+    
+    
+    -- find the inv adjusment amount..
+    SELECT
+            sum(gltrans_amount)
+        INTO
+            v_adj_amount 
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber LIKE  'NS-IA-VBC-' || i_tranid || '-' ||  i_oldid::text || '-IA-%'
+            AND
+            gltrans_doctype = 'AD'
+            AND
+            gltrans_accnt_id = 149
+            AND
+            gltrans_date = v_transdate;
+        
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find it   VNS-IA-VBC-%-%-IA-....', i_oldid::text , i_tranid;
+    END IF;
+    
+    
+    -- find the DM which contains the correct amount..
+    
+    SELECT
+            gltrans_amount
+         INTO
+            v_full_debit_amount
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber LIKE 'VC-' || i_tranid || '-' ||  i_oldid::text ||  '-REV-%'
+            AND
+            gltrans_doctype = 'DM'
+            AND
+            gltrans_accnt_id = 148;
+        
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find it   VC-%-%-REV-...', i_oldid::text , i_tranid;
+    END IF;
+    
+    
+     RAISE NOTICE 'DATE: %', v_transdate;
+    RAISE NOTICE 'Full Credit: %', v_full_credit_amount; -- 70
+    RAISE NOTICE 'Full Debit: %', v_full_debit_amount; -- 63
+    RAISE NOTICE 'IA Adjust amount: %', v_adj_amount; -- 100
+   
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    --  Prepaid Account - Purchasing  (100) + 63  + (63 - 70)
+    
+    RAISE NOTICE 'prepaid - %', ((v_full_debit_amount * 2) - v_full_credit_amount);
+    SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCFIX-' || i_tranid || '-' ||  i_oldid::text,
+                                100,
+                               (v_full_debit_amount * 2) - v_full_credit_amount,
+                                v_transdate) INTO v_result;
+    -- Currency Gain Loss (122) - 126
+    
+    RAISE NOTICE 'cur gainloss- %', v_full_debit_amount * -2.0;
+     SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCFIX-' || i_tranid || '-' ||  i_oldid::text,
+                                122,
+                               v_full_debit_amount * -2.0,
+                               v_transdate) INTO v_result;
+    --- Invenotry Asset 149 - 100+70
+    
+    RAISE NOTICE 'inventory asset - %', v_full_debit_amount -  v_adj_amount ;
+      SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCFIX-' || i_tranid || '-' ||  i_oldid::text,
+                                149,
+                              v_full_credit_amount  -  v_adj_amount ,
+                               v_transdate) INTO v_result;
+  
+     --- AP (SG)  148 -- DO NOTHING? (the only change here is the later application bug..)
+     
+     -- inventory adjust 291
+    RAISE NOTICE 'inventory adjustment - %', v_adj_amount  ;
+      SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCFIX-' || i_tranid || '-' ||  i_oldid::text,
+                                291,
+                               v_adj_amount  ,
+                               v_transdate) INTO v_result;
+     
+     
+     SELECT
+            sum(glseries_amount)
+        INTO
+            v_change
+        FROM
+            glseries
+        WHERE
+            glseries_sequence = v_glsequence;
+            
+            
+    RAISE NOTICE 'Change % ', v_change;
+    
+    if (v_change != 0.0) THEN
+        
+    
+        RAISE EXCEPTION 'change is not valid';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fix import issues with Vendor Credit: ' || i_tranid || '-' ||  i_oldid::text
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+    
+            
+    RETURN v_result;
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+
+
+
+
+SELECT fixvendorcredit(5770, 'US0007'); 
+SELECT fixvendorcredit( 5773, 'US0014');
+
+SELECT fixvendorcredit( 5774, 'US0013');
+
+SELECT fixvendorcredit( 5776, 'US0017');
+
+
+SELECT fixvendorcredit(5741, 'Stock-return');
+SELECT fixvendorcredit(5780, 'US0027');
+
+SELECT fixvendorcredit(5781, 'US0028');
+SELECT fixvendorcredit(5779, 'US0026');
diff --git a/pgsql/migration/x-netsuite-fixvendorcreditje.sql b/pgsql/migration/x-netsuite-fixvendorcreditje.sql
new file mode 100644 (file)
index 0000000..df5d896
--- /dev/null
@@ -0,0 +1,187 @@
+
+
+
+
+CREATE OR REPLACE FUNCTION fixvendorcreditje(integer )
+  RETURNS integer AS
+$BODY$
+DECLARE
+  i_oldseries ALIAS FOR $1;
+  
+  v_transdate DATE;
+  v_amount DECIMAL (18,3);
+  v_ap_amount DECIMAL (18,3);
+  v_change DECIMAL (18,3);
+   
+  v_docnumber TEXT;
+  v_glsequence INTEGER;
+  v_result INTEGER;
+  
+BEGIN
+
+    -- cur gainloss...
+    SELECT
+            gltrans_docnumber,
+            gltrans_amount,
+            gltrans_date
+        INTO
+            v_docnumber,
+            v_amount,
+            v_transdate
+        FROM
+            gltrans
+        WHERE
+            gltrans_sequence = i_oldseries
+        AND
+            gltrans_accnt_id = 122
+        AND
+            gltrans_doctype = 'JE'
+        LIMIT 1 ;
+        
+    
+    IF NOT FOUND THEN
+        RAISE NOTICE 'Missing';
+        RETURN 0;
+    END IF;
+    
+
+    -- fixed already..
+
+    SELECT
+            gltrans_id
+        INTO
+            v_result
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'NS-VCJEFIX-' || v_docnumber
+            AND
+            gltrans_deleted = false
+        LIMIT 1 ;
+        
+    IF FOUND THEN
+        RAISE NOTICE 'Already processed';
+        RETURN 0;
+    END IF;
+            
+
+    SELECT
+            COUNT(gltrans_id)
+        INTO
+            v_result
+        FROM
+             gltrans
+        WHERE
+            gltrans_sequence = i_oldseries;
+
+    IF (v_result != 3) THEN
+        RAISE NOTICE 'Not 3 item transaction - skipping';
+        RETURN 0;
+    END IF;
+    
+    -- get AP amount.
+    SELECT
+            gltrans_amount 
+        INTO
+            v_ap_amount
+        FROM
+            gltrans
+        WHERE
+            gltrans_sequence = i_oldseries 
+            AND
+            gltrans_accnt_id = 148;
+        
+        
+    IF NOT FOUND THEN
+        RAISE NOTICE 'could not find it   AP Transaction';
+        RETURN 0;
+    END IF;
+    
+      
+    
+    RAISE NOTICE 'DATE: %', v_transdate;
+    RAISE NOTICE 'Adjust amount: %', v_amount; -- 100
+   
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    --  Prepaid Account - Purchasing  (100) + 63  + (63 - 70)
+     
+    -- Currency Gain Loss (122) - 126
+    
+    
+     SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCJEFIX-' || v_docnumber,
+                                122,
+                               v_amount * -1.0,
+                               v_transdate) INTO v_result;
+    
+     --- AP (SG)  148 -- DO NOTHING? (the only change here is the later application bug..)
+     
+    
+       SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'NS-VCJEFIX-' || v_docnumber,
+                                148,
+                               v_amount  ,
+                               v_transdate) INTO v_result;
+     
+     
+     SELECT
+            sum(glseries_amount)
+        INTO
+            v_change
+        FROM
+            glseries
+        WHERE
+            glseries_sequence = v_glsequence;
+            
+            
+    RAISE NOTICE 'Change % ', v_change;
+    
+    if (v_change != 0.0) THEN
+        
+    
+        RAISE EXCEPTION 'change is not valid';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fix import issues with Vendor Credit Adjustment: '  || v_docnumber
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+     
+    RETURN v_result;
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+SELECT fixvendorcreditje(gls_id) FROM
+    (SELECT
+        distinct(gltrans_sequence) AS gls_id
+    FROM
+    
+        gltrans
+    WHERE
+        gltrans_accnt_id = 122
+        AND
+        gltrans_doctype = 'JE'
+        AND
+        gltrans_docnumber like 'NS-JE-P%'
+    ) gls  ;
diff --git a/pgsql/migration/x-netsuite-recv.sql b/pgsql/migration/x-netsuite-recv.sql
new file mode 100644 (file)
index 0000000..44097d9
--- /dev/null
@@ -0,0 +1,176 @@
+-- plan b....
+
+-- needs to fill in:
+-- a) recv_recvgrp_id in recv
+-- b) various data on recvgrp
+
+
+  
+CREATE OR REPLACE FUNCTION recvgrp_migrate(i_id INTEGER ) RETURNS VOID 
+AS $BODY$
+
+DECLARE
+    v_gid INTEGER;
+    v_poid INTEGER;
+
+    v_number text;
+    v_date date;
+    v_oldid text;
+    v_locname text;
+    v_locid INTEGER;
+    v_landedcost decimal(12,4);
+    v_irid INTEGER;
+    v_currid INTEGER;
+    
+BEGIN
+   
+        v_gid := NULL;
+        
+        SELECT
+                recv_oldid,
+                recv_recvgrp_id,
+                (SELECT
+                        poitem_pohead_id
+                    FROM
+                        poitem
+                    WHERE
+                        poitem_id = recv_orderitem_id
+                    LIMIT 1
+                )
+            INTO
+                v_oldid,
+                v_gid,
+                v_poid
+            FROM
+                recv
+            WHERE
+                recv_id = i_id;
+        
+        SELECT
+                pohead_curr_id
+            INTO
+                v_currid
+            FROM
+                pohead
+            WHERE
+                pohead_id = v_poid;
+       
+        
+        SELECT
+                trandate,
+                tranid,
+                Netsuite_Location.name,
+                ItemReceipt_id
+            INTO
+                v_date,
+                v_number,
+                v_locname,
+                v_irid
+            FROM
+                Netsuite_ItemReceiptItem
+            LEFT JOIN
+                Netsuite_ItemReceipt
+            ON
+                Netsuite_ItemReceipt.id = Netsuite_ItemReceiptItem.ItemReceipt_id
+            LEFT JOIN
+                Netsuite_Location
+            ON
+                Netsuite_Location.id = Netsuite_ItemReceiptItem.location
+            
+            WHERE
+                Netsuite_ItemReceiptItem.id::text = v_oldid;
+        
+        IF NOT FOUND THEN
+            RAISE NOTICE 'Missing item reciept for % - skipping', v_oldid;
+            RETURN ;
+        END IF;
+        
+        SELECT
+                COALESCE(SUM(amount),0)
+            INTO
+                v_landedcost
+            FROM
+                Netsuite_LandedCost
+            WHERE
+                ItemReciept_id = v_irid;
+             
+        
+        
+        
+         IF v_gid IS NOT NULL THEN
+            RAISE NOTICE 'Already have recvgrp % - just updateing', i_id;
+            UPDATE
+                    recvgrp
+                SET
+                    recvgrp_landed_cost = v_landedcost,
+                    recvgrp_landed_curr_id = v_currid,
+                    recvgrp_landed_method = 'Q'
+                WHERE
+                    recvgrp_id = v_gid;
+            
+            RETURN;
+        END IF;
+        
+        
+        -- now see if we already have the     
+        SELECT
+                recvgrp_id
+            INTO
+                v_gid
+            FROM
+                recvgrp
+            WHERE
+                recvgrp_number = v_number;
+                
+        IF FOUND THEN
+            UPDATE
+                    recv
+                SET
+                    recv_recvgrp_id = v_gid
+                WHERE
+                    recv_id = i_id;
+            RETURN;
+            
+        END IF;
+        
+        
+        SELECT
+                location_id
+            INTO
+                v_locid
+            FROM
+                location
+            WHERE
+                location_name = v_locname
+                OR
+                location_name = 'CONSIGN : ' || v_locname;
+                
+        IF NOT FOUND THEN
+            RAISE NOTICE 'COULD NOT FIND LOCATION %s - skipping', v_locname;
+            RETURN;
+        END IF;
+        -- we do not have it...
+        
+        
+        -- 
+        INSERT INTO recvgrp (
+                recvgrp_number, recvgrp_date, recvgrp_pohead_id,
+                recvgrp_location_id, recvgrp_landed_cost, recvgrp_landed_curr_id,
+                recvgrp_landed_method
+                
+            )
+        VALUES
+            (
+                v_number, v_date, v_poid,
+                v_locid, v_landedcost,  v_currid,
+                'Q'
+            ); 
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+  
+SELECT  recvgrp_migrate(recv_id ) FROM recv where recv_oldid IS NOT NULL;
+  
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-taxfix.sql b/pgsql/migration/x-netsuite-taxfix.sql
new file mode 100644 (file)
index 0000000..255f9d8
--- /dev/null
@@ -0,0 +1,325 @@
+
+
+-- SELECT netsuite_fix_tax(gltrans_id) FROM gltrans WHERE gltrans_acct_id = 123 AND gltrans_doctype != 'JE';
+  
+CREATE OR REPLACE FUNCTION netsuite_fix_tax(i_id INTEGER ) RETURNS VOID 
+AS $BODY$
+
+DECLARE
+    v_id INTEGER;
+    
+
+    v_date DATE;
+    
+    v_doctype TEXT;
+    v_journalnumber INT;
+    
+    v_amount numeric(12,2);
+    v_taxtotal numeric(12,2);
+    v_mul numeric(12,2);
+    v_je_id INTEGER;
+    
+    v_result INTEGER;
+    v_glsequence INTEGER;
+    
+    v_docnumber TEXT;
+    v_desc  TEXT;
+    v_is_void BOOLEAN;
+    v_num_rev INTEGER;
+    
+    v_tax_accnt INTEGER;
+    
+BEGIN
+   
+   v_tax_accnt := 138; -- Sales
+   --v_tax_accnt : = 139; // Purchases
+   v_mul := 1.0;
+   -- find the credit memo ap..
+    SELECT
+            gltrans_journalnumber,
+            gltrans_doctype,
+            gltrans_amount,
+            gltrans_date,
+            gltrans_docnumber
+            
+        INTO
+            v_journalnumber,
+            v_doctype,
+            v_amount,
+            v_date,
+            v_docnumber
+            
+        FROM
+            gltrans
+        WHERE
+                gltrans_accnt_id = 123
+            AND
+                gltrans_doctype != 'JE'
+            AND
+                gltrans_id = i_id;
+                
+    
+     IF NOT FOUND THEN
+        RAISE NOTICE 'SKIP - gltrans_id = % NOT FOUND', i_id;
+        RETURN;
+    END IF;
+    
+    -- see if we have created a JE ? 
+   
+   
+   SELECT
+            gltrans_id
+            
+        INTO
+            v_je_id
+            
+        FROM
+            gltrans
+        WHERE
+                gltrans_accnt_id = 123
+            AND
+                gltrans_doctype = 'JE'
+            AND
+                gltrans_docnumber = 'TAX-' || v_docnumber || '-' || i_id;
+            
+    IF FOUND THEN
+        RAISE NOTICE 'SKIP - gltrans_id = % ALREADY TRANSFERED', i_id;
+        RETURN;
+    END IF;
+    
+    
+    if (v_doctype = 'CR') THEN
+        RAISE NOTICE 'SKIP - gltrans_id = % IGNORE CR', i_id;
+        RETURN;
+    END IF;
+    
+    -- next verify that it's valid.
+    
+    IF (v_doctype = 'IN') THEN
+    
+    
+       
+        
+        SELECT
+                invchead_void
+            INTO
+                v_is_void
+            FROM
+                invchead
+            WHERE
+                invchead_invcnumber = v_docnumber
+            LIMIT 1;
+            
+        IF NOT FOUND THEN
+            -- not invoice found..
+            RAISE EXCEPTION 'SKIP - gltrans_id = % could not find docnumber=%', i_id,v_docnumber;
+            RETURN;
+        END IF;
+        
+        IF  v_is_void THEN
+        
+            -- we have the case that some invoices have been voided, however when the void occured,
+            -- I had already set up the correct account...
+            
+            -- see if we can find the void record...
+            SELECT
+                    count(gltrans_id)
+                INTO
+                    v_num_rev
+                FROM
+                    gltrans
+                WHERE
+                    gltrans_docnumber = v_docnumber
+                AND
+                    gltrans_accnt_id = 123;
+            
+            
+            IF NOT FOUND THEN
+                RAISE EXCEPTION 'SKIP - gltrans_id = % could not find trans in gltrans? should not happend... docnumber=%', i_id,v_docnumber;
+                RETURN;
+            END IF;
+            IF v_num_rev = 2 THEN
+                RAISE NOTICE 'SKIP - gltrans_id = % Reversed invoice', i_id;
+                RETURN;
+            END IF;
+            IF v_num_rev != 1 THEN
+                  RAISE EXCEPTION 'SKIP - gltrans_id = % got % matches for   docnumber=%', i_id, v_num_rev, v_docnumber;
+                RETURN;
+            END IF;
+            -- otherwise ?? it should be '1' and we will reverse it..
+             
+        END IF;
+        
+        select
+                sum(taxhist_tax)
+            INTO
+                v_taxtotal
+            FROM
+                invcitemtax
+            WHERE
+                taxhist_journalnumber =  v_journalnumber;
+        
+       
+        RAISE NOTICE 'v_taxtotal = %', v_taxtotal;
+        IF NOT FOUND OR v_taxtotal IS NULL OR v_taxtotal <  0.01  THEN
+            RAISE EXCEPTION 'SKIP - gltrans_id = % COULD NOT FIND invcitemtax for this', i_id;
+            RETURN;
+        END IF;
+        
+        
+        -- check to see if invoice has been voided, in which case a reversal has already occured..
+        
+        
+        
+        v_mul := -1;
+        v_desc := 'Invoice';
+        
+    ELSIF (v_doctype = 'CM') THEN
+        
+        
+        SELECT
+                sum(taxhist_tax)
+            INTO
+                v_taxtotal
+            FROM
+                cmitemtax
+            WHERE
+                taxhist_journalnumber =  v_journalnumber;
+        
+       
+        
+         
+            
+            
+        RAISE NOTICE 'v_taxtotal = %', v_taxtotal;
+        IF NOT FOUND OR v_taxtotal IS NULL  THEN
+        
+            SELECT
+                    SUM(taxhist_tax)
+                INTO
+                    v_taxtotal
+                FROM
+                    aropen
+                LEFT OUTER JOIN
+                    aropentax ON  (aropen_id=taxhist_parent_id)
+                            
+                LEFT OUTER JOIN
+                            cmhead ON ((aropen_doctype='C')
+                            AND (aropen_docnumber=v_docnumber));
+            RAISE NOTICE '[FROM aropentax] v_taxtotal = %', v_taxtotal;
+        
+        END IF;                  
+        IF NOT FOUND OR v_taxtotal IS NULL  THEN
+         
+            IF v_amount > -0.03 THEN
+                RAISE NOTICE 'SKIP - gltrans_id = % COULD NOT FIND cmitemtax for this', i_id;
+                RETURN;
+            END IF;
+        
+        
+            RAISE EXCEPTION 'SKIP - gltrans_id = % COULD NOT FIND cmitemtax for this (value=%)', i_id, v_amount;
+            RETURN;
+        END IF;
+        
+        v_mul := -1.0;
+    
+        v_desc := 'Credit Memo';
+    
+    ELSIF (v_doctype = 'VO') THEN
+        SELECT
+                sum(taxhist_tax)
+            INTO
+                v_taxtotal
+            FROM
+                voheadtax
+            WHERE
+                taxhist_journalnumber =  v_journalnumber;
+        
+        RAISE NOTICE 'v_taxtotal = %', v_taxtotal;
+        IF NOT FOUND OR v_taxtotal IS NULL OR v_taxtotal >  -0.01  THEN
+            RAISE EXCEPTION 'SKIP - gltrans_id = % COULD NOT FIND voheadtax for this where taxhist_journalnumber = %', i_id, v_journalnumber;
+            RETURN;
+        END IF;
+        
+        v_mul := -1.0;
+        v_tax_accnt := 139; -- Purchases
+        v_desc := 'Vendor Bill';
+        
+    ELSE
+        
+        RAISE EXCEPTION 'SKIP - gltrans_id = % NOT A VALID doctype? % ', i_id, v_doctype;
+        RETURN;
+    END IF;
+    
+    -- we have now determined that the transaction is of the right type, we need to create a Journal entry.
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    
+    
+    SELECT      insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                            'TAX-' || v_docnumber || '-' || i_id,
+                             
+                            123,
+                            v_mul * v_amount,
+                            v_date) INTO v_result;
+    IF (v_result < 1 ) THEN
+        RAISE EXCEPTION 'Error inserting GL SERIES for gltrans_id %', i_id;
+        RETURN;
+    END IF;
+    
+    -- the reverse. into 139
+     
+    SELECT      insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                            'TAX-' || v_docnumber || '-' || i_id,
+                             
+                             v_tax_accnt,
+                            -1.0 * v_mul * v_amount,
+                            v_date) INTO v_result;
+    
+    IF (v_result < 1 ) THEN
+        RAISE EXCEPTION 'Error inserting GL(2) SERIES for gltrans_id %', i_id;
+        RETURN;
+    END IF;
+    
+   UPDATE glseries
+                    SET glseries_notes = ' Tax For ' || v_desc || ' Ref: ' || v_docnumber
+                    
+                WHERE (glseries_sequence=v_glsequence);
+                
+    
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+    IF (v_result < 1 ) THEN
+        RAISE EXCEPTION 'Error inserting GL(2) SERIES for gltrans_id %', i_id;
+        RETURN;
+    END IF;    
+
+
+    RAISE NOTICE 'SUCCESS - CREATED JE FOR  gltrans_id = % (%)', i_id, v_doctype;
+
+    RETURN;
+     
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+  
+SELECT
+        netsuite_fix_tax(gltrans_id)
+    FROM
+        gltrans
+    WHERE
+        gltrans_accnt_id = 123;
+        
+--    AND
+--        gltrans_doctype = 'VO'
+--    LIMIT 2;
\ No newline at end of file
diff --git a/pgsql/migration/x-netsuite-voidporeturn.sql b/pgsql/migration/x-netsuite-voidporeturn.sql
new file mode 100644 (file)
index 0000000..d9e92de
--- /dev/null
@@ -0,0 +1,234 @@
+-- this fixes the mess I made by forgetting to update postporeject...
+
+-- SELECT fixporeject(68) ... 56
+
+CREATE OR REPLACE FUNCTION fixporeject(integer)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  i_poreject_id ALIAS FOR $1;
+  _itemlocSeries INTEGER;
+  _p RECORD;
+  _inv RECORD;
+_dist RECORD;
+  _returnval   INTEGER;
+  _returnvalbool BOOLEAN;
+  v_itemlocdist_id INTEGER;
+  v_itemloc_invhist_id INTEGER;
+BEGIN
+
+
+
+    _itemlocSeries := 0;
+   
+
+    RAISE EXCEPTION 'Do not use this, it puts the last transaction the wrong way round';
+    SELECT
+            *
+        INTO
+             _p
+        FROM
+            poreject
+        LEFT JOIN
+            poitem
+        ON
+            poreject_poitem_id = poitem_id
+        LEFT JOIN
+            pohead
+        ON
+            pohead_id = poitem_pohead_id
+            
+        WHERE
+            poreject_id = i_poreject_id;
+    
+    -- find the
+    
+    SELECT
+        *
+        INTO
+            _inv
+        FROM
+            invdetailview
+         
+            WHERE
+                invhist_ordnumber = _p.poreject_ponumber || '-' ||  _p.poitem_linenumber::TEXT
+                AND
+                invhist_comments = 'Fix invalid Return Inventory to P/O'
+                AND
+                invhist_itemsite_id = _p.poreject_itemsite_id;
+    
+    IF FOUND THEN
+        RAISE NOTICE 'Found the fix already - ignore';
+        RETURN 0;
+    END IF;
+    
+    
+    RAISE NOTICE 'SELECT * FROM invdetailview WHERE invhist_ordnumber=% AND invhist_transdate::date = % AND invhist_itemsite_id =  %',
+            _p.poreject_ponumber  || '-' ||  _p.poitem_linenumber::TEXT, '2012-10-10', _p.poreject_itemsite_id;
+    
+    SELECT
+        *
+        INTO
+            _inv
+        FROM
+            invdetailview
+         
+            WHERE
+                invhist_ordnumber =  _p.poreject_ponumber || '-' ||  _p.poitem_linenumber::TEXT
+                AND
+                invhist_transdate::date = '2012-10-10'
+                AND
+                invhist_itemsite_id = _p.poreject_itemsite_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'COULD NOT FIND INVDETAIL';
+    END IF;
+    
+-- post InvTransaction - to reverse wrong TX..
+
+    -- need to check the accnt ids - 149 / 141
+
+    IF (_itemlocSeries = 0) THEN
+        SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+    END IF;
+
+
+    --RAISE NOTICE '  SELECT postInvTrans(%, ''%'',%,''%'',''%'',''%'',''%'',''%'',%,%,%,''%''); ',
+    --        _p.poreject_itemsite_id,
+    --        'RP',
+    --        _inv.invhist_invqty,
+    --        'S/R',
+    --        'PO',
+    --        (_p.pohead_number || '-' || _p.poitem_linenumber::TEXT),
+    --        '',
+    --        'Fix invalid Return Inventory to P/O',
+    --        149, 
+    --        141,
+    --        _itemlocSeries,
+    --        _inv.invhist_transdate; 
+    --
+    RAISE NOTICE 'RUN IT';
+    
+    SELECT postInvTrans(
+            _p.poreject_itemsite_id,
+            'RP',
+            _inv.invhist_invqty,
+            'S/R',
+            'PO',
+            (_p.pohead_number || '-' || _p.poitem_linenumber::TEXT),
+            '',
+            'Fix invalid Return Inventory to P/O',
+            141, 
+            149,
+            _itemlocSeries,
+            _inv.invhist_transdate
+        ) INTO v_itemloc_invhist_id ;
+    
+    
+        
+    IF (v_itemloc_invhist_id < 0) THEN
+        RAISE EXCEPTION 'postInv reverse failed';
+    END IF;
+    
+    SELECT itemlocdist_id INTO v_itemlocdist_id FROM itemlocdist WHERE itemlocdist_invhist_id  = v_itemloc_invhist_id ;
+    
+    -- now reloacate the inventory
+    RAISE NOTICE 'RELOC INV';
+
+    
+
+        INSERT INTO itemlocdist (
+                    itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                    itemlocdist_source_id,  itemlocdist_qty,
+                    itemlocdist_ls_id, itemlocdist_expiration
+                )  SELECT
+                    itemlocdist_id,       'L',
+                    _inv.invdetail_location_id , _inv.invhist_invqty  * -1.0,
+                    itemlocdist_ls_id, endOfTime() FROM itemlocdist WHERE (itemlocdist_series= _itemlocSeries);
+        
+        RAISE NOTICE 'DIST IT';
+       
+        SELECT distributeToLocations(v_itemlocdist_id) INTO _returnval;
+       
+        IF (_returnval < 0) THEN
+            RAISE EXCEPTION 'distributeToLocations reverse failed';
+        END IF;
+        RAISE NOTICE 'POST IT';
+        
+        SELECT postItemlocseries(_itemlocSeries) INTO _returnvalbool;
+
+        IF (NOT _returnvalbool) THEN
+            RAISE EXCEPTION 'postItemlocseries reverse failed';
+        END IF;
+        
+
+    RAISE NOTICE 'REPOST IT';
+-- The post the correct transaction...
+    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+    SELECT postInvTrans(
+            _p.poreject_itemsite_id ,
+            'RP',
+            _inv.invhist_invqty  * -1.0,
+            'S/R',
+            'PO',
+            (_p.pohead_number || '-' || _p.poitem_linenumber::TEXT),
+            '',
+            'reapply Fix invalid Return Inventory to P/O',
+            149, 
+            141,
+            _itemlocSeries,
+            _p.poreject_date
+        ) INTO v_itemloc_invhist_id ;
+        
+        
+    IF (v_itemloc_invhist_id < 0) THEN
+        RAISE EXCEPTION 'postInv reverse failed';
+    END IF;       
+    
+    SELECT itemlocdist_id INTO v_itemlocdist_id FROM itemlocdist WHERE itemlocdist_invhist_id  = v_itemloc_invhist_id ;
+   
+    -- now reloacate the inventory
+
+
+        INSERT INTO itemlocdist (
+                    itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+                    itemlocdist_source_id,  itemlocdist_qty,
+                    itemlocdist_ls_id, itemlocdist_expiration
+                )  SELECT
+                    itemlocdist_id,       'L',
+                    _inv.invdetail_location_id , _inv.invhist_invqty ,
+                    itemlocdist_ls_id, endOfTime() FROM itemlocdist WHERE (itemlocdist_series= _itemlocSeries);
+
+      
+       SELECT distributeToLocations(v_itemlocdist_id) INTO _returnval;
+       
+        IF (_returnval < 0) THEN
+            RAISE EXCEPTION 'postItemlocseries reapply failed';
+        END IF;
+        
+       SELECT postItemlocseries(_itemlocSeries)  INTO _returnvalbool;
+
+
+      IF (NOT _returnvalbool) THEN
+            RAISE EXCEPTION 'postItemlocseries reverse failed';
+        END IF;
+      
+
+  RETURN _itemlocSeries;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION fixporeject(integer)
+  OWNER TO admin;
+  
+  
+SELECT fixporeject(poreject_id)  FROM poreject WHERE poreject_id <= 68  AND poreject_id  >= 56; 
\ No newline at end of file
diff --git a/pgsql/old/apaging.sql b/pgsql/old/apaging.sql
new file mode 100644 (file)
index 0000000..2ac3a5f
--- /dev/null
@@ -0,0 +1,113 @@
+-- Function: apaging(date, boolean)
+
+-- DROP FUNCTION apaging(date, boolean);
+
+CREATE OR REPLACE FUNCTION apaging(date, boolean)
+  RETURNS SETOF apaging AS
+$BODY$
+DECLARE
+  pAsOfDate ALIAS FOR $1;
+  pUseDocDate ALIAS FOR $2;
+  _row apaging%ROWTYPE;
+  _x RECORD;
+  _returnVal INTEGER;
+  _asOfDate DATE;
+BEGIN
+
+  _asOfDate := COALESCE(pAsOfDate,current_date);
+
+  FOR _x IN
+        SELECT
+        --report uses currency rate snapshot to convert all amounts to base based on apopen_docdate to ensure the same exchange rate
+
+        --today and greater base:
+        CASE WHEN((apopen_duedate >= DATE(_asOfDate)))
+        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS cur_val,
+
+        --0 to 30 base
+        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-30) AND (apopen_duedate < DATE(_asOfDate)))
+        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS thirty_val,
+
+        --30-60 base
+        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-60) AND (apopen_duedate < DATE(_asOfDate) - 30 ))
+        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS sixty_val,
+
+        --60-90 base
+        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-90) AND (apopen_duedate < DATE(_asOfDate) - 60))
+        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS ninety_val,
+
+        --greater than 90 base:
+        CASE WHEN((apopen_duedate > DATE(_asOfDate)-10000) AND (apopen_duedate < DATE(_asOfDate) - 90))
+        THEN (((apopen_amount-apopen_paid + COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS plus_val,
+
+        --total amount base:
+        CASE WHEN((apopen_duedate > DATE(_asOfDate)-10000))
+        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
+        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS total_val,
+
+        --AR Open Amount base
+        CASE WHEN apopen_doctype IN ('C', 'R') 
+        THEN (apopen_amount * -1) / apopen_curr_rate
+        ELSE apopen_amount / apopen_curr_rate END AS apopen_amount,
+        
+        apopen_docdate,
+        apopen_duedate,
+        apopen_ponumber,
+        apopen_invcnumber,
+        apopen_docnumber,
+        apopen_doctype,
+        vend_id,
+        vend_name,
+        vend_number,
+        vend_vendtype_id,
+        vendtype_code,
+        terms_descrip
+
+        FROM vendinfo, vendtype, apopen
+          LEFT OUTER JOIN terms ON (apopen_terms_id=terms_id)
+          LEFT OUTER JOIN apapply ON (((apopen_id=apapply_target_apopen_id)
+                                    OR (apopen_id=apapply_source_apopen_id))
+                                   AND (apapply_postdate >_asOfDate))
+        WHERE ( (apopen_vend_id = vend_id)
+        AND (vend_vendtype_id=vendtype_id)
+        AND (CASE WHEN (pUseDocDate) THEN apopen_docdate ELSE apopen_distdate END <= _asOfDate)
+        AND (COALESCE(apopen_closedate,_asOfDate+1)>_asOfDate) )
+        GROUP BY apopen_id,apopen_docdate,apopen_duedate,apopen_ponumber, apopen_invcnumber, apopen_docnumber,apopen_doctype,apopen_paid,
+                 apopen_curr_id,apopen_amount,vend_id,vend_name,vend_number,vend_vendtype_id,vendtype_code,terms_descrip,
+                 apopen_curr_rate
+        ORDER BY vend_number, apopen_duedate
+  LOOP
+        _row.apaging_docdate := _x.apopen_docdate;
+        _row.apaging_duedate := _x.apopen_duedate;
+        _row.apaging_ponumber := _x.apopen_ponumber;
+        _row.apaging_invcnumber := _x.apopen_invcnumber;
+        _row.apaging_docnumber := _x.apopen_docnumber;
+        _row.apaging_doctype := _x.apopen_doctype;
+        _row.apaging_vend_id := _x.vend_id;
+        _row.apaging_vend_number := _x.vend_number;
+        _row.apaging_vend_name := _x.vend_name;
+        _row.apaging_vend_vendtype_id := _x.vend_vendtype_id;
+        _row.apaging_vendtype_code := _x.vendtype_code;
+        _row.apaging_terms_descrip := _x.terms_descrip;
+        _row.apaging_apopen_amount := _x.apopen_amount;
+        _row.apaging_cur_val := _x.cur_val;
+        _row.apaging_thirty_val := _x.thirty_val;
+        _row.apaging_sixty_val := _x.sixty_val;
+        _row.apaging_ninety_val := _x.ninety_val;
+        _row.apaging_plus_val := _x.plus_val;
+        _row.apaging_total_val := _x.total_val;
+        RETURN NEXT _row;
+  END LOOP;
+  RETURN;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100
+  ROWS 1000;
+ALTER FUNCTION apaging(date, boolean)
+  OWNER TO admin;
diff --git a/pgsql/old/api-functions-insertsalesline.sql b/pgsql/old/api-functions-insertsalesline.sql
new file mode 100644 (file)
index 0000000..28f12de
--- /dev/null
@@ -0,0 +1,108 @@
+-- Function: insertsalesline(api.salesline)
+
+-- DROP FUNCTION insertsalesline(api.salesline);
+
+CREATE OR REPLACE FUNCTION insertsalesline(api.salesline)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  pNEW ALIAS FOR $1;
+  _r RECORD;
+
+BEGIN
+
+  IF (NOT EXISTS (SELECT cohead_id FROM cohead WHERE cohead_number=pNEW.order_number)) THEN
+    RAISE EXCEPTION 'Function insertSalesLine failed because Sales Order % not found', pNEW.order_number;
+  END IF;
+
+  IF (NOT EXISTS (SELECT item_id FROM item WHERE item_number=pNEW.item_number)) THEN
+    RAISE EXCEPTION 'Function insertSalesLine failed because Item Number % not found', pNEW.item_number;
+  END IF;
+
+  SELECT * INTO _r
+  FROM cohead, itemsite, item, whsinfo
+  WHERE ((cohead_number=pNEW.order_number)
+  AND (itemsite_warehous_id=warehous_id
+  AND (itemsite_item_id=item_id)
+  AND (itemsite_active)
+  AND (item_number=pNEW.item_number)
+  AND (warehous_active)
+  AND (warehous_id=COALESCE(getWarehousId(pNEW.sold_from_site,'ALL'),cohead_warehous_id,fetchprefwarehousid()))));
+
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Function insertSalesLine failed with unknown failure to retrieve Sales Order';
+  END IF;
+
+  INSERT INTO coitem (
+    coitem_cohead_id,
+    coitem_linenumber,
+    coitem_itemsite_id,
+    coitem_status,
+    coitem_scheddate,
+    coitem_promdate,
+    coitem_qtyord,
+    coitem_qty_uom_id,
+    coitem_qty_invuomratio,
+    coitem_qtyshipped,
+    coitem_unitcost,
+    coitem_price,
+    coitem_price_uom_id,
+    coitem_price_invuomratio,
+    coitem_custprice,
+    coitem_order_id,
+    coitem_memo,
+    coitem_imported,
+    coitem_qtyreturned,
+    coitem_custpn,
+    coitem_order_type,
+    coitem_substitute_item_id,
+    coitem_prcost,
+    coitem_taxtype_id,
+    coitem_warranty,
+    coitem_cos_accnt_id)
+  VALUES (
+    _r.cohead_id,
+    pNEW.line_number::INTEGER,
+    _r.itemsite_id,
+    pNEW.status,
+    pNEW.scheduled_date,
+    pNEW.promise_date,
+    pNEW.qty_ordered,
+    COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),
+    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),_r.item_inv_uom_id),
+    0,
+    itemcost_dispense(_r.item_id, _r.qty_ordered),
+    COALESCE(pNEW.net_unit_price,itemPrice(_r.item_id,_r.cohead_cust_id,
+             _r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate)),
+    COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),
+    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),_r.item_price_uom_id),
+    itemPrice(_r.item_id,_r.cohead_cust_id,_r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate),
+    -1,
+    pNEW.notes,
+    true,
+    0,
+    pNEW.customer_pn,
+    CASE
+      WHEN ((pNEW.create_order  AND (_r.item_type = 'M')) OR 
+           ((pNEW.create_order IS NULL) AND _r.itemsite_createwo)) THEN
+        'W'
+      WHEN ((pNEW.create_order AND (_r.item_type = 'P')) OR 
+           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopr)) THEN
+        'R'
+      WHEN ((pNEW.create_order AND (_r.item_type = 'P') AND (_r.itemsite_createsopo)) OR 
+           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopo)) THEN
+        'P'
+    END,
+    getitemid(pNEW.substitute_for),
+    pNEW.overwrite_po_price,
+    COALESCE(getTaxTypeId(pNEW.tax_type), getItemTaxType(_r.itemsite_item_id, _r.cohead_taxzone_id)),
+    pNEW.warranty,
+    getGlAccntId(pNEW.alternate_cos_account)
+    );
+
+  RETURN TRUE;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION insertsalesline(api.salesline) OWNER TO "admin";
diff --git a/pgsql/old/copyso.sql b/pgsql/old/copyso.sql
new file mode 100644 (file)
index 0000000..2ae7868
--- /dev/null
@@ -0,0 +1,273 @@
+-- Function: copyso(integer, date)
+
+-- DROP FUNCTION copyso(integer, date);
+
+CREATE OR REPLACE FUNCTION copyso(integer, date)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pSoheadid ALIAS FOR $1;
+  pSchedDate ALIAS FOR $2;
+  _soheadid INTEGER;
+
+BEGIN
+
+  SELECT NEXTVAL('cohead_cohead_id_seq') INTO _soheadid;
+
+  INSERT INTO cohead
+  ( cohead_id,
+    cohead_number,
+    cohead_cust_id,
+    cohead_custponumber,
+    cohead_type,
+    cohead_orderdate,
+    cohead_warehous_id,
+    cohead_shipto_id,
+    cohead_shiptoname,
+    cohead_shiptoaddress1,
+    cohead_shiptoaddress2,
+    cohead_shiptoaddress3,
+    cohead_shiptoaddress4,
+    cohead_shiptoaddress5,
+    cohead_salesrep_id,
+    cohead_terms_id,
+    cohead_origin,
+    cohead_fob,
+    cohead_shipvia,
+    cohead_shiptocity,
+    cohead_shiptostate,
+    cohead_shiptozipcode,
+    cohead_freight,
+    cohead_misc,
+    cohead_imported,
+    cohead_ordercomments,
+    cohead_shipcomments,
+    cohead_shiptophone,
+    cohead_shipchrg_id,
+    cohead_shipform_id,
+    cohead_billtoname,
+    cohead_billtoaddress1,
+    cohead_billtoaddress2,
+    cohead_billtoaddress3,
+    cohead_billtocity,
+    cohead_billtostate,
+    cohead_billtozipcode,
+    cohead_misc_accnt_id,
+    cohead_misc_descrip,
+    cohead_commission,
+    cohead_miscdate,
+    cohead_holdtype,
+    cohead_packdate,
+    cohead_prj_id,
+    cohead_wasquote,
+    cohead_lastupdated,
+    cohead_shipcomplete,
+    cohead_created,
+    cohead_creator,
+    cohead_quote_number,
+    cohead_billtocountry,
+    cohead_shiptocountry,
+    cohead_curr_id,
+    cohead_calcfreight,
+    cohead_shipto_cntct_id,
+    cohead_shipto_cntct_honorific,
+    cohead_shipto_cntct_first_name,
+    cohead_shipto_cntct_middle,
+    cohead_shipto_cntct_last_name,
+    cohead_shipto_cntct_suffix,
+    cohead_shipto_cntct_phone,
+    cohead_shipto_cntct_title,
+    cohead_shipto_cntct_fax,
+    cohead_shipto_cntct_email,
+    cohead_billto_cntct_id,
+    cohead_billto_cntct_honorific,
+    cohead_billto_cntct_first_name,
+    cohead_billto_cntct_middle,
+    cohead_billto_cntct_last_name,
+    cohead_billto_cntct_suffix,
+    cohead_billto_cntct_phone,
+    cohead_billto_cntct_title,
+    cohead_billto_cntct_fax,
+    cohead_billto_cntct_email,
+    cohead_taxzone_id,
+    cohead_taxtype_id,
+    cohead_ophead_id,
+    cohead_status )
+  SELECT
+    _soheadid,
+    fetchSoNumber(),
+    cohead_cust_id,
+    cohead_custponumber,
+    cohead_type,
+    CURRENT_DATE,
+    cohead_warehous_id,
+    cohead_shipto_id,
+    cohead_shiptoname,
+    cohead_shiptoaddress1,
+    cohead_shiptoaddress2,
+    cohead_shiptoaddress3,
+    cohead_shiptoaddress4,
+    cohead_shiptoaddress5,
+    cohead_salesrep_id,
+    cohead_terms_id,
+    cohead_origin,
+    cohead_fob,
+    cohead_shipvia,
+    cohead_shiptocity,
+    cohead_shiptostate,
+    cohead_shiptozipcode,
+    cohead_freight,
+    cohead_misc,
+    FALSE,
+    cohead_ordercomments,
+    cohead_shipcomments,
+    cohead_shiptophone,
+    cohead_shipchrg_id,
+    cohead_shipform_id,
+    cohead_billtoname,
+    cohead_billtoaddress1,
+    cohead_billtoaddress2,
+    cohead_billtoaddress3,
+    cohead_billtocity,
+    cohead_billtostate,
+    cohead_billtozipcode,
+    cohead_misc_accnt_id,
+    cohead_misc_descrip,
+    cohead_commission,
+    cohead_miscdate,
+    cohead_holdtype,
+    COALESCE(pSchedDate, cohead_packdate),
+    cohead_prj_id,
+    FALSE,
+    cohead_lastupdated,
+    cohead_shipcomplete,
+    NULL,
+    CURRENT_USER,
+    NULL,
+    cohead_billtocountry,
+    cohead_shiptocountry,
+    cohead_curr_id,
+    cohead_calcfreight,
+    cohead_shipto_cntct_id,
+    cohead_shipto_cntct_honorific,
+    cohead_shipto_cntct_first_name,
+    cohead_shipto_cntct_middle,
+    cohead_shipto_cntct_last_name,
+    cohead_shipto_cntct_suffix,
+    cohead_shipto_cntct_phone,
+    cohead_shipto_cntct_title,
+    cohead_shipto_cntct_fax,
+    cohead_shipto_cntct_email,
+    cohead_billto_cntct_id,
+    cohead_billto_cntct_honorific,
+    cohead_billto_cntct_first_name,
+    cohead_billto_cntct_middle,
+    cohead_billto_cntct_last_name,
+    cohead_billto_cntct_suffix,
+    cohead_billto_cntct_phone,
+    cohead_billto_cntct_title,
+    cohead_billto_cntct_fax,
+    cohead_billto_cntct_email,
+    cohead_taxzone_id,
+    cohead_taxtype_id,
+    cohead_ophead_id,
+    cohead_status
+  FROM cohead
+  WHERE (cohead_id=pSoheadid);
+
+  INSERT INTO coitem
+  ( coitem_cohead_id,
+    coitem_linenumber,
+    coitem_itemsite_id,
+    coitem_status,
+    coitem_scheddate,
+    coitem_promdate,
+    coitem_qtyord,
+    coitem_unitcost,
+    coitem_price,
+    coitem_custprice,
+    coitem_qtyshipped,
+    coitem_order_id,
+    coitem_memo,
+    coitem_imported,
+    coitem_qtyreturned,
+    coitem_closedate,
+    coitem_custpn,
+    coitem_order_type,
+    coitem_close_username,
+--    coitem_lastupdated,
+    coitem_substitute_item_id,
+    coitem_created,
+    coitem_creator,
+    coitem_prcost,
+    coitem_qty_uom_id,
+    coitem_qty_invuomratio,
+    coitem_price_uom_id,
+    coitem_price_invuomratio,
+    coitem_warranty,
+    coitem_cos_accnt_id,
+    coitem_qtyreserved,
+    coitem_subnumber,
+    coitem_firm,
+    coitem_taxtype_id )
+  SELECT
+    _soheadid,
+    coitem_linenumber,
+    coitem_itemsite_id,
+    'O',
+    COALESCE(pSchedDate, coitem_scheddate),
+    coitem_promdate,
+    coitem_qtyord,
+    itemcost_dispense(itemsite_item_id, coitem_qtyord),
+    coitem_price,
+    coitem_custprice,
+    0.0,
+    -1,
+    coitem_memo,
+    FALSE,
+    0.0,
+    NULL,
+    coitem_custpn,
+    coitem_order_type,
+    NULL,
+--    NULL,
+    coitem_substitute_item_id,
+    NULL,
+    CURRENT_USER,
+    coitem_prcost,
+    coitem_qty_uom_id,
+    coitem_qty_invuomratio,
+    coitem_price_uom_id,
+    coitem_price_invuomratio,
+    coitem_warranty,
+    coitem_cos_accnt_id,
+    0.0,
+    coitem_subnumber,
+    coitem_firm,
+    coitem_taxtype_id
+  FROM coitem, itemsite
+  WHERE ( (coitem_itemsite_id=itemsite_id)
+   AND (coitem_status <> 'X')
+   AND (coitem_cohead_id=pSoheadid)
+   AND (coitem_subnumber = 0) );
+
+  INSERT INTO charass
+        (charass_target_type, charass_target_id,
+         charass_char_id, charass_value)
+  SELECT charass_target_type, b.coitem_id,
+         charass_char_id, charass_value
+    FROM coitem a, charass, coitem b
+   WHERE ((charass_target_type='SI')
+     AND  (charass_target_id=a.coitem_id)
+     AND  (a.coitem_cohead_id=pSoheadid)
+     AND  (b.coitem_cohead_id=_soheadid)
+     AND  (a.coitem_linenumber=b.coitem_linenumber)
+     AND  (a.coitem_subnumber=b.coitem_subnumber));
+
+  RETURN _soheadid;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION copyso(integer, date) OWNER TO "admin";
diff --git a/pgsql/old/distributeitemlocseries.sql b/pgsql/old/distributeitemlocseries.sql
new file mode 100644 (file)
index 0000000..43d0bde
--- /dev/null
@@ -0,0 +1,207 @@
+-- Function: distributeitemlocseries(integer)
+
+-- DROP FUNCTION distributeitemlocseries(integer);
+
+CREATE OR REPLACE FUNCTION distributeitemlocseries(integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemlocSeries   ALIAS FOR $1;
+  _distCounter     INTEGER;
+  _itemlocdist     RECORD;
+  _itemlocid       INTEGER;
+  _invhistid       INTEGER;
+  _check           BOOLEAN;
+  _debug           BOOLEAN := true;
+BEGIN
+
+  IF (_debug) THEN
+    RAISE NOTICE 'distributeItemlocSeries, series=%', pItemlocSeries;
+  END IF;
+
+  _distCounter := 0;
+
+--  March through all of the itemlocdists for pItemlocSeries
+  FOR _itemlocdist IN SELECT itemlocdist_id AS itemlocdistid,
+                             itemlocdist_source_type AS type,
+                             itemlocdist_source_id AS sourceid,
+                             itemlocdist_qty AS qty,
+                             itemlocdist_itemsite_id AS itemsiteid,
+                             itemsite_freeze,
+                             itemlocdist_invhist_id AS invhistid,
+                             itemlocdist_ls_id AS lotserialid,
+                             itemlocdist_expiration AS expiration,
+                             itemlocdist_flush,
+                             itemlocdist_warranty AS warranty,
+                             itemlocdist_series AS series
+                      FROM itemlocdist, itemsite
+                      WHERE ( (itemlocdist_itemsite_id=itemsite_id)
+                       AND (itemlocdist_series=pItemlocSeries) )
+                      ORDER BY itemlocdist_flush DESC LOOP
+
+    _distCounter := _distCounter + 1;
+    IF (_debug) THEN
+      RAISE NOTICE 'itemlocdist loop %', _distCounter;
+      RAISE NOTICE 'itemlocdistid=%', _itemlocdist.itemlocdistid;
+      RAISE NOTICE 'type=%', _itemlocdist.type;
+      RAISE NOTICE 'sourceid=%', _itemlocdist.sourceid;
+      RAISE NOTICE 'qty=%', _itemlocdist.qty;
+      RAISE NOTICE 'itemsiteid=%', _itemlocdist.itemsiteid;
+      RAISE NOTICE 'freeze=%', _itemlocdist.itemsite_freeze;
+      RAISE NOTICE 'invhistid=%', _itemlocdist.invhistid;
+      RAISE NOTICE 'lotserialid=%', _itemlocdist.lotserialid;
+      RAISE NOTICE 'expiration=%', _itemlocdist.expiration;
+      RAISE NOTICE 'flush=%', _itemlocdist.itemlocdist_flush;
+      RAISE NOTICE 'warranty=%', _itemlocdist.warranty;
+    END IF;
+
+--  Commit invhist to itemsite
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+    PERFORM postInvHist(_itemlocdist.invhistid);
+    END IF;
+
+--  Mark the invhist tuple for the itemlocdist in question as having detail
+    UPDATE invhist
+    SET invhist_hasdetail=TRUE
+    WHERE ( (NOT invhist_hasdetail)
+     AND (invhist_id=_itemlocdist.invhistid) );
+
+--  If this itemlocdist is a flush, write a invdetail tuple that records the empty
+    IF (_itemlocdist.itemlocdist_flush) THEN
+      INSERT INTO invdetail
+      ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+        invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration,
+        invdetail_warrpurc )
+      SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
+             (itemloc_qty * -1), itemloc_qty, 0, itemloc_expiration, 
+             _itemlocdist.warranty
+      FROM itemloc
+      WHERE ( (itemloc_qty <> 0)
+       AND (itemloc_id=_itemlocdist.sourceid) );
+
+--  Delete the flushed itemloc if its parent itemsite is not frozen
+      IF (NOT _itemlocdist.itemsite_freeze) THEN
+        DELETE FROM itemloc
+        WHERE (itemloc_id=_itemlocdist.sourceid);
+      END IF;
+
+    ELSE
+--  If this is a location type distribution, check to see if the target itemloc
+--  already exists
+      IF (_itemlocdist.type = 'L') THEN
+        SELECT itemloc_id INTO _itemlocid
+        FROM itemloc
+        WHERE ( (itemloc_itemsite_id=_itemlocdist.itemsiteid)
+         AND (itemloc_location_id=_itemlocdist.sourceid)
+         AND (COALESCE(itemloc_ls_id,-1)=COALESCE(_itemlocdist.lotserialid,-1))
+         AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_itemlocdist.expiration,endOfTime()))
+         AND (COALESCE(itemloc_warrpurc,endoftime())=COALESCE(_itemlocdist.warranty,endoftime())) );
+
+--  Nope, create it
+        IF (NOT FOUND) THEN
+          SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
+
+          INSERT INTO itemloc
+          ( itemloc_id, itemloc_itemsite_id,
+            itemloc_location_id, itemloc_qty,
+            itemloc_ls_id, itemloc_expiration,
+            itemloc_warrpurc )
+          VALUES
+          ( _itemlocid, _itemlocdist.itemsiteid,
+            _itemlocdist.sourceid, 0,
+            _itemlocdist.lotserialid, _itemlocdist.expiration,
+            _itemlocdist.warranty );
+        END IF;
+
+      ELSE
+        _itemlocid = _itemlocdist.sourceid;
+
+        IF (_itemlocid IS NOT NULL AND (SELECT count(itemloc_id) = 0 FROM itemloc WHERE itemloc_id=_itemlocid)) THEN
+          RAISE EXCEPTION 'No record to distribute against. Someone else may have already distributed this record.';
+        END IF;
+      END IF;
+
+--  Record the invdetail
+      INSERT INTO invdetail
+      (invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+       invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration,
+       invdetail_warrpurc)
+      SELECT _itemlocdist.invhistid, itemloc_location_id, _itemlocdist.lotserialid,
+             _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
+             itemloc_expiration,_itemlocdist.warranty
+      FROM itemloc
+      WHERE (itemloc_id=_itemlocid);
+
+--  Update the itemloc_qty if its parent itemsite is not frozen
+      IF (NOT _itemlocdist.itemsite_freeze) THEN
+        UPDATE itemloc
+        SET itemloc_qty = (itemloc_qty + _itemlocdist.qty)
+        WHERE (itemloc_id=_itemlocid);
+      END IF;
+
+--  Adjust QOH if this itemlocdist is to/from a non-netable location
+      IF ( SELECT (NOT location_netable)
+           FROM itemloc, location
+           WHERE ( (itemloc_location_id=location_id)
+            AND (itemloc_id=_itemlocid) ) ) THEN
+
+--  Record the netable->non-netable (or visaveras) invhist
+        SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
+        INSERT INTO invhist
+        ( invhist_id, invhist_itemsite_id, 
+          invhist_transtype, invhist_invqty,
+          invhist_qoh_before, invhist_qoh_after,
+          invhist_docnumber, invhist_comments,
+          invhist_invuom, invhist_unitcost,
+          invhist_costmethod, invhist_value_before, invhist_value_after,
+          invhist_series ) 
+        SELECT _invhistid, itemsite_id, 
+               'NN', (_itemlocdist.qty * -1),
+               itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
+               invhist_docnumber, invhist_comments,
+               uom_name, stdCost(item_id),
+               itemsite_costmethod, itemsite_value,
+               (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
+                                                               ELSE itemcost_dispense(itemsite_item_id, _itemlocdist.qty)
+                                                          END)),
+               _itemlocdist.series
+        FROM item, itemsite, invhist, uom
+        WHERE ((itemsite_item_id=item_id)
+         AND (item_inv_uom_id=uom_id)
+         AND (itemsite_controlmethod <> 'N')
+         AND (itemsite_id=_itemlocdist.itemsiteid)
+         AND (invhist_id=_itemlocdist.invhistid));
+
+--  Adjust the parent itemsite
+        IF (NOT _itemlocdist.itemsite_freeze) THEN
+          UPDATE itemsite
+          SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
+              itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
+          FROM itemloc
+          WHERE ((itemloc_itemsite_id=itemsite_id)
+           AND (itemloc_id=_itemlocid));
+        END IF;
+      END IF;
+
+    END IF;
+
+--  If, after the distribution, the target itemloc_qty = 0, delete the itemloc
+--  if its parent itemsite is not frozen
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+      DELETE FROM itemloc
+      WHERE ( (itemloc_qty=0)
+       AND (itemloc_id=_itemlocid) );
+    END IF;
+
+  END LOOP;
+
+  DELETE FROM itemlocdist
+  WHERE (itemlocdist_series=pItemlocSeries);
+
+  RETURN _distCounter;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION distributeitemlocseries(integer) OWNER TO "admin";
diff --git a/pgsql/old/distributetolocations.sql b/pgsql/old/distributetolocations.sql
new file mode 100644 (file)
index 0000000..e49bf8f
--- /dev/null
@@ -0,0 +1,234 @@
+-- Function: distributetolocations(integer)
+
+-- DROP FUNCTION distributetolocations(integer);
+
+CREATE OR REPLACE FUNCTION distributetolocations(integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemlocdistid ALIAS FOR $1;
+  _distCounter INTEGER;
+  _itemlocdist RECORD;
+  _itemlocid INTEGER;
+  _runningQty NUMERIC;
+  _tmp RECORD;
+
+BEGIN
+
+  _distCounter := 0;
+  _runningQty  := 0;
+
+-- A scenario can occur where two people try to post distributions
+-- to the same itemsite against two or more lot/serial/mlc locations
+-- leading to a deadlock. This line tries to prevent that by locking
+-- ahead of time all the itemsites that the transaction will need
+-- before any of the other tables are locked individually.
+  SELECT itemsite_id
+    INTO _tmp
+    FROM itemsite
+   WHERE(itemsite_id in (SELECT DISTINCT itemlocdist_itemsite_id
+                           FROM itemlocdist
+                          WHERE(itemlocdist_id=pItemlocdistid)))
+     FOR UPDATE;
+
+--  March through all of the itemlocdist owned by the passed parent itemlocdist
+  FOR _itemlocdist IN SELECT c.itemlocdist_id AS itemlocdistid,
+                             c.itemlocdist_source_type AS type,
+                             c.itemlocdist_source_id AS sourceid,
+                             c.itemlocdist_qty AS qty,
+                             p.itemlocdist_itemsite_id AS itemsiteid,
+                             itemsite_freeze,
+                             p.itemlocdist_invhist_id AS invhistid,
+                             p.itemlocdist_ls_id AS lotserialid,
+                             p.itemlocdist_expiration AS expiration,
+                             p.itemlocdist_warranty AS warranty,
+                             p.itemlocdist_order_type AS ordertype,
+                             p.itemlocdist_order_id AS orderid,
+                             p.itemlocdist_series AS series
+                      FROM itemlocdist AS c, itemlocdist AS p, itemsite
+                      WHERE ( (c.itemlocdist_itemlocdist_id=p.itemlocdist_id)
+                       AND (p.itemlocdist_source_type='O')
+                       AND (p.itemlocdist_itemsite_id=itemsite_id)
+                       AND (p.itemlocdist_id=pItemlocdistid) ) LOOP
+
+    _distCounter := _distCounter + 1;
+
+--  If the target for this itemlocdist is a location, check to see if the
+--  required itemloc already exists
+    IF (_itemlocdist.type = 'L') THEN
+      SELECT itemloc_id INTO _itemlocid
+      FROM itemloc
+      WHERE ( (itemloc_itemsite_id=_itemlocdist.itemsiteid)
+       AND (itemloc_location_id=_itemlocdist.sourceid)
+       AND (COALESCE(itemloc_ls_id, -1)=COALESCE(_itemlocdist.lotserialid, -1))
+       AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_itemlocdist.expiration,endOfTime()))
+       AND (COALESCE(itemloc_warrpurc,endoftime())=COALESCE(_itemlocdist.warranty,endoftime())) );
+
+--  Nope, make it
+      IF (NOT FOUND) THEN
+        SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
+        INSERT INTO itemloc
+        ( itemloc_id, itemloc_itemsite_id,
+          itemloc_location_id, itemloc_qty,
+          itemloc_ls_id, itemloc_expiration,
+          itemloc_warrpurc )
+        VALUES
+        ( _itemlocid, _itemlocdist.itemsiteid,
+          _itemlocdist.sourceid, 0,
+          _itemlocdist.lotserialid, _itemlocdist.expiration,
+          _itemlocdist.warranty );
+      END IF;
+
+    ELSE
+--  Yep, cache it
+      _itemlocid = _itemlocdist.sourceid;
+
+      IF (_itemlocid IS NOT NULL AND (SELECT count(itemloc_id) = 0 FROM itemloc WHERE itemloc_id=_itemlocid)) THEN
+        RAISE EXCEPTION 'No record to distribute against. Someone else may have already distributed this record.';
+      END IF;
+    END IF;
+
+--  Record the invdetail for this itemlocdist
+    INSERT INTO invdetail
+    ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+      invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration, 
+      invdetail_warrpurc )
+    SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
+           _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
+           itemloc_expiration,_itemlocdist.warranty
+    FROM itemloc
+    WHERE (itemloc_id=_itemlocid);
+
+--  Update the parent invhist to indicate that it has invdetail records
+    UPDATE invhist
+    SET invhist_hasdetail=TRUE
+    WHERE ((invhist_hasdetail=FALSE)
+     AND (invhist_id=_itemlocdist.invhistid));
+
+--  Update the itemloc_qty if its parent itemsite is not frozen
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+      UPDATE itemloc
+      SET itemloc_qty = (itemloc_qty + _itemlocdist.qty)
+      WHERE (itemloc_id=_itemlocid);
+
+      PERFORM postInvHist(_itemlocdist.invhistid);
+
+--  Handle reservation data
+      IF ( (SELECT fetchMetricBool('EnableSOReservationsByLocation')) AND
+           (_itemlocdist.qty < 0) ) THEN
+
+--  If a shipment on a sales order, record reservation change before updating
+--  so it can be reversed later if necessary
+        IF (_itemlocdist.ordertype = 'SO') THEN
+          INSERT INTO shipitemlocrsrv
+          SELECT nextval('shipitemlocrsrv_shipitemlocrsrv_id_seq'),
+            shipitem_id, itemloc_itemsite_id, itemloc_location_id,
+            itemloc_ls_id, itemloc_expiration, itemloc_warrpurc,
+            least(_itemlocdist.qty, itemlocrsrv_qty)
+          FROM shipitem, itemloc
+            JOIN itemlocrsrv ON (itemloc_id=itemlocrsrv_itemloc_id)
+          WHERE ( (shipitem_invhist_id=_itemlocdist.invhistid)
+            AND   (itemloc_id=_itemlocid)
+            AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+            AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
+        END IF;
+
+--  Update the itemloc reservation
+        UPDATE itemlocrsrv
+        SET itemlocrsrv_qty = (itemlocrsrv_qty + _itemlocdist.qty)
+        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
+          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+          AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
+          
+--  Delete reservation if fully distributed
+        DELETE FROM itemlocrsrv
+        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
+          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+          AND   (itemlocrsrv_source_id=_itemlocdist.orderid)
+          AND   (itemlocrsrv_qty=0) );
+      END IF;
+    END IF;
+
+--  Adjust QOH if this itemlocdist is to/from a non-netable location
+    IF ( SELECT (NOT location_netable)
+         FROM itemloc, location
+         WHERE ((itemloc_location_id=location_id)
+          AND (itemloc_id=_itemlocid)) ) THEN
+
+--  Record the invhist record for the netable->non-netable (or visaversa)
+      INSERT INTO invhist
+      ( invhist_itemsite_id,
+        invhist_transtype, invhist_invqty,
+        invhist_qoh_before, invhist_qoh_after,
+        invhist_docnumber, invhist_comments,
+        invhist_invuom, invhist_unitcost,
+        invhist_costmethod, invhist_value_before, invhist_value_after,
+        invhist_series )
+      SELECT itemsite_id,
+             'NN', (_itemlocdist.qty * -1),
+             itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
+             invhist_docnumber, invhist_comments,
+             uom_name, stdCost(item_id),
+             itemsite_costmethod, itemsite_value,
+             (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
+                                                             ELSE itemcost_dispense(itemsite_item_id, _itemlocdist.qty)
+                                                        END)),
+             _itemlocdist.series
+      FROM item, itemsite, invhist, uom
+      WHERE ( (itemsite_item_id=item_id)
+       AND (item_inv_uom_id=uom_id)
+       AND (itemsite_controlmethod <> 'N')
+       AND (itemsite_id=_itemlocdist.itemsiteid)
+       AND (invhist_id=_itemlocdist.invhistid) );
+
+--  Update the itemsite_qoh
+      IF (NOT _itemlocdist.itemsite_freeze) THEN
+        UPDATE itemsite
+        SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
+            itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
+        FROM itemloc
+        WHERE ((itemloc_itemsite_id=itemsite_id)
+         AND (itemloc_id=_itemlocid));
+      END IF;
+    END IF;
+
+--  Cache the running qty.
+    _runningQty := _runningQty + _itemlocdist.qty;
+
+--  Dene with the child itemlocdist, so delete it
+    DELETE FROM itemlocdist
+    WHERE (itemlocdist_id=_itemlocdist.itemlocdistid);
+
+--  If the target itemloc is now at qty=0, delete it if its parent
+--  itemsite is not frozen
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+      DELETE FROM itemloc
+      WHERE ( (itemloc_qty=0)
+       AND (itemloc_id=_itemlocid) );
+    END IF;
+
+  END LOOP;
+
+--  If the running qty for the detailed distributions is the same as the
+--  total qty to distribute indicated by the parent itemlocdist, then the
+--  parent itemlocdist has been fully distributed and should be deleted.
+  IF ( ( SELECT itemlocdist_qty
+         FROM itemlocdist
+         WHERE (itemlocdist_id=pItemlocdistid) ) = _runningQty) THEN
+    DELETE FROM itemlocdist
+    WHERE (itemlocdist_id=pItemlocdistid);
+  ELSE
+--  There is still some more qty to distribute in the parent itemlocdist.
+--  Update the qty to distribute with the qty that has been distributed.
+    UPDATE itemlocdist
+    SET itemlocdist_qty = (itemlocdist_qty - _runningQty)
+    WHERE (itemlocdist_id=pItemlocdistid);
+  END IF;
+
+  RETURN _distCounter;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION distributetolocations(integer) OWNER TO "admin";
diff --git a/pgsql/old/distributetolocations.sql.disabled b/pgsql/old/distributetolocations.sql.disabled
new file mode 100644 (file)
index 0000000..e49bf8f
--- /dev/null
@@ -0,0 +1,234 @@
+-- Function: distributetolocations(integer)
+
+-- DROP FUNCTION distributetolocations(integer);
+
+CREATE OR REPLACE FUNCTION distributetolocations(integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemlocdistid ALIAS FOR $1;
+  _distCounter INTEGER;
+  _itemlocdist RECORD;
+  _itemlocid INTEGER;
+  _runningQty NUMERIC;
+  _tmp RECORD;
+
+BEGIN
+
+  _distCounter := 0;
+  _runningQty  := 0;
+
+-- A scenario can occur where two people try to post distributions
+-- to the same itemsite against two or more lot/serial/mlc locations
+-- leading to a deadlock. This line tries to prevent that by locking
+-- ahead of time all the itemsites that the transaction will need
+-- before any of the other tables are locked individually.
+  SELECT itemsite_id
+    INTO _tmp
+    FROM itemsite
+   WHERE(itemsite_id in (SELECT DISTINCT itemlocdist_itemsite_id
+                           FROM itemlocdist
+                          WHERE(itemlocdist_id=pItemlocdistid)))
+     FOR UPDATE;
+
+--  March through all of the itemlocdist owned by the passed parent itemlocdist
+  FOR _itemlocdist IN SELECT c.itemlocdist_id AS itemlocdistid,
+                             c.itemlocdist_source_type AS type,
+                             c.itemlocdist_source_id AS sourceid,
+                             c.itemlocdist_qty AS qty,
+                             p.itemlocdist_itemsite_id AS itemsiteid,
+                             itemsite_freeze,
+                             p.itemlocdist_invhist_id AS invhistid,
+                             p.itemlocdist_ls_id AS lotserialid,
+                             p.itemlocdist_expiration AS expiration,
+                             p.itemlocdist_warranty AS warranty,
+                             p.itemlocdist_order_type AS ordertype,
+                             p.itemlocdist_order_id AS orderid,
+                             p.itemlocdist_series AS series
+                      FROM itemlocdist AS c, itemlocdist AS p, itemsite
+                      WHERE ( (c.itemlocdist_itemlocdist_id=p.itemlocdist_id)
+                       AND (p.itemlocdist_source_type='O')
+                       AND (p.itemlocdist_itemsite_id=itemsite_id)
+                       AND (p.itemlocdist_id=pItemlocdistid) ) LOOP
+
+    _distCounter := _distCounter + 1;
+
+--  If the target for this itemlocdist is a location, check to see if the
+--  required itemloc already exists
+    IF (_itemlocdist.type = 'L') THEN
+      SELECT itemloc_id INTO _itemlocid
+      FROM itemloc
+      WHERE ( (itemloc_itemsite_id=_itemlocdist.itemsiteid)
+       AND (itemloc_location_id=_itemlocdist.sourceid)
+       AND (COALESCE(itemloc_ls_id, -1)=COALESCE(_itemlocdist.lotserialid, -1))
+       AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_itemlocdist.expiration,endOfTime()))
+       AND (COALESCE(itemloc_warrpurc,endoftime())=COALESCE(_itemlocdist.warranty,endoftime())) );
+
+--  Nope, make it
+      IF (NOT FOUND) THEN
+        SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
+        INSERT INTO itemloc
+        ( itemloc_id, itemloc_itemsite_id,
+          itemloc_location_id, itemloc_qty,
+          itemloc_ls_id, itemloc_expiration,
+          itemloc_warrpurc )
+        VALUES
+        ( _itemlocid, _itemlocdist.itemsiteid,
+          _itemlocdist.sourceid, 0,
+          _itemlocdist.lotserialid, _itemlocdist.expiration,
+          _itemlocdist.warranty );
+      END IF;
+
+    ELSE
+--  Yep, cache it
+      _itemlocid = _itemlocdist.sourceid;
+
+      IF (_itemlocid IS NOT NULL AND (SELECT count(itemloc_id) = 0 FROM itemloc WHERE itemloc_id=_itemlocid)) THEN
+        RAISE EXCEPTION 'No record to distribute against. Someone else may have already distributed this record.';
+      END IF;
+    END IF;
+
+--  Record the invdetail for this itemlocdist
+    INSERT INTO invdetail
+    ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+      invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration, 
+      invdetail_warrpurc )
+    SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
+           _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
+           itemloc_expiration,_itemlocdist.warranty
+    FROM itemloc
+    WHERE (itemloc_id=_itemlocid);
+
+--  Update the parent invhist to indicate that it has invdetail records
+    UPDATE invhist
+    SET invhist_hasdetail=TRUE
+    WHERE ((invhist_hasdetail=FALSE)
+     AND (invhist_id=_itemlocdist.invhistid));
+
+--  Update the itemloc_qty if its parent itemsite is not frozen
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+      UPDATE itemloc
+      SET itemloc_qty = (itemloc_qty + _itemlocdist.qty)
+      WHERE (itemloc_id=_itemlocid);
+
+      PERFORM postInvHist(_itemlocdist.invhistid);
+
+--  Handle reservation data
+      IF ( (SELECT fetchMetricBool('EnableSOReservationsByLocation')) AND
+           (_itemlocdist.qty < 0) ) THEN
+
+--  If a shipment on a sales order, record reservation change before updating
+--  so it can be reversed later if necessary
+        IF (_itemlocdist.ordertype = 'SO') THEN
+          INSERT INTO shipitemlocrsrv
+          SELECT nextval('shipitemlocrsrv_shipitemlocrsrv_id_seq'),
+            shipitem_id, itemloc_itemsite_id, itemloc_location_id,
+            itemloc_ls_id, itemloc_expiration, itemloc_warrpurc,
+            least(_itemlocdist.qty, itemlocrsrv_qty)
+          FROM shipitem, itemloc
+            JOIN itemlocrsrv ON (itemloc_id=itemlocrsrv_itemloc_id)
+          WHERE ( (shipitem_invhist_id=_itemlocdist.invhistid)
+            AND   (itemloc_id=_itemlocid)
+            AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+            AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
+        END IF;
+
+--  Update the itemloc reservation
+        UPDATE itemlocrsrv
+        SET itemlocrsrv_qty = (itemlocrsrv_qty + _itemlocdist.qty)
+        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
+          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+          AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
+          
+--  Delete reservation if fully distributed
+        DELETE FROM itemlocrsrv
+        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
+          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
+          AND   (itemlocrsrv_source_id=_itemlocdist.orderid)
+          AND   (itemlocrsrv_qty=0) );
+      END IF;
+    END IF;
+
+--  Adjust QOH if this itemlocdist is to/from a non-netable location
+    IF ( SELECT (NOT location_netable)
+         FROM itemloc, location
+         WHERE ((itemloc_location_id=location_id)
+          AND (itemloc_id=_itemlocid)) ) THEN
+
+--  Record the invhist record for the netable->non-netable (or visaversa)
+      INSERT INTO invhist
+      ( invhist_itemsite_id,
+        invhist_transtype, invhist_invqty,
+        invhist_qoh_before, invhist_qoh_after,
+        invhist_docnumber, invhist_comments,
+        invhist_invuom, invhist_unitcost,
+        invhist_costmethod, invhist_value_before, invhist_value_after,
+        invhist_series )
+      SELECT itemsite_id,
+             'NN', (_itemlocdist.qty * -1),
+             itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
+             invhist_docnumber, invhist_comments,
+             uom_name, stdCost(item_id),
+             itemsite_costmethod, itemsite_value,
+             (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
+                                                             ELSE itemcost_dispense(itemsite_item_id, _itemlocdist.qty)
+                                                        END)),
+             _itemlocdist.series
+      FROM item, itemsite, invhist, uom
+      WHERE ( (itemsite_item_id=item_id)
+       AND (item_inv_uom_id=uom_id)
+       AND (itemsite_controlmethod <> 'N')
+       AND (itemsite_id=_itemlocdist.itemsiteid)
+       AND (invhist_id=_itemlocdist.invhistid) );
+
+--  Update the itemsite_qoh
+      IF (NOT _itemlocdist.itemsite_freeze) THEN
+        UPDATE itemsite
+        SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
+            itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
+        FROM itemloc
+        WHERE ((itemloc_itemsite_id=itemsite_id)
+         AND (itemloc_id=_itemlocid));
+      END IF;
+    END IF;
+
+--  Cache the running qty.
+    _runningQty := _runningQty + _itemlocdist.qty;
+
+--  Dene with the child itemlocdist, so delete it
+    DELETE FROM itemlocdist
+    WHERE (itemlocdist_id=_itemlocdist.itemlocdistid);
+
+--  If the target itemloc is now at qty=0, delete it if its parent
+--  itemsite is not frozen
+    IF (NOT _itemlocdist.itemsite_freeze) THEN
+      DELETE FROM itemloc
+      WHERE ( (itemloc_qty=0)
+       AND (itemloc_id=_itemlocid) );
+    END IF;
+
+  END LOOP;
+
+--  If the running qty for the detailed distributions is the same as the
+--  total qty to distribute indicated by the parent itemlocdist, then the
+--  parent itemlocdist has been fully distributed and should be deleted.
+  IF ( ( SELECT itemlocdist_qty
+         FROM itemlocdist
+         WHERE (itemlocdist_id=pItemlocdistid) ) = _runningQty) THEN
+    DELETE FROM itemlocdist
+    WHERE (itemlocdist_id=pItemlocdistid);
+  ELSE
+--  There is still some more qty to distribute in the parent itemlocdist.
+--  Update the qty to distribute with the qty that has been distributed.
+    UPDATE itemlocdist
+    SET itemlocdist_qty = (itemlocdist_qty - _runningQty)
+    WHERE (itemlocdist_id=pItemlocdistid);
+  END IF;
+
+  RETURN _distCounter;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION distributetolocations(integer) OWNER TO "admin";
diff --git a/pgsql/old/fifo-view.sql b/pgsql/old/fifo-view.sql
new file mode 100644 (file)
index 0000000..b6df84b
--- /dev/null
@@ -0,0 +1,339 @@
+-- View: invhist_buy
+
+CREATE OR REPLACE FUNCTION invhist_firstid(int, text, text)
+  RETURNS  int  AS
+$BODY$
+DECLARE
+  
+  i_itemsite ALIAS FOR $1;
+  i_order ALIAS FOR $2;
+  i_type  ALIAS FOR $3;
+  v_ret INT;
+   
+BEGIN
+    
+    SELECT invhist_id INTO v_ret
+            FROM
+                invhist
+            WHERE
+                invhist_itemsite_id = i_itemsite
+                AND
+                invhist_ordnumber = i_order
+                AND
+                invhist_transtype = i_type 
+            ORDER BY
+                invhist_id ASC
+            LIMIT 1 ;
+        
+    RETURN v_ret; 
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+  
+ALTER FUNCTION  invhist_firstid(int, text, text)
+  OWNER TO admin;
+  
+  
+  
+  
+CREATE OR REPLACE FUNCTION invhist_firstdate(int, text, text)
+  RETURNS timestamp with time zone  AS
+$BODY$
+DECLARE
+  
+  i_itemsite ALIAS FOR $1;
+  i_order ALIAS FOR $2;
+  i_type  ALIAS FOR $3;
+  v_ret  timestamp with time zone ;
+   
+BEGIN
+    
+    SELECT invhist_transdate INTO v_ret
+            FROM
+                invhist
+            WHERE
+                invhist_itemsite_id = i_itemsite
+                AND
+                invhist_ordnumber = i_order
+                AND
+                invhist_transtype = i_type 
+            ORDER BY
+                invhist_id ASC
+            LIMIT 1 ;
+        
+    RETURN v_ret; 
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invhist_firstdate(int, text, text)
+  OWNER TO admin;
+
+DROP VIEW invhist_buy ;
+-- buy is a mix of RP and +ve adjustments.
+CREATE OR REPLACE VIEW invhist_buy AS
+
+
+     SELECT
+        distinct(invhist_ordnumber)  AS ordernumber,
+        invhist_itemsite_id                             AS itemsite_id,
+        SUM(invhist_qoh_after - invhist_qoh_before)          AS qty,
+        SUM(invhist_value_after - invhist_value_before)    AS totalcost,
+        SUM(invhist_value_after - invhist_value_before)
+            / SUM(invhist_qoh_after - invhist_qoh_before)   AS unitcost,
+        'RP'                                        AS transtype ,
+        
+        invhist_firstid(invhist_itemsite_id, invhist_ordnumber, 'RP')
+                                                        AS invhist_id,
+                                                        
+        invhist_firstdate(invhist_itemsite_id, invhist_ordnumber, 'RP')
+                                                         AS transdate ,
+        0 AS qtybefore
+        
+    FROM
+        invhist
+    WHERE
+        invhist_transtype = 'RP'
+        AND
+        invhist_posted = true
+    GROUP BY
+        invhist_ordnumber,
+        invhist_itemsite_id
+         
+        ;
+            
+
+ALTER TABLE invhist_buy
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_buy TO admin;
+GRANT ALL ON TABLE invhist_buy TO xtrole;
+
+
+
+
+
+CREATE OR REPLACE FUNCTION invhist_buy_qtybydate(int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+  i_id ALIAS FOR $1;
+  v_itemsite_id INTEGER;
+  v_transdate timestamp with time zone;
+  v_qty numeric(18,6) ;
+  v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+
+
+
+
+   SELECT
+      itemsite_id,
+     transdate,
+     qty
+        INTO
+        v_itemsite_id, 
+        v_transdate,
+        v_qty
+        FROM invhist_buy 
+        WHERE
+            invhist_id = i_id
+        LIMIT 1;
+   
+
+-- # when transactions are the same day, we only want to include the ones with lower ids..
+
+
+    SELECT   COALESCE(SUM( qty), 0) + v_qty INTO v_return 
+        FROM invhist_buy 
+        WHERE
+            itemsite_id = v_itemsite_id
+            AND   ( 
+                transdate <  v_transdate 
+                OR
+                (transdate =  v_transdate AND invhist_id < i_id)
+            )  ;
+
+    IF (v_return IS NULL) THEN 
+        v_return = 0;
+    END IF;
+
+
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invhist_buy_qtybydate(int)
+  OWNER TO admin;
+
+
+
+-- #------------- SELL
+
+
+DROP VIEW invhist_sell ;
+-- buy is a mix of RP and +ve adjustments.
+CREATE OR REPLACE VIEW invhist_sell AS
+
+-- should this use ordnum + docnumber..
+
+     SELECT
+        distinct(invhist_ordnumber)  AS ordernumber,
+        invhist_itemsite_id                             AS itemsite_id,
+        SUM(invhist_qoh_after - invhist_qoh_before)          AS qty,
+        SUM(invhist_value_after - invhist_value_before)    AS current_totalcost,
+        
+        
+        CASE
+            WHEN SUM(invhist_qoh_after - invhist_qoh_before) = 0.0
+            THEN 0.0
+            ELSE  
+            SUM(invhist_value_after - invhist_value_before)
+                / SUM(invhist_qoh_after - invhist_qoh_before)
+            END
+                                                          AS current_unitcost,
+        
+        'SH'                                   AS ordertype ,
+        
+        invhist_firstid(invhist_itemsite_id, invhist_ordnumber, 'SH')
+                                                        AS invhist_id,
+                                                        
+        invhist_firstdate(invhist_itemsite_id, invhist_ordnumber, 'SH')
+                                                         AS transdate,
+        
+        0 AS qtyafter,
+        0.0 AS calc_unitcost,
+        0.0 AS calc_totalcost
+        
+        
+    FROM
+        invhist
+    WHERE
+        (invhist_transtype = 'SH' OR invhist_transtype = 'RS')
+        AND 
+        invhist_posted = true;
+    GROUP BY
+        invhist_ordnumber,
+        invhist_itemsite_id 
+        ;
+            
+
+ALTER TABLE invhist_sell
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_sell TO admin;
+GRANT ALL ON TABLE invhist_sell TO xtrole;
+
+
+
+
+
+CREATE OR REPLACE FUNCTION invhist_sell_qtybefore(int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+  i_id ALIAS FOR $1;
+  v_itemsite_id INTEGER;
+  v_transdate timestamp with time zone;
+  v_qty numeric(18,6) ;
+  v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+
+
+
+
+   SELECT
+      itemsite_id,
+     transdate,
+     qty
+        INTO
+        v_itemsite_id, 
+        v_transdate 
+         
+        FROM invhist_sell
+        WHERE
+            invhist_id = i_id
+        LIMIT 1;
+   
+
+-- # when transactions are the same day, we only want to include the ones with lower ids..
+
+
+    SELECT   COALESCE(SUM( qty), 0)   INTO v_return 
+        FROM invhist_sell 
+        WHERE
+            itemsite_id = v_itemsite_id
+            AND   ( 
+                transdate <  v_transdate 
+                OR
+                (transdate =  v_transdate AND invhist_id < i_id)
+            )  ;
+
+    IF (v_return IS NULL) THEN 
+        v_return = 0;
+    END IF;
+
+
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invhist_sell_qtybefore(int)
+  OWNER TO admin;
+
+
+--------------- COGS CALC...
+xtuplehk=# select *, invhist_sell_qtybefore(invhist_id) from invhist_sell where invhist_id = 53429  ;
+ ordernumber | itemsite_id |    qty    | current_totalcost |   current_unitcost   | ordertype | invhist_id |       transdate        | invhist_sell_qtybefore 
+-------------+-------------+-----------+-------------------+----------------------+-----------+------------+------------------------+------------------------
+ 3997-12     |        1149 | -60.000000 |          -8738.40 | 145.6400000000000000 | SH        |      53429 | 2010-02-26 00:00:00+08 |            -718.000000
+
+
+Now to calculate FIFO VALUE..1149
+
+select * ,invhist_buy_qtybydate(invhist_id) as qtyafter from invhist_buy
+        where
+            itemsite_id=1149
+            AND
+            invhist_buy_qtybydate(invhist_id) > 718.000000
+            AND
+            invhist_buy_qtybydate(invhist_id) <= 718.000000 + 60.000000
+        
+        ORDER BY
+            transdate ASC, invhist_id ASC
+        LIMIT 1;
+        
+        
+ordernumber   | itemsite_id |    qty     | totalcost |       unitcost       | transtype | invhist_id |       transdate        |  qtyafter   
+-----------------+-------------+------------+-----------+----------------------+-----------+------------+------------------------+-------------
+BU0021/NV5675-2 |        1149 | 402.000000 |  58547.28 | 145.6400000000000000 | RP        |      36656 | 2011-08-09 00:00:00+08 | 1693.000000
+
+STOCK UN-ALLOCATED (IN THIS ONE) = 1693.000000 - 1595.000000
+ ==> 98 PIECES
+
+TRIGGER INSERT UPDATE ON invhist
+    UPDATE OR INSERT THE invhist_buy or invhist_sell tables
+    THEN RUN invhist_sell_qtybefore OR invhist_buy_qtybydate
+    ON ALL ROWS AFTER
+    THEN
+    RUN THE FIFO CALC 
+    
+
+        
+
+
diff --git a/pgsql/old/geteffectivextuser.sql b/pgsql/old/geteffectivextuser.sql
new file mode 100644 (file)
index 0000000..f8b1ce1
--- /dev/null
@@ -0,0 +1,25 @@
+CREATE OR REPLACE FUNCTION getEffectiveXtUser() RETURNS TEXT AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+BEGIN
+/*
+  The default return value of this function is simply
+  the user currently connected.
+  
+  Overload this function from another schema 
+  to implement specific user handling from an external 
+  application that uses connection pooling. 
+  Use setEffectiveXtUser(text) to create a temporary table that 
+  inserts user data that can in turn be used as a lookup 
+  reference for an over loaded version of this function like so:
+  
+  SELECT effective_value
+  FROM effective_user
+  WHERE effective_key = 'username'
+*/
+
+  RETURN CURRENT_USER;
+
+END;
+$$ LANGUAGE 'plpgsql' STABLE;
+
diff --git a/pgsql/old/invadjustment.sql b/pgsql/old/invadjustment.sql
new file mode 100644 (file)
index 0000000..5fb36d2
--- /dev/null
@@ -0,0 +1,60 @@
+-- Function: invadjustment(integer, numeric, text, text, timestamp with time zone, numeric)
+
+-- DROP FUNCTION invadjustment(integer, numeric, text, text, timestamp with time zone, numeric);
+
+CREATE OR REPLACE FUNCTION invadjustment(integer, numeric, text, text, timestamp with time zone, numeric)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemsiteid     ALIAS FOR $1;
+  pQty            ALIAS FOR $2;
+  pDocumentNumber ALIAS FOR $3;
+  pComments       ALIAS FOR $4;
+  pGlDistTS       ALIAS FOR $5;
+  pCostValue      ALIAS FOR $6;
+
+  _CostValueOwn  numeric;
+  _invhistid      INTEGER;
+  _itemlocSeries  INTEGER;
+
+BEGIN
+
+--  Make sure the passed itemsite points to a real item
+  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
+         FROM itemsite, item
+         WHERE ( (itemsite_item_id=item_id)
+          AND (itemsite_id=pItemsiteid) ) ) ) THEN
+    RETURN 0;
+  END IF;
+
+  IF ( pQty > 0) THEN
+    IF (pCostValue IS NULL OR pCostValue = 0) THEN
+        RAISE EXCEPTION 'Cost value isn''t provided';
+    END IF;
+       _CostValueOwn := pCostValue;
+  ELSIF (pQty < 0) THEN
+    IF (pCostValue IS NOT NULL) THEN
+        RAISE EXCEPTION 'Cost value hasn''t sense for such type of transaction';
+    END IF;
+    
+    _CostValueOwn := itemcost_dispense(pItemsiteid, pQty);
+  END IF;
+  
+  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+  SELECT postInvTrans( itemsite_id, 'AD', pQty,
+                       'I/M', 'AD', pDocumentNumber, '',
+                       ('Miscellaneous Adjustment for item ' || item_number || E'\n' ||  pComments),
+                       costcat_asset_accnt_id, costcat_adjustment_accnt_id,
+                       _itemlocSeries, pGlDistTS, _CostValueOwn) INTO _invhistid
+  FROM itemsite, item, costcat
+  WHERE ( (itemsite_item_id=item_id)
+   AND (itemsite_costcat_id=costcat_id)
+   AND (itemsite_id=pItemsiteid) );
+
+  RETURN _itemlocSeries;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION invadjustment(integer, numeric, text, text, timestamp with time zone, numeric) OWNER TO "admin";
diff --git a/pgsql/old/invreceipt.sql b/pgsql/old/invreceipt.sql
new file mode 100644 (file)
index 0000000..c023162
--- /dev/null
@@ -0,0 +1,62 @@
+-- Function: invreceipt(integer, numeric, text, text, text, timestamp with time zone, numeric)
+
+-- DROP FUNCTION invreceipt(integer, numeric, text, text, text, timestamp with time zone, numeric);
+
+CREATE OR REPLACE FUNCTION invreceipt(integer, numeric, text, text, text, timestamp with time zone, numeric)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemsiteid ALIAS FOR $1;
+  pQty ALIAS FOR $2;
+  pOrdernumber ALIAS FOR $3;
+  pDocumentNumber ALIAS FOR $4;
+  pComments ALIAS FOR $5;
+  pGlDistTS     ALIAS FOR $6;
+  pCostValue ALIAS FOR $7;
+  
+  _CostValueOwn numeric;
+  
+  _invhistid INTEGER;
+  _itemlocSeries INTEGER;
+
+BEGIN
+
+--  Make sure the passed itemsite points to a real item
+  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
+         FROM itemsite, item
+         WHERE ( (itemsite_item_id=item_id)
+          AND (itemsite_id=pItemsiteid) ) ) ) THEN
+    RETURN 0;
+  END IF;
+
+  IF ( pQty > 0) THEN
+    IF (pCostValue IS NULL) THEN
+        RAISE EXCEPTION 'Cost value isn''t provided';
+    END IF;
+       _CostValueOwn := pCostValue;
+  ELSIF (pQty < 0) THEN
+    IF (pCostValue IS NOT NULL) THEN
+        RAISE EXCEPTION 'Cost value hasn''t sense for such type of transaction';
+    END IF;
+    
+    _CostValueOwn := itemcost_dispense(pItemsiteid, pQty);
+  END IF;
+  
+  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+  SELECT postInvTrans( itemsite_id, 'RX', pQty,
+                       'I/M', 'RX', pDocumentNumber, '',
+                       ('Miscellaneous Receipt for item ' || item_number || E'\n' ||  pComments),
+                       costcat_asset_accnt_id, costcat_liability_accnt_id,
+                       _itemlocSeries, pGlDistTS, _CostValueOwn) INTO _invhistid
+  FROM itemsite, item, costcat
+  WHERE ( (itemsite_item_id=item_id)
+   AND (itemsite_costcat_id=costcat_id)
+   AND (itemsite_id=pItemsiteid) );
+
+  RETURN _itemlocSeries;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION invreceipt(integer, numeric, text, text, text, timestamp with time zone, numeric) OWNER TO "admin";
diff --git a/pgsql/old/postinvtrans.sql b/pgsql/old/postinvtrans.sql
new file mode 100644 (file)
index 0000000..a74ff06
--- /dev/null
@@ -0,0 +1,314 @@
+-- Function: postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer)
+
+-- DROP FUNCTION postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer);
+
+CREATE OR REPLACE FUNCTION postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemsiteid         ALIAS FOR $1;
+  pTransType         ALIAS FOR $2;
+  pQty             ALIAS FOR $3;
+  pModule         ALIAS FOR $4;
+  pOrderType         ALIAS FOR $5;
+  pOrderNumber         ALIAS FOR $6;
+  pDocNumber         ALIAS FOR $7;
+  pComments         ALIAS FOR $8;
+  pDebitid         ALIAS FOR $9;
+  pCreditid         ALIAS FOR $10;
+  pItemlocSeries     ALIAS FOR $11;
+  pTimestamp         TIMESTAMP WITH TIME ZONE := $12;
+  pCostOvrld         ALIAS FOR $13;
+  pInvhistid         ALIAS FOR $14;  -- original transaction to be returned, reversed, etc.
+
+  _creditid         INTEGER;
+  _debitid         INTEGER;
+  _glreturn         INTEGER;
+  _invhistid         INTEGER;
+  _itemlocdistid     INTEGER;
+  _r             RECORD;
+  _sense         INTEGER;  -- direction in which to adjust inventory QOH
+  _t             RECORD;
+  _xferwhsid         INTEGER;
+
+BEGIN
+
+  --  Cache item and itemsite info  
+  SELECT CASE WHEN(itemsite_costmethod IN ('A','J')) THEN COALESCE(abs(pCostOvrld / pQty), avgcost(itemsite_id))
+              ELSE stdCost(itemsite_item_id)
+         END AS cost,
+            itemsite_costmethod,
+            itemsite_qtyonhand,
+            itemsite_warehous_id,
+         ( (item_type = 'R') OR (itemsite_controlmethod = 'N') ) AS nocontrol,
+         (itemsite_controlmethod IN ('L', 'S')) AS lotserial,
+         (itemsite_loccntrl) AS loccntrl,
+         itemsite_freeze AS frozen INTO _r
+  FROM itemsite JOIN item ON (item_id=itemsite_item_id)
+  WHERE (itemsite_id=pItemsiteid);
+
+
+  -- FIFO support
+  
+  IF (
+        --(
+            _r.itemsite_costmethod = 'F' 
+            OR
+            (
+                _r.itemsite_costmethod = 'S' AND fetchMetricBool('UseStandardAsFIFO')
+            )
+     --   )
+       -- AND
+        -- only do this calculation if price was not passed.
+      --  (
+      --      pCostOvrld IS NOT NULL
+      --  )
+    ) THEN
+        RAISE NOTICE 'FIFO in action, and cost is not available: %', pCostOvrld;
+        
+        -- not sure why this calc is here... - all 
+        -- _r.cost := COALESCE(abs(pCostOvrld / pQty), _r.cost);
+        RAISE NOTICE 'Default cost 1: %', _r.cost ;
+        
+        IF (pTransType = 'SH' OR pTransType = 'RS') THEN
+            -- Shipment or return shipment
+            -- cost is based on fifo calculation?
+            _r.cost := itemcost_dispense(pItemsiteid, pQty);
+            
+        ELSIF (pTransType = 'AD' AND pQty > 0) THEN
+            -- increased stock..
+            _r.cost := COALESCE(abs(pCostOvrld / pQty), _r.cost);
+            IF _r.cost = 0 THEN
+                RAISE EXCEPTION 'Adjustment increase posted without value';
+            END IF;
+        
+        
+        
+        ELSIF (pTransType = 'AD' AND pQty < 0) THEN
+            _r.cost := itemcost_dispense(pItemsiteid, pQty);
+        
+        ELSE 
+            -- recieving stock.
+            -- look up cost in purchase order
+-- THIS NEEDS TO THROW AN ERROR IF the cost has not been found
+-- Just in case we missed something.
+
+    -- 
+            
+            SELECT poitem_unitprice
+                INTO
+                    _r.cost
+                FROM
+                    poitem
+                LEFT JOIN
+                    pohead
+                    ON
+                    poitem_pohead_id = pohead_id
+                    
+                WHERE 
+                    pohead_number || '-' || poitem_linenumber = pOrderNumber  
+                    AND
+                    poitem_itemsite_id = pItemsiteid
+                LIMIT 1;
+            
+            -- if we really do not have a price... .try the dispense price
+            _r.cost := COALESCE(_r.cost, itemcost_dispense(pItemsiteid, pQty));
+            
+        END IF;
+    END IF;
+
+RAISE NOTICE 'rocst is: %', _r.cost;
+        
+
+  --  Post the Inventory Transactions
+  IF (NOT _r.nocontrol) THEN
+
+    IF (COALESCE(pItemlocSeries,0) = 0) THEN
+      RAISE EXCEPTION 'Transaction series must be provided';
+    END IF;
+
+    SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
+
+    IF ((pTimestamp IS NULL) OR (CAST(pTimestamp AS date)=CURRENT_DATE)) THEN
+      pTimestamp := CURRENT_TIMESTAMP;
+    END IF;
+
+    IF (pTransType = 'TS' OR pTransType = 'TR') THEN
+      SELECT * INTO _t FROM tohead WHERE (tohead_number=pDocNumber);
+      IF (pTransType = 'TS') THEN
+        _xferwhsid := CASE
+            WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+            WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_src_warehous_id
+            WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_dest_warehous_id
+            WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+            ELSE NULL
+        END;
+      ELSIF (pTransType = 'TR') THEN
+        _xferwhsid := CASE
+            WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+            WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_dest_warehous_id
+            WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_src_warehous_id
+            WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+            ELSE NULL
+        END;
+      END IF;
+    END IF;
+
+
+    -- increase inventory: AD RM RT RP RR RS RX RB TR
+    -- decrease inventory: IM IB IT SH SI EX RI
+    -- TS and TR are special: shipShipment and recallShipment should not change
+    -- QOH at the Transfer Order src whs (as this was done by issueToShipping)
+    -- but postReceipt should change QOH at the transit whs
+    IF (pTransType='TS') THEN
+      _sense := CASE WHEN (SELECT tohead_trns_warehous_id=_r.itemsite_warehous_id
+               FROM tohead
+               WHERE (tohead_number=pDocNumber)) THEN -1
+               ELSE 0
+               END;
+    ELSIF (pTransType='TR') THEN
+      _sense := CASE WHEN (SELECT tohead_src_warehous_id=_r.itemsite_warehous_id
+               FROM tohead
+               WHERE (tohead_number=pDocNumber)) THEN 0
+               ELSE 1
+               END;
+    ELSIF (pTransType IN ('IM', 'IB', 'IT', 'SH', 'SI', 'EX', 'RI')) THEN
+      _sense := -1;
+
+    ELSE
+      _sense := 1;
+    END IF;
+
+    IF((_r.itemsite_costmethod='A') AND (_r.itemsite_qtyonhand + round(_sense * pQty, 6)) < 0) THEN
+      -- Can not let average costed itemsites go negative
+      RAISE EXCEPTION 'This transaction will cause an Average Costed item to go negative which is not allowed.';
+      RETURN -2;
+    END IF;
+
+
+    --RAISE NOTICE 'itemsite_value=% ', (SELECT itemsite_value FROM itemsite where itemsite_id = pItemsiteid LIMIT 1);
+    --RAISE NOTICE '_r.cost=% ', _r.cost;
+    --RAISE NOTICE '_sense=% ', _sense;
+    --RAISE NOTICE 'pQty=% ', pQty;
+
+    INSERT INTO invhist
+    ( invhist_id, invhist_itemsite_id, invhist_transtype, invhist_transdate,
+      invhist_invqty, invhist_qoh_before,
+      invhist_qoh_after,
+      invhist_costmethod, invhist_value_before, invhist_value_after,
+      invhist_ordtype, invhist_ordnumber, invhist_docnumber, invhist_comments,
+      invhist_invuom, invhist_unitcost, invhist_xfer_warehous_id, invhist_posted,
+      invhist_series )
+    SELECT
+      _invhistid, itemsite_id, pTransType, pTimestamp,
+      pQty, itemsite_qtyonhand,
+      (itemsite_qtyonhand + (_sense * pQty)),
+      itemsite_costmethod, itemsite_value, itemsite_value + (_r.cost * _sense * pQty),
+      pOrderType, pOrderNumber, pDocNumber, pComments,
+      uom_name, _r.cost, _xferwhsid, FALSE, pItemlocSeries
+    FROM itemsite, item, uom
+    WHERE ( (itemsite_item_id=item_id)
+        AND (item_inv_uom_id=uom_id)
+        AND (itemsite_id=pItemsiteid) );
+
+    IF (pCreditid IN (SELECT accnt_id FROM accnt)) THEN
+      _creditid = pCreditid;
+    ELSE
+      SELECT warehous_default_accnt_id INTO _creditid
+      FROM itemsite, warehous
+      WHERE ( (itemsite_warehous_id=warehous_id)
+        AND  (itemsite_id=pItemsiteid) );
+    END IF;
+
+    IF (pDebitid IN (SELECT accnt_id FROM accnt)) THEN
+      _debitid = pDebitid;
+    ELSE
+      SELECT warehous_default_accnt_id INTO _debitid
+      FROM itemsite, warehous
+      WHERE ( (itemsite_warehous_id=warehous_id)
+        AND  (itemsite_id=pItemsiteid) );
+    END IF;
+
+--  Post the G/L Transaction
+    IF (_creditid <> _debitid) THEN
+      SELECT insertGLTransaction(pModule, pOrderType, pOrderNumber, pComments,
+                 _creditid, _debitid, _invhistid,
+                 (_r.cost * pQty), pTimestamp::DATE, FALSE) INTO _glreturn;
+    END IF;
+
+    --  Distribute this if this itemsite is controlled
+    IF ( _r.lotserial OR _r.loccntrl ) THEN
+
+      _itemlocdistid := nextval('itemlocdist_itemlocdist_id_seq');
+      INSERT INTO itemlocdist
+      ( itemlocdist_id,
+        itemlocdist_itemsite_id,
+        itemlocdist_source_type,
+        itemlocdist_reqlotserial,
+        itemlocdist_distlotserial,
+        itemlocdist_expiration,
+        itemlocdist_qty,
+        itemlocdist_series,
+        itemlocdist_invhist_id,
+        itemlocdist_order_type,
+        itemlocdist_order_id )
+      SELECT _itemlocdistid,
+             pItemsiteid,
+             'O',
+             (((pQty * _sense) > 0)  AND _r.lotserial),
+         ((pQty * _sense) < 0),
+             endOfTime(),
+             (_sense * pQty),
+             pItemlocSeries,
+             _invhistid,
+             pOrderType, 
+             CASE WHEN pOrderType='SO' THEN getSalesLineItemId(pOrderNumber)
+                  ELSE NULL
+             END;
+
+      -- populate distributions if invhist_id parameter passed to undo
+      IF (pInvhistid IS NOT NULL) THEN
+        INSERT INTO itemlocdist
+          ( itemlocdist_itemlocdist_id, itemlocdist_source_type, itemlocdist_source_id,
+            itemlocdist_itemsite_id, itemlocdist_ls_id, itemlocdist_expiration,
+            itemlocdist_qty, itemlocdist_series, itemlocdist_invhist_id ) 
+        SELECT _itemlocdistid, 'L', COALESCE(invdetail_location_id, -1),
+               invhist_itemsite_id, invdetail_ls_id,  COALESCE(invdetail_expiration, endoftime()),
+               (invdetail_qty * -1.0), pItemlocSeries, _invhistid
+        FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
+        WHERE (invhist_id=pInvhistid);
+
+        IF ( _r.lotserial)  THEN          
+          INSERT INTO lsdetail 
+            ( lsdetail_itemsite_id, lsdetail_ls_id, lsdetail_created,
+              lsdetail_source_type, lsdetail_source_id, lsdetail_source_number ) 
+          SELECT invhist_itemsite_id, invdetail_ls_id, CURRENT_TIMESTAMP,
+                 'I', _itemlocdistid, ''
+          FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
+          WHERE (invhist_id=pInvhistid);
+        END IF;
+
+        PERFORM distributeitemlocseries(pItemlocSeries);
+        
+      END IF;
+
+    END IF;   -- end of distributions
+
+  -- These records will be used for posting G/L transactions to trial balance after records committed.
+  -- If we try to do it now concurrency locking prevents any transacitons while
+  -- user enters item distribution information.  Cant have that.
+    INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
+    VALUES ( _glreturn, pItemlocSeries );
+
+    RETURN _invhistid;
+  ELSE
+    RETURN -1;
+  END IF;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer) OWNER TO "admin";
diff --git a/pgsql/old/sg-eoy-fixmonths2011.sql b/pgsql/old/sg-eoy-fixmonths2011.sql
new file mode 100644 (file)
index 0000000..b4b9b4f
--- /dev/null
@@ -0,0 +1,24 @@
+
+SELECT  netsuite_eoyfix( '2010-10-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2010-11-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2010-12-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-01-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-02-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-03-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-04-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-05-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-06-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-07-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-08-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-create_invbuysell_tbls.sql b/pgsql/old/x-fifo-create_invbuysell_tbls.sql
new file mode 100644 (file)
index 0000000..ff0cc93
--- /dev/null
@@ -0,0 +1,141 @@
+create table invbuy (
+    invbuy_invhist_id integer NOT NULL UNIQUE,
+    invbuy_transdate timestamp with time zone DEFAULT ('now'::text)::timestamp(6) with time zone,
+    invbuy_ordnumber text NOT NULL,
+    invbuy_itemsite_id integer NOT NULL,
+    invbuy_qty numeric(18, 6),
+    invbuy_totalcost numeric(12, 2),
+    invbuy_unitcost numeric(16, 6),
+    invbuy_transtype character(2),
+    invbuy_qtyafter numeric(18, 6),
+    invbuy_totalcostafter numeric(12, 2),
+
+        
+    CONSTRAINT invbuy_pkey PRIMARY KEY (invbuy_itemsite_id, invbuy_ordnumber),
+    CONSTRAINT invbuy_invhist_fk FOREIGN KEY (invbuy_invhist_id) REFERENCES invhist (invhist_id),
+    CONSTRAINT invbuy_itemsite_fk FOREIGN KEY (invbuy_itemsite_id) REFERENCES itemsite (itemsite_id)
+    
+);
+
+CREATE INDEX invbuy_qty_indx
+  ON invbuy
+  USING btree
+  (invbuy_qty);
+
+CREATE INDEX invbuy_qtyafter_indx
+  ON invbuy
+  USING btree
+  (invbuy_qtyafter);
+
+CREATE INDEX invbuy_totalcostafter_indx
+  ON invbuy
+  USING btree
+  (invbuy_totalcostafter);
+
+CREATE INDEX invbuy_transtype_indx
+  ON invbuy
+  USING btree
+  (invbuy_transtype);
+
+CREATE INDEX invbuy_transdate_indx
+  ON invbuy
+  USING btree
+  (invbuy_transdate);
+  
+  
+  
+  
+GRANT ALL ON TABLE invbuy TO admin;
+GRANT ALL ON TABLE invbuy TO xtrole;
+
+create table invsell (
+    invsell_invhist_id integer NOT NULL UNIQUE,
+    invsell_transdate timestamp with time zone DEFAULT ('now'::text)::timestamp(6) with time zone,
+    invsell_itemsite_id integer NOT NULL,
+    invsell_ordnumber text NOT NULL,
+    invsell_qty numeric(18, 6),
+    invsell_current_totalcost numeric(12, 2),
+    invsell_current_unitcost numeric(16, 6),
+    invsell_transtype character(2),
+    invsell_qtybefore numeric(18, 6),
+    invsell_totalcostbefore numeric(12, 2),
+    invsell_calc_unitcost numeric(18, 6),
+    invsell_calc_totalcost numeric(18, 6),
+    invsell_is_estimate boolean,
+        
+    CONSTRAINT invsell_pkey PRIMARY KEY (invsell_itemsite_id, invsell_ordnumber),
+    CONSTRAINT invsell_invhist_fk FOREIGN KEY (invsell_invhist_id) REFERENCES invhist (invhist_id),
+    CONSTRAINT invsell_itemsite_fk FOREIGN KEY (invsell_itemsite_id) REFERENCES itemsite (itemsite_id)
+);
+
+CREATE INDEX invsell_qty_indx
+  ON invsell
+  USING btree
+  (invsell_qty);
+
+CREATE INDEX invsell_qtyafter_indx
+  ON invsell
+  USING btree
+  (invsell_qtyafter);
+
+CREATE INDEX invsell_totalcostafter_indx
+  ON invsell
+  USING btree
+  (invsell_totalcostafter);
+
+CREATE INDEX invsell_transtype_indx
+  ON invsell
+  USING btree
+  (invsell_transtype);
+
+CREATE INDEX invsell_transdate_indx
+  ON invsell
+  USING btree
+  (invsell_transdate);    
+
+
+CREATE INDEX  invsell_is_estimate_indx
+  ON invsell
+  USING btree
+  (invsell_is_estimate);  
+
+CREATE INDEX  invsell_current_unitcost_indx
+  ON invsell
+  USING btree
+  (invsell_current_unitcost);  
+
+CREATE INDEX  invsell_calc_unitcost_indx
+  ON invsell
+  USING btree
+  (invsell_calc_unitcost);  
+
+
+CREATE INDEX  invsell_current_totalcost_indx
+  ON invsell
+  USING btree
+  (invsell_current_totalcost);
+  
+
+CREATE INDEX  invsell_calc_totalcost_indx
+  ON invsell
+  USING btree
+  (invsell_calc_totalcost);
+  
+
+GRANT ALL ON TABLE invsell TO admin;
+GRANT ALL ON TABLE invsell TO xtrole;
+
+
+CREATE TABLE invdepend (
+    invdepend_parent_id integer NOT NULL,
+    invdepend_invhist_id integer NOT NULL,
+    
+    CONSTRAINT invdepend_pkey PRIMARY KEY (invdepend_invhist_id),
+    CONSTRAINT invdepend_parent_fk FOREIGN KEY (invdepend_parent_id) REFERENCES invhist (invhist_id),
+    CONSTRAINT invdepend_invhist_fk FOREIGN KEY (invdepend_invhist_id) REFERENCES invhist (invhist_id)
+);
+
+GRANT ALL ON TABLE invdepend TO admin;
+GRANT ALL ON TABLE invdepend TO xtrole;
+
diff --git a/pgsql/old/x-fifo-create_trig_invhisttriggerfifo.sql b/pgsql/old/x-fifo-create_trig_invhisttriggerfifo.sql
new file mode 100644 (file)
index 0000000..9ffdaf4
--- /dev/null
@@ -0,0 +1,5 @@
+CREATE TRIGGER _invhisttriggerfifo 
+    AFTER INSERT OR UPDATE ON invhist
+        FOR EACH ROW EXECUTE PROCEDURE invhisttriggerfifo();
+        
+        
diff --git a/pgsql/old/x-fifo-invdetail-adjust.sql b/pgsql/old/x-fifo-invdetail-adjust.sql
new file mode 100644 (file)
index 0000000..1b4a402
--- /dev/null
@@ -0,0 +1,156 @@
+-- find the qty available..
+
+
+-- cogs adjustment - moves $value from cogs to inventory..
+-- based on fifo calc.
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_recalc_cogs()
+    RETURNS  numeric(18, 6) 
+    
+AS $BODY$
+DECLARE
+    
+    v_current_value              numeric(18, 6);
+    v_correct_value          numeric(18, 6);
+    v_adjust_value          numeric(18, 6);
+    v_glsequence INTEGER;
+    v_acct_cogs INTEGER;
+    v_acct_inventory INTEGER;
+    v_result INTEGER;
+    
+BEGIN
+      
+    SELECT 
+            costcat_asset_accnt_id
+        INTO 
+            v_acct_inventory
+        FROM
+            costcat
+        WHERE
+            costcat_code = 'CATEGORY1'
+        LIMIT 1;
+    
+    SELECT 
+            salesaccnt_cos_accnt_id
+        INTO
+            v_acct_cogs
+        FROM
+            salesaccnt
+        WHERE
+            salesaccnt_prodcat = '.*'
+        LIMIT
+            1;
+            
+    
+    SELECT
+            sum(gltrans_amount)
+        INTO
+            v_current_value
+        FROM
+            gltrans
+        WHERE
+            -- same number in both systems
+            -- should be taken from lookup..
+            
+                gltrans_accnt_id = v_acct_cogs
+            AND
+            (
+                  -- fullfilments.
+                    (gltrans_source  = 'S/R' AND gltrans_doctype = 'SH')
+                OR
+                -- invoices (DIRECTLY BILLED WITHOUT SO/SHIP PROCESS)
+                    (gltrans_source  = 'S/O'    AND gltrans_doctype = 'IN')
+                -- OR
+                -- purchase recieve..( voucher?)
+                --    (gltrans_source  = 'A/P' AND  gltrans_doctype = 'VO')
+                -- OR
+                -- adjustments
+                --     (gltrans_source  = 'I/M' AND gltrans_doctype = 'AD')
+                OR
+              
+                -- our fifo adjustments..
+                    (
+                        gltrans_source  = 'G/L'
+                    AND
+                        gltrans_doctype = 'JE'
+                    AND
+                        gltrans_docnumber like 'FIFO-COGS-%'
+                    )
+            );
+            
+    SELECT
+            sum(invfifo_totalcost * (ABS(invdetail_qty)/invdetail_qty))
+        INTO
+            v_correct_value
+        FROM
+            invdetailview
+        WHERE
+            invhist_transtype = 'SH';
+         
+    
+    RAISE NOTICE 'ADJUST FIFO by %', (v_correct_value -      v_current_value);
+    v_adjust_value         := (v_correct_value -      v_current_value) ;
+    
+    IF v_adjust_value   < 1 AND v_adjust_value > -1 THEN
+        RETURN 0;
+    END IF;
+    
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    SELECT insertIntoGLSeries(
+                    v_glsequence,
+                    'G/L',
+                    'JE',
+                    'FIFO-COGS-' || v_glsequence,
+                    v_acct_cogs,
+                   v_adjust_value,
+                   NOW()::DATE,
+                   'FIFO COGS Adjustment based on Calculations'
+                   ) INTO v_result;
+                   
+                   
+    IF (v_result < 0) THEN
+        PERFORM deleteGLSeries(v_glsequence);
+       RETURN v_result;
+    END IF;
+    
+    SELECT insertIntoGLSeries(
+                    v_glsequence,
+                    'G/L',
+                    'JE',
+                    'FIFO-COGS-' || v_glsequence,
+                    v_acct_inventory,
+                    v_adjust_value * -1,
+                    NOW()::DATE,
+                    'FIFO COGS Adjustment based on Calculations'
+                ) INTO v_result;
+    
+                               
+    IF (v_result < 0) THEN
+        PERFORM deleteGLSeries(v_glsequence);
+       RETURN v_result;
+    END IF;
+    
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    IF (v_result < 0) THEN
+        PERFORM deleteGLSeries(v_glsequence);
+       RETURN v_result;
+    END IF;
+    
+    RETURN v_correct_value -      v_current_value;
+          
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_recalc_cogs( )
+  OWNER TO admin;
+          
+          
+          
+          
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invdetail_update_sell.sql b/pgsql/old/x-fifo-invdetail_update_sell.sql
new file mode 100644 (file)
index 0000000..a949ffc
--- /dev/null
@@ -0,0 +1,296 @@
+
+-- SELECT count (res) FROM ( SELECT invfifo_update_sell(itemsite_id, location_id,0) as res
+--   FROM (select distinct(invhist_itemsite_id) as itemsite_id, invdetail_location_id as location_id
+-- from invdetailview group by invhist_itemsite_id, invdetail_location_id) allitems ) wrap;
+
+-- testing :
+--   invdetail_location_id    | 128
+--    itemsite = 1269
+-- SELECT invfifo_update_sell(1269, 128, 0)
+-- find the qty available..
+
+-- SELECT invfifo_update_sell(1514, 128, 0)
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_sell(integer, integer, numeric(18, 6))
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+     
+    i_itemsite_id  ALIAS FOR $1;
+    i_location_id ALIAS FOR $2;
+    i_qty_before      ALIAS FOR $3;
+    
+    v_no_more  boolean;
+    v_totalcost     numeric(18, 6);
+    v_unitcost              numeric(18, 6);
+    v_run_cost_before              numeric(18, 6);
+    
+    v_add_unitcost   numeric(18, 6);
+    
+    
+    v_cost_before             numeric(18, 6);
+    v_cost_after             numeric(18, 6);
+    v_cost_before_res             numeric(18, 6);
+    v_cost_after_res             numeric(18, 6);
+    
+    
+    
+    v_rev_cost_before         numeric(18, 6);
+    v_rev_totalcost      numeric(18, 6);
+    v_rev_location_id   INTEGER;
+    v_costdiff  numeric(18, 6);
+    
+    v_invfifo_curs RECORD;
+    
+    invfifo_curs CURSOR (c_itemsite_id integer, c_location_id integer,  c_start_qty numeric(18, 6)) IS
+              
+            SELECT
+                invfifo_invdetail_id,
+                invfifo_totalcost,
+                invfifo_qty_before,
+                invfifo_qty_after,
+                invfifo_cost_before,
+                invfifo_cost_after,
+                invdetail_qty,
+                invdetail_invhist_id,
+                
+                (SELECT
+                        invd.invdetail_id
+                    FROM
+                        invdetail invd
+                    WHERE
+                        invd.invdetail_invhist_id = invdetailview.invdetail_invhist_id
+                        AND
+                        invd.invdetail_id != invdetail_id
+                ) as rev_invdetail_id
+                
+            FROM      
+                invdetailview
+            WHERE
+                    invdetail_location_id = c_location_id
+                AND
+                    invfifo_qty_before >= c_start_qty
+                AND
+                    invhist_itemsite_id = c_itemsite_id
+                AND
+                    invdetail_qty < 0
+            ORDER BY
+                invfifo_qty_before ASC;
+                 
+      
+BEGIN
+      
+    --RAISE NOTICE 'invfifo_update_sell( %, %, %)', i_itemsite_id, i_location_id, i_qty_before;
+    
+    v_no_more := false;
+    
+    v_run_cost_before := 0;
+    
+    SELECT stdcost(i_itemsite_id) INTO v_unitcost ;
+    
+    -- running values...
+    SELECT
+       
+                invfifo_cost_before 
+            INTO      
+                v_run_cost_before
+                
+             
+            FROM
+                invdetailview
+            
+            WHERE
+                    invdetail_location_id = i_location_id
+                AND
+                    invfifo_qty_before < i_qty_before
+                AND
+                    invhist_itemsite_id = i_itemsite_id
+                AND
+                    invdetail_qty < 0
+            ORDER BY
+                invfifo_qty_before ASC
+            LIMIT 1;
+                
+    v_run_cost_before := COALESCE(v_run_cost_before, 0);
+    --RAISE NOTICE 'cost before =%', v_run_cost_before;
+    
+    --RAISE NOTICE 'RUN CUSROR :  %, %, %', i_itemsite_id, i_location_id, i_qty_before;
+     
+    FOR v_invfifo_curs IN invfifo_curs (i_itemsite_id, i_location_id, i_qty_before) LOOP
+     
+        
+  
+    
+        -- RAISE NOT\qICE 'got record';
+        -- set up the defaults..
+        v_cost_before := v_run_cost_before;
+        v_cost_after  := v_run_cost_before + v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+        
+        v_add_unitcost := v_unitcost;
+        v_totalcost := v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+        
+        v_run_cost_before = v_run_cost_before + v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+        
+        if (NOT v_no_more) THEN 
+        
+            --RAISE NOTICE 'invfifo_cost_at_qty (%, %, %)' , i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_before;
+            --RAISE NOTICE 'invfifo_cost_at_qty (%, %, %)' , i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_after;
+        
+            SELECT invfifo_cost_at_qty( i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_before) INTO v_cost_before_res;
+            SELECT invfifo_cost_at_qty( i_itemsite_id  , i_location_id , v_invfifo_curs.invfifo_qty_after) INTO v_cost_after_res;
+        
+          
+            IF (v_cost_before_res < 0 OR v_cost_after_res < 0) THEN
+                
+            -- we where not able to find the price.
+                v_no_more := true;
+                v_run_cost_before = v_cost_after;
+               
+                
+            ELSE
+                v_cost_before := v_cost_before_res;
+                v_cost_after  := v_cost_after_res;
+                v_add_unitcost :=  (v_cost_after - v_cost_before) / ABS(v_invfifo_curs.invdetail_qty);
+                v_totalcost := (v_cost_after - v_cost_before);
+                -- set the current unit costs
+                v_unitcost := v_add_unitcost; 
+            END IF;
+            
+            --RAISE NOTICE
+            --        'cost @%-% unitcost = % before / after = % % ' ,
+            --        v_invfifo_curs.invfifo_qty_before, v_invfifo_curs.invfifo_qty_after,
+            --        v_add_unitcost,
+            --        v_cost_before_res, v_cost_after_res ;
+        
+        END IF;
+        
+        -- do not update anything if there was no change..
+        
+        IF v_totalcost = v_invfifo_curs.invfifo_totalcost THEN
+             --RAISE NOTICE 'invfifo_totalcost, SKIP NO CHANGE=%', v_totalcost;
+             CONTINUE;
+        END IF;
+        
+        
+        -- update this row...
+        --RAISE NOTICE 'invfifo_totalcost, set=%', v_totalcost;
+        
+        
+        UPDATE 
+            invfifo
+        SET
+            invfifo_unitcost   = v_add_unitcost,
+            invfifo_totalcost  = v_totalcost,
+            invfifo_cost_before = v_cost_before,
+            invfifo_cost_after = v_cost_after,
+            invfifo_is_estimate = v_no_more
+        WHERE
+            invfifo_invdetail_id = v_invfifo_curs.invfifo_invdetail_id;
+            
+            
+        IF v_invfifo_curs.rev_invdetail_id IS NOT NULL AND v_invfifo_curs.rev_invdetail_id > 0 THEN
+            -- it's a transfer, and the unit price of the transfer will need adjusting...
+            
+            
+            RAISE NOTICE 'GOT TX FLAG AS RECALC to %, @ d', v_rev_location_id, v_invfifo_curs.rev_invdetail_id;
+            
+            -- this in turn will cause a cascade of price revaluations..
+            -- find the total cost before on that entry.
+            SELECT
+                    invfifo_cost_before,
+                    invfifo_totalcost,
+                    invdetail_location_id
+                INTO
+                    v_rev_cost_before,
+                    v_rev_totalcost,
+                    v_rev_location_id
+                FROM
+                    invfifo
+                WHERE
+                    v_invfifo_curs.rev_invdetail_id;
+            
+            
+            -- to fix this..
+            -- we have to add costdiff to each future item.
+            -- TEST: WAS $4 (v_rev_totalcost)  then changed to $3 (v_totalcost)
+            --         so we have to reduce by $1 all cost/afters/befores...
+            --
+            -- The knock on effect from changing the  buy prices will be that
+            -- anything sold into that location will have to be revalued.
+            -- there is a concern here that this could get recursive...
+            
+            
+            v_costdiff = v_totalcost - v_rev_totalcost;
+            
+            UPDATE
+                    invfifo
+                SET
+                    invfifo_unitcost    = v_add_unitcost,
+                    invfifo_totalcost   = v_totalcost,
+                    invfifo_cost_after  =  invfifo_cost_after + v_costdiff,
+                    invfifo_recalc_queued = false  -- not sure if this will work..
+                WHERE
+                    v_invfifo_curs.rev_invdetail_id;
+              
+            -- update the matching record... and all ones in the future..
+            
+            UPDATE 
+                    invfifo
+                SET
+                    
+                    invfifo_cost_before = invfifo_cost_before + v_costdiff,
+                    invfifo_cost_after  = invfifo_cost_after +  v_costdiff,
+                    invfifo_recalc_queued = true
+                    
+                FROM
+                    invdetail,invhist
+               
+                WHERE
+                        invfifo_invdetail_id = invdetail_id
+                    AND
+                        invhist_id  = invdetail_invhist_id
+                    AND
+                    
+                        invdetail_location_id = v_rev_location_id
+                    AND
+                        ( 
+                            invhist_transdate > r_invhist.invhist_transdate
+                            OR
+                            (
+                                invhist_transdate = r_invhist.invhist_transdate
+                                AND
+                                invhist_id > v_invfifo_curs.rev_invdetail_id
+                            )
+                        )
+                    AND
+                        invhist_itemsite_id = r_invhist.invhist_itemsite_id
+                    AND
+                        invdetail_qty > 0;
+                
+                 
+               
+        
+        END IF;
+         
+    END LOOP;
+    
+   
+    
+       
+    RETURN TRUE;
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_sell(integer, integer, numeric(18, 6))
+  OWNER TO admin;
+          
+          
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invfifo_creditmemo_cost.sql b/pgsql/old/x-fifo-invfifo_creditmemo_cost.sql
new file mode 100644 (file)
index 0000000..8c2039f
--- /dev/null
@@ -0,0 +1,95 @@
+
+-- SELECT invdetail_id, invfifo_creditmemo_cost(invdetail_id)  FROM  invdetailview where invhist_transtype='RS';
+
+
+CREATE OR REPLACE FUNCTION invfifo_creditmemo_cost(integer)
+    RETURNS  numeric(18, 6)
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    
+    r_invdetail RECORD;
+    
+    v_unitcost  numeric(18, 6);
+    v_ret  numeric(18, 6);
+    v_last_id INTEGER;
+    v_cust_id  INTEGER;
+
+BEGIN
+    
+    SELECT
+            invhist_ordnumber,
+            invhist_transtype,
+            invhist_itemsite_id
+        INTO
+            r_invdetail
+        FROM
+            invdetailview
+        WHERE
+            invhist_id = invdetail_invhist_id 
+            AND
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF (r_invdetail.invhist_transtype != 'RS') THEN
+        RAISE EXCEPTION 'invfifo_creditmemo_cost called on non-credit memo';
+    END IF;
+    
+       
+        -- who is the customer..
+        SELECT
+                cmhead_cust_id
+            INTO
+                v_cust_id
+            FROM
+                cmhead
+            WHERE
+                cmhead_number = r_invdetail.invhist_ordnumber
+            LIMIT
+                1;
+        
+        -- This is a very simplistic way to do this.
+        -- basically we find the the last sold price to that customer..
+        SELECT
+                invfifo_unitcost
+            INTO
+                v_ret
+            FROM
+                invdetailview
+            WHERE
+                invfifo_cust_id = v_cust_id
+            AND
+                invhist_transtype = 'SH'
+            ORDER BY
+                invhist_transdate DESC,
+                invdetail_id DESC
+            LIMIT
+                1;
+        
+        
+        IF NOT FOUND OR v_ret = 0.0 THEN
+            RAISE NOTICE 'could not find buy price for cm %', r_invdetail.invhist_ordnumber;
+            SELECT
+                    stdcost(itemsite_item_id)
+                INTO
+                    v_ret
+                FROM
+                    itemsite
+                WHERE
+                    itemsite_id = r_invdetail.invhist_itemsite_id;
+            
+        END IF;
+    return v_ret;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_creditmemo_cost(integer)
+  OWNER TO admin;
+    
+    
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invfifo_purchase_value.sql b/pgsql/old/x-fifo-invfifo_purchase_value.sql
new file mode 100644 (file)
index 0000000..e1c8f48
--- /dev/null
@@ -0,0 +1,157 @@
+--
+--Work out the fifo cost (including landed cost eventually for a goods reciept.)
+
+-- SELECT invdetail_id, invfifo_purchase_cost(invdetail_id)  FROM  invdetailview where invhist_transtype='RP';
+
+
+CREATE OR REPLACE FUNCTION invfifo_purchase_cost(integer)
+    RETURNS  numeric(18, 6)
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    
+    r_invdetail RECORD;
+    
+    v_unitcost  numeric(18, 6);
+    v_ret  numeric(18, 6);
+    v_last_id INTEGER;
+
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetail, invhist, itemsite 
+        WHERE
+            invhist_itemsite_id = itemsite_id
+            AND
+            invhist_id = invdetail_invhist_id 
+            AND
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF (r_invdetail.invhist_transtype != 'RP') THEN
+        RAISE EXCEPTION 'invfifo_purchase_cost called on non-purchased item';
+    END IF;
+    
+    -- fetch the actual purchase price
+    
+    SELECT
+            currtobase(pohead_curr_id, poitem_unitprice, r_invdetail.invhist_transdate::date) 
+        INTO
+            v_unitcost  
+        FROM
+            poitem,pohead
+        where
+            poitem_pohead_id = pohead_id
+            AND
+            (pohead_number || '-' || poitem_linenumber)  = r_invdetail.invhist_ordnumber
+        LIMIT 1;
+    
+    -- find the total quantity of that order so that landed cost can be 
+    
+    
+    
+    -- we should probably update the 'stdcost' so future sales are based on this..
+    -- this may be a bit flakey if people using it with multicosted items..
+   
+    SELECT invfifo_purchase_last(r_invdetail.invhist_itemsite_id) INTO v_last_id;
+    
+    -- RAISE NOTICE 'ISLAST ?  % ?= %',  i_invdetail_id, v_last_id;
+    
+    IF (i_invdetail_id = v_last_id) THEN 
+        --RAISE NOTICE 'UPDATE itemcost for % to %', r_invdetail.itemsite_item_id,  v_unitcost * 1.1;
+        
+        -- turn off event loggin.
+        -- ALTER TABLE itemcost DISABLE TRIGGER    itemcostaftertrigger ;
+        
+        -- UPDATE
+        --        itemcost
+        --    SET
+        --        itemcost_stdcost = v_unitcost * 1.1,
+        --        itemcost_actcost = v_unitcost * 1.1,
+        --        itemcost_curr_id = basecurrid()
+        --        
+        --    WHERE
+        --        itemcost_id = (
+        --            SELECT
+        --                    itemcost_id
+        --                FROM
+        --                    itemcost
+        --                WHERE
+        --                    itemcost_costelem_id = getcostelemid('Material')
+        --                    AND
+        --                    itemcost_item_id = r_invdetail.itemsite_item_id
+        --                LIMIT 1
+        --        );
+        --
+        --ALTER TABLE itemcost ENABLE TRIGGER    itemcostaftertrigger ;
+    END IF;
+    -- at this point we should add on the landed cost
+    -- looking at the recvgrp for this transaction.
+    
+    -- at present, we are just going to add 10%.
+    
+    v_ret := v_unitcost * 1.1;
+    
+    return v_ret;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_purchase_cost(integer)
+  OWNER TO admin;
+    
+    
+
+CREATE OR REPLACE FUNCTION invfifo_purchase_last(integer)
+    RETURNS  INTEGER
+
+AS $BODY$
+DECLARE        
+           
+    i_itemsite_id  ALIAS FOR $1;
+     
+    v_ret INTEGER;
+
+BEGIN
+    
+    SELECT invdetail_id
+        INTO
+            v_ret
+        FROM
+            invdetailview
+        WHERE
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invhist_transtype = 'RP'
+        ORDER BY
+            invhist_transdate DESC,
+            invdetail_id DESC
+        LIMIT
+            1;
+            
+    IF NOT FOUND THEN
+        RETURN -1;
+    END IF;
+    
+    RETURN v_ret;
+   
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_purchase_last(integer)
+  OWNER TO admin;
+    
+         
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invfifo_update_queued.sql b/pgsql/old/x-fifo-invfifo_update_queued.sql
new file mode 100644 (file)
index 0000000..e01ec8e
--- /dev/null
@@ -0,0 +1,94 @@
+  
+CREATE OR REPLACE FUNCTION invfifo_update_queued(INTEGER)
+    RETURNS  boolean
+ AS $BODY$
+DECLARE
+    i_itemsite_id ALIAS FOR $1;
+    
+    v_qty_before  numeric(18, 6);
+    v_location_id INTEGER;
+   v_matches INTEGER;
+   v_maxloop INTEGER; 
+BEGIN
+   v_maxloop := 10;
+    WHILE v_maxloop > 0  LOOP
+            v_matches := 0;
+            v_maxloop := v_maxloop -1;
+            SELECT
+                    DISTINCT(invdetail_location_id),
+                    MIN(invfifo_qty_before),
+                    COUNT(invdetail_id)
+                INTO
+                    v_location_id,
+                    v_qty_before,
+                    v_matches
+                    
+                FROM
+                    invfifo
+                LEFT JOIN
+                    invdetail
+                ON
+                    invfifo_invdetail_id = invdetail_id
+                LEFT JOIN
+                    invhist
+                ON 
+                    invhist_id = invdetail_invhist_id
+                
+                WHERE 
+                    invhist_itemsite_id = i_itemsite_id
+                    AND
+                    invfifo_recalc_queued
+                    AND
+                    invdetail_qty > 0
+                GROUP BY
+                    invdetail_location_id
+                LIMIT 1;
+            IF NOT FOUND THEN
+                EXIT;
+            END IF;
+            IF v_matches < 1 THEN
+                EXIT; -- same asa break...
+            END IF;
+            
+            PERFORM invfifo_update_sell(i_itemsite_id, v_location_id, v_qty_before);
+            
+            UPDATE 
+                    invfifo
+                    
+                SET
+                    invfifo_recalc_queued = false
+                FROM
+                    invdetail,invhist
+                
+                WHERE 
+                    invfifo_invdetail_id = invdetail_id
+                    AND
+                    invhist_id = invdetail_invhist_id
+                    AND
+                    invhist_itemsite_id = i_itemsite_id
+                    AND
+                    invdetail_location_id = v_location_id
+                    AND
+                    invfifo_recalc_queued
+                    AND
+                    invdetail_qty > 0;
+                      
+            
+    END LOOP; 
+    
+    RETURN TRUE;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_queued(integer)
+  OWNER TO admin;
+          
+          
+                 
+          
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invfifo_update_values.sql b/pgsql/old/x-fifo-invfifo_update_values.sql
new file mode 100644 (file)
index 0000000..f97ecd0
--- /dev/null
@@ -0,0 +1,289 @@
+
+--This is a full on walk through the transactions in sequence.
+--  - it can find either a buy or sell transaciton.
+--  
+--  - for transfers it should skip the 'buy' as that is costed based on the sell.
+--  
+--  
+
+
+-- IS THIS NEEDED any more??? - 
+--
+--
+--CREATE OR REPLACE FUNCTION invfifo_update_values(integer)
+--    RETURNS  boolean
+--AS $BODY$
+--DECLARE        
+--           
+--    i_itemsite_id  ALIAS FOR $1;
+--    
+--    
+--    
+--    v_no_more  boolean;
+--    v_totalcost     numeric(18, 6);
+--    v_unitcost              numeric(18, 6);
+--    v_stdcost              numeric(18, 6);
+--    
+--    v_run_cost_before              numeric(18, 6);
+--    
+--    v_add_unitcost   numeric(18, 6);
+--    
+--    
+--    v_cost_before             numeric(18, 6);
+--    v_cost_after             numeric(18, 6);
+--    v_cost_before_res             numeric(18, 6);
+--    v_cost_after_res             numeric(18, 6);
+--    
+--    
+--    
+--    v_rev_cost_before         numeric(18, 6);
+--    v_rev_totalcost      numeric(18, 6);
+--    v_rev_location_id   INTEGER;
+--    v_costdiff  numeric(18, 6);
+--    
+--    v_invfifo_curs RECORD;
+--    
+--    invfifo_curs CURSOR (c_itemsite_id integer, c_location_id integer,  c_start_qty numeric(18, 6)) IS
+--              
+--            SELECT
+--                invfifo_invdetail_id,
+--                invfifo_totalcost,
+--                invfifo_qty_before,
+--                invfifo_qty_after,
+--                invfifo_cost_before,
+--                invfifo_cost_after,
+--                invdetail_qty,
+--                invdetail_invhist_id
+--                 
+--                
+--            FROM      
+--                invdetailview
+--            WHERE
+--                   
+--                    invhist_itemsite_id = c_itemsite_id
+--                 
+--            ORDER BY
+--                invhist_transdate ASC,
+--                invdetail_id ASC;
+--                 
+--      
+--BEGIN
+--      
+--    --RAISE NOTICE 'invfifo_update_sell( %, %, %)', i_itemsite_id, i_location_id, i_qty_before;
+--     
+--    SELECT stdcost(itemsite_item_id ) INTO v_stdcost FROM itemsite where itemsite_id = i_itemsite_id;
+--      
+--    FOR v_invfifo_curs IN invfifo_curs (i_itemsite_id) LOOP
+--     
+--        
+--        
+--        -- first determine what type of tx this is..
+--        v_unitcost = v_stdcost;
+--        
+--        if (v_invfifo_curs.invdetail_qty > 0) THEN
+--            -- aquiring product...
+--            
+--            IF (v_invfifo_curs.invhist_transtype = 'RP') THEN
+--                SELECT invfifo_purchase_cost(NEW.invdetail_id) INTO v_unitcost;
+--                v_totalcost = v_unitcost * v_unitcost.invdetail_qty;
+--            END IF;
+--                
+--                
+--            IF (v_invfifo_curs.invhist_transtype = 'RS') THEN
+--                SELECT invfifo_creditmemo_cost(NEW.invdetail_id) INTO v_unitcost;
+--                v_totalcost = v_unitcost * v_unitcost.invdetail_qty;
+--            END IF;
+--            
+--            
+--            -- TRANSFER... it's based on purchase price.
+--            -- WE DO NOT VALUE IT HERE, it will be the next item in the list, and that
+--            -- will trigger a valuation of it..
+--            
+--            IF (v_invfifo_curs.invhist_transtype = 'RL') THEN
+--                CONTINUE;
+--            END IF;
+--            
+--            
+--            -- ADJUSTMENT..
+--            IF (v_invfifo_curs.invhist_transtype = 'AD') THEN
+--                v_totalcost = v_invfifo_curs.value_after - v_invfifo_curs.value_before;
+--                v_unitcost = v_totalcost / v_invfifo_curs.invdetail_qty;
+--            END IF;
+--            
+--            
+--            -- find the last transaction before this one at this location.
+--            
+--            
+--            
+--            
+--            
+--            
+--            
+--    
+--        -- RAISE NOT\qICE 'got record';
+--        -- set up the defaults..
+--        v_cost_before := v_run_cost_before;
+--        v_cost_after  := v_run_cost_before + v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+--        
+--        v_add_unitcost := v_unitcost;
+--        v_totalcost := v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+--        
+--        v_run_cost_before = v_run_cost_before + v_unitcost * ABS(v_invfifo_curs.invdetail_qty);
+--        
+--        if (NOT v_no_more) THEN 
+--        
+--            --RAISE NOTICE 'invfifo_cost_at_qty (%, %, %)' , i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_before;
+--            --RAISE NOTICE 'invfifo_cost_at_qty (%, %, %)' , i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_after;
+--        
+--            SELECT invfifo_cost_at_qty( i_itemsite_id  , i_location_id,  v_invfifo_curs.invfifo_qty_before) INTO v_cost_before_res;
+--            SELECT invfifo_cost_at_qty( i_itemsite_id  , i_location_id , v_invfifo_curs.invfifo_qty_after) INTO v_cost_after_res;
+--        
+--          
+--            IF (v_cost_before_res < 0 OR v_cost_after_res < 0) THEN
+--                
+--            -- we where not able to find the price.
+--                v_no_more := true;
+--                v_run_cost_before = v_cost_after;
+--               
+--                
+--            ELSE
+--                v_cost_before := v_cost_before_res;
+--                v_cost_after  := v_cost_after_res;
+--                v_add_unitcost :=  (v_cost_after - v_cost_before) / ABS(v_invfifo_curs.invdetail_qty);
+--                v_totalcost := (v_cost_after - v_cost_before);
+--                -- set the current unit costs
+--                v_unitcost := v_add_unitcost; 
+--            END IF;
+--            
+--            --RAISE NOTICE
+--            --        'cost @%-% unitcost = % before / after = % % ' ,
+--            --        v_invfifo_curs.invfifo_qty_before, v_invfifo_curs.invfifo_qty_after,
+--            --        v_add_unitcost,
+--            --        v_cost_before_res, v_cost_after_res ;
+--        
+--        END IF;
+--        
+--        -- do not update anything if there was no change..
+--        
+--        IF v_totalcost = v_invfifo_curs.invfifo_totalcost THEN
+--             --RAISE NOTICE 'invfifo_totalcost, SKIP NO CHANGE=%', v_totalcost;
+--             CONTINUE;
+--        END IF;
+--        
+--        
+--        -- update this row...
+--        --RAISE NOTICE 'invfifo_totalcost, set=%', v_totalcost;
+--        
+--        
+--        UPDATE 
+--            invfifo
+--        SET
+--            invfifo_unitcost   = v_add_unitcost,
+--            invfifo_totalcost  = v_totalcost,
+--            invfifo_cost_before = v_cost_before,
+--            invfifo_cost_after = v_cost_after,
+--            invfifo_is_estimate = v_no_more
+--        WHERE
+--            invfifo_invdetail_id = v_invfifo_curs.invfifo_invdetail_id;
+--            
+--            
+--        IF v_invfifo_curs.rev_invdetail_id IS NOT NULL AND v_invfifo_curs.rev_invdetail_id > 0 THEN
+--            -- it's a transfer, and the unit price of the transfer will need adjusting...
+--            
+--            
+--            RAISE NOTICE 'GOT TX FLAG AS RECALC to %, @ d', v_rev_location_id, v_invfifo_curs.rev_invdetail_id;
+--            
+--            -- this in turn will cause a cascade of price revaluations..
+--            -- find the total cost before on that entry.
+--            SELECT
+--                    invfifo_cost_before,
+--                    invfifo_totalcost,
+--                    invdetail_location_id
+--                INTO
+--                    v_rev_cost_before,
+--                    v_rev_totalcost,
+--                    v_rev_location_id
+--                FROM
+--                    invfifo
+--                WHERE
+--                    v_invfifo_curs.rev_invdetail_id;
+--            
+--            
+--            -- to fix this..
+--            -- we have to add costdiff to each future item.
+--            -- TEST: WAS $4 (v_rev_totalcost)  then changed to $3 (v_totalcost)
+--            --         so we have to reduce by $1 all cost/afters/befores...
+--            --
+--            -- The knock on effect from changing the  buy prices will be that
+--            -- anything sold into that location will have to be revalued.
+--            -- there is a concern here that this could get recursive...
+--            
+--            
+--            v_costdiff = v_totalcost - v_rev_totalcost;
+--            
+--            UPDATE
+--                    invfifo
+--                SET
+--                    invfifo_unitcost    = v_add_unitcost,
+--                    invfifo_totalcost   = v_totalcost,
+--                    invfifo_cost_after  =  invfifo_cost_after + v_costdiff,
+--                    invfifo_recalc_queued = false  -- not sure if this will work..
+-- 
+--                WHERE
+--                    v_invfifo_curs.rev_invdetail_id;
+--              
+--            -- update the matching record... and all ones in the future..
+--            
+--            UPDATE 
+--                    invfifo
+--                SET
+--                    
+--                    invfifo_cost_before = invfifo_cost_before + v_costdiff,
+--                    invfifo_cost_after  = invfifo_cost_after +  v_costdiff,
+--                    invfifo_recalc_queued = true
+--                    
+--                FROM
+--                    invdetail,invhist
+--               
+--                WHERE
+--                        invfifo_invdetail_id = invdetail_id
+--                    AND
+--                        invhist_id  = invdetail_invhist_id
+--                    AND
+--                    
+--                        invdetail_location_id = v_rev_location_id
+--                    AND
+--                        ( 
+--                            invhist_transdate > r_invhist.invhist_transdate
+--                            OR
+--                            (
+--                                invhist_transdate = r_invhist.invhist_transdate
+--                                AND
+--                                invhist_id > v_invfifo_curs.rev_invdetail_id
+--                            )
+--                        )
+--                    AND
+--                        invhist_itemsite_id = r_invhist.invhist_itemsite_id
+--                    AND
+--                        invdetail_qty > 0;
+--                
+--                 
+--               
+--        
+--        END IF;
+--         
+--    END LOOP;
+--    
+--   
+--    
+--       
+--    RETURN TRUE;
+--     
+-- END;
+--$BODY$
+--  LANGUAGE plpgsql VOLATILE
+--  COST 100;
+--  
+--ALTER FUNCTION  invfifo_update_values(integer)
+--  OWNER TO admin;
+--          
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invhist_sell_unitcost_calc.sql b/pgsql/old/x-fifo-invhist_sell_unitcost_calc.sql
new file mode 100644 (file)
index 0000000..b772068
--- /dev/null
@@ -0,0 +1,201 @@
+-- This routine should return total cost.
+
+-- using invsell_totalcostbefore is totally unreliable..
+-- 
+
+
+CREATE OR REPLACE FUNCTION invhist_sell_unitcost_calc(integer)
+  RETURNS numeric(16, 6) AS
+$BODY$
+DECLARE
+  -- Variable naming :  i_ = INPUT,  v_ = Variables
+  i_invhist_id         ALIAS FOR $1;
+  v_itemsite_id integer;
+  v_invsell_qtybefore numeric(18, 6) DEFAULT 0;
+  v_invsell_totalcostbefore numeric(12, 2) DEFAULT 0;
+  v_invsell_totalcostafter  numeric(12, 2) DEFAULT 0;
+  v_invsell_qty numeric(18, 6) DEFAULT 0;
+  
+  v_totalcost_avail numeric(12, 2) DEFAULT 0;
+  v_qty_avail numeric(18, 6) DEFAULT 0;
+
+  v_calc_unitcost numeric(16, 6) DEFAULT 0;
+  v_temp_a numeric(16, 6) DEFAULT 0;
+  v_temp_b numeric(16, 6) DEFAULT 0;
+  v_temp_c  numeric(16, 6) DEFAULT 0;
+  
+  
+BEGIN 
+
+    -- find record by invhist_id and get orders
+    -- itemsite_id, qty and qtybefore
+    
+-- add our cost before value here..    
+    SELECT  invsell_itemsite_id,
+            COALESCE(invsell_qtybefore,0),
+            invsell_qty
+         FROM
+            invsell 
+        INTO
+            v_itemsite_id,
+            v_invsell_qtybefore,
+            v_invsell_qty
+        WHERE 
+            invsell_invhist_id = i_invhist_id;
+
+
+   -- RAISE NOTICE 'i_invhist_id=%', i_invhist_id;
+   -- RAISE NOTICE 'v_itemsite_id=%', v_itemsite_id;
+   -- RAISE NOTICE 'v_invsell_qty=%', v_invsell_qty;
+   -- RAISE NOTICE 'v_invsell_qtybefore=%', v_invsell_qtybefore;
+    
+    -- FIND ALL THE STOCK WE CAN USE UP..
+    
+    -- The price of what we need is
+    -- total after - total before - what's left over..
+    
+    
+    
+    
+    
+    
+    
+--BUY: (after | qty)
+--   18   18  ($4.65)
+--   24   6   ($2.63)
+--   28   4
+--   32   4
+   
+--SELL: (before | qty)
+--   0    3
+--   3    2
+--   5    4
+--   9   1
+--   10  3
+--   13  6
+--  19   4
+    
+-- GET THE $ value of stock available before we change.
+
+    SELECT
+        
+        invbuy_totalcostafter 
+            - ((invbuy_qtyafter - v_invsell_qtybefore) * invbuy_unitcost)
+        INTO
+            v_invsell_totalcostbefore
+        FROM
+            invbuy
+        WHERE
+            invbuy_qtyafter >= v_invsell_qtybefore
+            AND
+            invbuy_itemsite_id = v_itemsite_id
+        ORDER BY
+            invbuy_qtyafter ASC
+            
+        LIMIT 1;
+         
+    
+   -- RAISE NOTICE 'v_invsell_totalcostbefore=%', v_invsell_totalcostbefore;
+    
+    
+    -- NEXT JUST DO THE SAME AND find the quantity AFTER..
+      SELECT
+        invbuy_totalcostafter 
+             - ((invbuy_qtyafter - (v_invsell_qtybefore + v_invsell_qty)) * invbuy_unitcost)
+        INTO
+            v_invsell_totalcostafter
+        FROM
+            invbuy
+        WHERE
+            invbuy_qtyafter >= v_invsell_qtybefore + v_invsell_qty
+            AND
+            invbuy_itemsite_id = v_itemsite_id
+        ORDER BY
+            invbuy_qtyafter ASC
+        LIMIT 1;
+         
+    
+    --RAISE NOTICE 'v_invsell_totalcostafter=%', v_invsell_totalcostafter;
+    
+    
+    
+    v_totalcost_avail := COALESCE(v_invsell_totalcostafter- v_invsell_totalcostbefore,0);
+    
+
+    -- 500 is the last,
+    -- sell before = 0 , asking for 498
+    
+    -- avail  is either the amount we are asking for, or less..
+    
+    SELECT
+        max(invbuy_qtyafter) - v_invsell_qtybefore
+          
+    INTO
+        v_qty_avail
+        
+        FROM
+            invbuy
+        WHERE
+            invbuy_itemsite_id = v_itemsite_id
+      
+        LIMIT 1;
+    
+    v_qty_avail := COALESCE(v_qty_avail,0);
+    
+    IF (v_qty_avail > v_invsell_qty) THEN
+        v_qty_avail  := v_invsell_qty;
+    END IF;
+    
+    IF (v_qty_avail <= 0) THEN
+        v_qty_avail  := 0;
+    END IF;
+    
+    
+    --RAISE NOTICE 'v_totalcost_avail=%', v_totalcost_avail;
+    --RAISE NOTICE 'v_qty_avail=%', v_qty_avail;
+   
+
+    
+    
+    -- if not found inventory for sell
+    if (v_qty_avail <= 0) THEN
+        -- if really not found any inventory for sell
+        -- then use last unitcost for this itemsite
+         
+              -- find the last unitcost..
+        SELECT
+                invbuy_unitcost
+            INTO
+                v_calc_unitcost
+            FROM
+                invbuy
+            WHERE
+                invbuy_itemsite_id = v_itemsite_id    
+            ORDER BY
+                invbuy_qtyafter DESC
+            LIMIT
+                1;
+    
+        -- if not found any inventory of this itemsite
+        -- then use standard cost for this itemsite
+        IF (NOT FOUND) THEN
+            v_calc_unitcost = stdcost(v_itemsite_id);
+        END IF;    
+        
+        RETURN ABS(v_calc_unitcost);
+    END IF;
+
+    
+    RETURN ABS(floor(( v_totalcost_avail/ v_qty_avail) * 1000) / 1000);
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+ALTER FUNCTION  invhist_sell_unitcost_calc(integer)
+  OWNER TO admin;
+  
+  
\ No newline at end of file
diff --git a/pgsql/old/x-fifo-invhisttriggerfifo.sql b/pgsql/old/x-fifo-invhisttriggerfifo.sql
new file mode 100644 (file)
index 0000000..04471e5
--- /dev/null
@@ -0,0 +1,593 @@
+--- THIS DOES NOT WORK YET - hence we remove the trigger..
+--DROP TRIGGER _invhisttriggerfifo ON invhist;
+
+
+CREATE OR REPLACE FUNCTION invhisttriggerfifo() RETURNS trigger 
+AS $BODY$
+DECLARE
+    v_trans_qty             numeric(18, 6);
+    v_new_invhist_id        integer;
+    v_invsell_invhist_id        integer;
+
+    v_tmp                   integer;
+    v_qtyafter              numeric(18, 6);
+    v_qtyafter_old          numeric(18, 6);
+    v_qtybefore             numeric(18, 6);
+    v_qtybefore_old         numeric(18, 6);
+    v_qtydiff               numeric(18, 6);
+    v_totalcostdiff         numeric(12, 2);
+    v_totalcostafter        numeric(12, 2);
+    v_totalcostafter_old    numeric(12, 2);
+    
+    v_totalcostbefore_diff  numeric(18, 6);
+
+    v_qty_before_min        numeric(18, 6);
+    
+    v_new_invbuy_data       record;
+    
+    v_is_new                boolean;
+    
+    v_first_transdate       timestamp with time zone;
+    v_first_invhist_id      integer;
+    v_new_totalcost         numeric(12, 2);
+    v_itemsite_id           integer;
+    
+    v_max_invbuy_qtyafter   numeric(12, 2);
+        
+    v_ordernumber           text;
+    
+    v_unitcost              numeric(18, 6);
+    
+    new_inv_buy             record;
+    
+    new_inv_sell            record;
+    
+BEGIN
+    
+    v_trans_qty := NEW.invhist_qoh_after - NEW.invhist_qoh_before;
+    
+    --determine type of transaction, BUY or SELL
+     
+    IF NOT NEW.invhist_posted THEN
+        RETURN NEW;
+    END IF;
+    
+    -- excluding variants where invhist record is already posted, but it transaction don't update value of qty, totalcost, or unitcost.
+    IF TG_OP = 'UPDATE' THEN
+        IF (
+            OLD.invhist_posted
+            AND
+                v_trans_qty = OLD.invhist_qoh_after - OLD.invhist_qoh_before 
+            AND
+                NEW.invhist_value_after - NEW.invhist_value_before = 
+                    OLD.invhist_value_after - OLD.invhist_value_before 
+            AND
+                NEW.invhist_unitcost = OLD.invhist_unitcost
+         )    
+        THEN
+            --RAISE NOTICE 'update made not change'; 
+            RETURN NEW;
+        END IF;
+    END IF;
+
+    
+    -- invhist_transtype | RL << TRANSFER.. -- ignored..
+    -- invhist_transtype | RS (SELL)
+    -- invhist_transtype | AD (BUY OR SELL)
+    -- invhist_transtype | RP (BUY)
+    -- invhist_transtype | SH (SELL)
+            
+    
+    -- if BUY
+    IF NEW.invhist_transtype = 'RP' 
+        OR
+        (NEW.invhist_transtype = 'AD' AND v_trans_qty > 0) THEN
+    
+        
+        
+            SELECT
+                    a2.ordernumber AS ordernumber,
+                    a2.itemsite_id AS itemsite_id, 
+                    a2.qty AS qty,
+                    a2.totalcost AS totalcost,
+                    -- a2.unitcost AS unitcost,
+                    i.invhist_id AS invhist_id,
+                    i.invhist_transdate AS transdate
+                
+                INTO new_inv_buy
+                
+                FROM
+                    (
+                        SELECT
+                            min(invhist_id) AS invhist_id,
+                            invhist_ordnumber  AS ordernumber,
+                            invhist_itemsite_id                             AS itemsite_id,
+                            SUM(invhist_qoh_after - invhist_qoh_before)          AS qty,
+                            SUM(invhist_value_after - invhist_value_before)    AS totalcost 
+                            -- if the tx is voided, then this may result in a zero qty, and 
+                            
+                            --SUM(invhist_value_after - invhist_value_before)
+                            -- / SUM(invhist_qoh_after - invhist_qoh_before)   AS unitcost
+                        FROM
+                            invhist
+                        WHERE
+                            invhist_itemsite_id = NEW.invhist_itemsite_id
+                            AND
+                            invhist_ordnumber = NEW.invhist_ordnumber
+                            AND
+                            invhist_transtype in ('RP', 'AD')
+                            AND
+                            invhist_posted = true
+                        GROUP BY invhist_itemsite_id, invhist_ordnumber
+                    ) AS a2, 
+                    invhist AS i
+                WHERE
+                    a2.invhist_id = i.invhist_id
+                LIMIT
+                    1;
+            
+            v_unitcost = 0.0;
+            if new_inv_buy.qty > 0 THEN
+                v_unitcost = new_inv_buy.totalcost/new_inv_buy.qty;
+            END IF;
+            
+         
+         
+            -- this logic is failing..
+            
+            IF NOT FOUND THEN
+                v_is_new := true;
+                v_first_transdate := NEW.invhist_transdate;
+                v_first_invhist_id := NEW.invhist_id;
+                new_inv_buy.qty := v_trans_qty;
+                v_new_totalcost := NEW.invhist_value_after - NEW.invhist_value_before;
+                v_itemsite_id := NEW.invhist_itemsite_id;
+                --RAISE NOTICE 'set v_is_new = true'; 
+            ELSE
+                v_is_new := false;
+                v_first_transdate := new_inv_buy.transdate;
+                v_first_invhist_id := new_inv_buy.invhist_id;
+                v_new_totalcost := new_inv_buy.totalcost;
+                v_itemsite_id := new_inv_buy.itemsite_id;
+                --RAISE NOTICE 'set v_is_new = false'; 
+            END IF;
+
+            -- it get's this far and creates it..
+            SELECT invdepend_invhist_id
+                INTO
+                    v_tmp
+                FROM
+                    invdepend
+                WHERE
+                    invdepend_invhist_id = NEW.invhist_id;
+                 
+
+            IF NOT FOUND THEN
+                INSERT INTO invdepend 
+                   (invdepend_invhist_id , invdepend_parent_id)
+                VALUES 
+                   ( NEW.invhist_id , v_first_invhist_id );
+            ELSE
+                UPDATE invdepend
+                    SET
+                        invdepend_parent_id = v_first_invhist_id
+                    WHERE
+                        invdepend_invhist_id = NEW.invhist_id;
+            
+            END IF;
+             
+            SELECT invbuy_qtyafter, invbuy_totalcostafter 
+                INTO v_qtyafter, v_totalcostafter 
+                FROM invbuy 
+                    WHERE
+                        invbuy_itemsite_id = v_itemsite_id
+                        AND
+                        ( 
+                            invbuy_transdate <  v_first_transdate 
+                            OR
+                            (
+                                invbuy_transdate =  v_first_transdate 
+                                AND 
+                                invbuy_invhist_id < v_first_invhist_id
+                            )
+                        )
+                ORDER BY invbuy_qtyafter DESC
+                LIMIT 1;
+            
+            v_qtyafter := COALESCE(v_qtyafter, 0) + new_inv_buy.qty;
+            v_totalcostafter := COALESCE(v_totalcostafter, 0) + v_new_totalcost;
+  
+  
+            SELECT
+                    invbuy_invhist_id INTO v_tmp
+                FROM
+                    invbuy
+                WHERE
+                    invbuy_invhist_id = v_first_invhist_id
+                LIMIT
+                    1;
+  
+  
+            IF NOT FOUND THEN
+                -- create a new record..
+                INSERT INTO invbuy 
+                    (
+                        invbuy_invhist_id, invbuy_transdate, 
+                        invbuy_ordnumber, invbuy_itemsite_id, 
+                        
+                        invbuy_qty, invbuy_totalcost, 
+                        invbuy_unitcost, invbuy_transtype, 
+                        
+                        invbuy_qtyafter, invbuy_totalcostafter
+                    ) VALUES (
+                        NEW.invhist_id, NEW.invhist_transdate, 
+                        NEW.invhist_ordnumber, NEW.invhist_itemsite_id, 
+                        
+                        v_trans_qty, v_new_totalcost, 
+                        NEW.invhist_unitcost, 'RP', 
+                        
+                        v_qtyafter, v_totalcostafter
+                    );
+                    
+                v_qtydiff := new_inv_buy.qty;
+                v_totalcostdiff := new_inv_buy.totalcost;
+            ELSE
+                -- get the existing qty recorded..
+                SELECT
+                        invbuy_qtyafter, invbuy_totalcostafter 
+                    INTO
+                        v_qtyafter_old, v_totalcostafter_old 
+                    FROM
+                        invbuy 
+                    WHERE 
+                        invbuy_invhist_id = new_inv_buy.invhist_id;
+                    
+                UPDATE invbuy SET
+                    invbuy_transdate = new_inv_buy.transdate,
+                    invbuy_qty = new_inv_buy.qty,
+                    invbuy_totalcost = new_inv_buy.totalcost,
+                    invbuy_unitcost = v_unitcost,
+                    invbuy_qtyafter = v_qtyafter,
+                    invbuy_totalcostafter = v_totalcostafter
+                WHERE 
+                    invbuy_invhist_id = new_inv_buy.invhist_id;
+                    
+                v_qtydiff := v_qtyafter - v_qtyafter_old;
+                v_totalcostdiff := v_totalcostafter - v_totalcostafter_old;
+            END IF;
+            
+            UPDATE invbuy SET
+                invbuy_qtyafter = invbuy_qtyafter + v_qtydiff,
+                invbuy_totalcostafter = invbuy_totalcostafter + v_totalcostdiff
+            WHERE 
+               invbuy_itemsite_id = v_itemsite_id
+               AND
+               (
+                   invbuy_transdate > v_first_transdate
+                   OR 
+                   (
+                        invbuy_transdate = v_first_transdate 
+                        AND 
+                        invbuy_invhist_id > v_first_invhist_id
+                    )
+                );
+            
+            
+            --RAISE NOTICE 'v_qtyafter=%', v_qtyafter;
+            --RAISE NOTICE 'v_itemsite_id=%',v_itemsite_id;
+            
+            
+            
+            --find record in invsell, which uses it inventories
+            SELECT invsell_invhist_id
+                INTO 
+                  v_first_invhist_id  
+
+                FROM 
+                    invsell 
+                WHERE 
+                    invsell_qtybefore < v_qtyafter 
+                    AND 
+                    invsell_itemsite_id = v_itemsite_id
+                ORDER BY
+                    invsell_qtybefore  ASC
+                LIMIT 1;
+            
+            
+            --RAISE NOTICE 'v_qty_before_min=%', v_qty_before_min;
+            
+            
+            -- recalc FIFO values for all records after current
+            PERFORM invsell_update_after(v_first_invhist_id);
+              
+             
+             
+            
+    -- if SELL
+    
+    
+    
+     
+    
+    ELSIF
+        NEW.invhist_transtype = 'SH'
+        OR
+        (NEW.invhist_transtype = 'AD' AND v_trans_qty < 0)
+        OR
+        NEW.invhist_transtype = 'RS' THEN
+        
+            
+            -- there are problems with this I think around the fact that
+            -- qty is -ve for this transaxtion - and the code seems to think it's +ve.
+             
+            
+            
+            SELECT  a2.ordernumber AS ordernumber,
+                    a2.itemsite_id AS itemsite_id, 
+                    ABS(a2.qty) AS qty,
+                    ABS(a2.current_totalcost) AS current_totalcost,
+                    a2.current_unitcost AS current_unitcost,
+                    i.invhist_id AS invhist_id,
+                    i.invhist_transdate AS transdate
+                INTO
+                    new_inv_sell
+                FROM
+                    (
+                        SELECT
+                            invhist_ordnumber                               AS ordernumber,
+                            invhist_itemsite_id                             AS itemsite_id,
+                            
+                            -- this is returning the wrong thing?
+                            min(invhist_id)                                 AS invhist_id,
+                            SUM(invhist_qoh_after - invhist_qoh_before)     AS qty,
+                            SUM(invhist_value_after - invhist_value_before) AS current_totalcost,
+        
+                            SUM(invhist_value_after - invhist_value_before)
+                                    / SUM(invhist_qoh_after - invhist_qoh_before)
+                                                                              AS current_unitcost
+                            
+                        FROM
+                            invhist
+                        WHERE
+                            invhist_itemsite_id = NEW.invhist_itemsite_id 
+                            AND
+                            invhist_ordnumber = NEW.invhist_ordnumber
+                            AND
+                            (
+                                invhist_transtype = 'SH'
+                                OR
+                                invhist_transtype = 'RS'
+                                OR
+                                invhist_transtype = 'AD'
+                            )
+                --            AND 
+                --            invhist_posted = true
+                        GROUP BY
+                            invhist_itemsite_id, invhist_ordnumber
+                        HAVING
+                            SUM(invhist_qoh_after - invhist_qoh_before) <> 0
+                    ) AS a2,
+                    invhist AS i
+                WHERE
+                    a2.invhist_id = i.invhist_id
+                LIMIT
+                    1;
+         
+            --RAISE NOTICE 'new_inv_sell=%',new_inv_sell;
+            
+            IF (NOT FOUND) THEN
+                 
+                v_is_new := true;
+                v_itemsite_id       := NEW.invhist_itemsite_id;
+                v_first_transdate    := NEW.invhist_transdate;
+                v_first_invhist_id   := NEW.invhist_id;
+                v_ordernumber   := NEW.invhist_ordnumber;
+                
+            ELSE
+             
+                v_is_new := false;
+                v_itemsite_id       := new_inv_sell.itemsite_id;
+                v_first_transdate  := new_inv_sell.transdate;
+                v_first_invhist_id  := new_inv_sell.invhist_id;
+                v_ordernumber := new_inv_sell.ordernumber;
+            END IF;
+            
+            
+            -- do a sanity check...
+            
+            SELECT invsell_invhist_id
+                INTO
+                    v_tmp
+                FROM
+                    invsell
+                WHERE
+                   invsell_itemsite_id = v_itemsite_id
+                   AND
+                   invsell_ordnumber = v_ordernumber;
+            
+            IF (FOUND ) THEN
+                v_is_new := false;
+                IF ( v_tmp != v_first_invhist_id ) THEN
+                    -- the first invhist has changed, should not normmaly happens
+                    -- but occurs when we are bulk trashing invsell/buy..
+                    UPDATE invsell SET
+                            invsell_invhist_id = v_first_invhist_id
+                        WHERE
+                            invsell_invhist_id  = v_tmp;
+                END IF;
+            ELSE
+                v_is_new := true;
+                
+            END IF;
+                
+            
+            
+            
+            
+            
+            
+            
+            -- find the previous qty.. before this transaction..
+            
+            
+            
+            
+            
+            
+            SELECT
+                invdepend_invhist_id
+                INTO v_tmp
+                FROM invdepend
+                WHERE
+                      invdepend_invhist_id = NEW.invhist_id;
+                 
+
+            IF NOT FOUND THEN
+                INSERT INTO invdepend 
+                   (invdepend_invhist_id,  invdepend_parent_id )
+                VALUES 
+                    (NEW.invhist_id, v_first_invhist_id);
+            ELSE
+                UPDATE invdepend
+                    SET
+                        invdepend_parent_id = v_first_invhist_id
+                    WHERE
+                        invdepend_invhist_id = NEW.invhist_id;
+            
+            END IF;
+          
+            
+            SELECT invsell_qtybefore 
+                INTO
+                    v_qtybefore
+                FROM invsell 
+                    WHERE
+                        invsell_itemsite_id = v_itemsite_id
+                        AND   
+                        ( 
+                            invsell_transdate <  v_first_transdate 
+                            OR
+                            (
+                                invsell_transdate =  v_first_transdate 
+                                AND 
+                                invsell_invhist_id < v_first_invhist_id
+                            )
+                        )
+                ORDER BY invsell_qtybefore DESC
+                LIMIT 1;
+            
+            v_qtybefore := COALESCE(v_qtybefore, 0);
+            
+            
+            -- if qtybefore old is ZERO.. then the qty's need updating..
+            IF ((v_qtybefore <= 0.0) OR v_is_new) THEN
+                --RAISE NOTICE 'using sum to find qtybefore';
+                
+                --RAISE NOTICE 'v_first_transdate=%',v_first_transdate;
+                --RAISE NOTICE 'v_first_invhist_id=%',v_first_invhist_id;
+                
+                
+                -- it's probably broken..
+                -- the real qty before is the sum of all the preceding values..
+                SELECT
+                    SUM(invsell_qty)
+                INTO
+                    v_qtybefore
+                FROM invsell 
+                    WHERE
+                        invsell_itemsite_id = v_itemsite_id
+                        AND   
+                        ( 
+                            invsell_transdate <  v_first_transdate 
+                            OR
+                            (
+                                invsell_transdate =  v_first_transdate 
+                                AND 
+                                invsell_invhist_id < v_first_invhist_id
+                            )
+                        )
+                
+                LIMIT 1;
+                v_qtybefore := COALESCE(v_qtybefore, 0);
+
+                --RAISE NOTICE 'v_qtybefore=%s',v_qtybefore;
+            
+            END IF;
+            
+            IF (v_is_new) THEN
+                -- create a new record..
+                INSERT INTO invsell 
+                    (
+                        invsell_invhist_id, invsell_transdate, 
+                        invsell_itemsite_id, invsell_ordnumber, 
+                        
+                        invsell_qty, invsell_current_totalcost, 
+                        invsell_current_unitcost, invsell_transtype, 
+                        
+                        invsell_qtybefore, invsell_is_estimate
+                    ) VALUES (
+                        NEW.invhist_id, NEW.invhist_transdate, 
+                        NEW.invhist_itemsite_id, NEW.invhist_ordnumber, 
+                        
+                        ABS(v_trans_qty), ABS(NEW.invhist_value_after - NEW.invhist_value_before), 
+                        NEW.invhist_unitcost, 'SH', 
+                        
+                        v_qtybefore, true
+                    );
+                v_qtydiff := new_inv_sell.qty;
+                
+            ELSE
+                -- get the existing qty recorded..
+                --RAISE NOTICE 'updating';
+                SELECT
+                        COALESCE(invsell_qtybefore,0)
+                    INTO
+                        v_qtybefore_old 
+                    FROM
+                        invsell 
+                    WHERE
+                        invsell_invhist_id = new_inv_sell.invhist_id;
+                
+                v_qtybefore_old := COALESCE(v_qtybefore_old, 0);
+                   
+                     
+                
+                UPDATE invsell
+                    SET
+                        invsell_transdate   = new_inv_sell.transdate,
+                        invsell_qty         = new_inv_sell.qty,
+                        invsell_current_totalcost = new_inv_sell.current_totalcost,
+                        invsell_current_unitcost = new_inv_sell.current_unitcost,
+                        invsell_qtybefore   = COALESCE(invsell_qtybefore  + v_qtybefore, 0)
+                    WHERE
+                        invsell_invhist_id = new_inv_sell.invhist_id;
+                
+                --RAISE NOTICE 'v_qtybefore=%',v_qtybefore;
+                --RAISE NOTICE 'v_qtybefore_old=%',v_qtybefore_old;
+                v_qtydiff := v_qtybefore - v_qtybefore_old;
+                --RAISE NOTICE 'v_qtydiff=%',v_qtydiff;
+                
+            END IF;
+            
+            -- update qty's after the record..
+            -- THIS IS more than a little borked..
+            -- this is probably the slow bit, if it's triggered on an early record,
+            -- it has to do quite a few updates..
+           
+                    
+            PERFORM invsell_update_after(v_first_invhist_id);
+            
+           
+            
+    END IF;
+        
+    RETURN NEW;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invhisttriggerfifo()
+  OWNER TO admin;
+
diff --git a/pgsql/old/x-fifo-invsell_apply.sql b/pgsql/old/x-fifo-invsell_apply.sql
new file mode 100644 (file)
index 0000000..d829e16
--- /dev/null
@@ -0,0 +1,178 @@
+CREATE OR REPLACE FUNCTION invsell_apply(integer, integer) RETURNS integer
+AS $BODY$
+DECLARE
+    i_invhist_parent_id ALIAS FOR $1;
+    i_invhist_id ALIAS FOR $2;
+
+    invsell_rec RECORD;
+    
+    v_totalcost_delta numeric(12, 2);
+    v_totalcost_new_after numeric(12, 2);
+    v_totalcost_after numeric(12, 2);
+    
+    v_invhist_ordnumber text;
+    v_invhist_docnumber text;
+    
+    v_cohead_cust_id integer;
+    v_cogs_accnt_id integer;
+    
+    v_asset_accnt_id integer;
+    
+    v_costcat_asset_accnt_id integer;
+    v_costcat_shipasset_accnt_id integer;
+    
+BEGIN
+
+
+    -- this get's called on all the individual tranactions that are affected by the invsell value change.
+    
+
+    SELECT
+            invhist_ordnumber, invhist_docnumber 
+        INTO
+            v_invhist_ordnumber, v_invhist_docnumber
+        FROM
+            invhist
+        WHERE
+            invhist_id = i_invhist_id;
+    
+    -- get the sell data for the parent..
+    
+    SELECT *
+        INTO
+            invsell_rec
+        FROM
+            invsell
+        WHERE
+            invsell_invhist_id = i_invhist_parent_id;
+    
+    -- on this transaction work out the change in cost..
+    -- it's based on unit cost...
+    
+    SELECT
+            (invhist_value_before  + (invsell_rec.invsell_calc_unitcost * (invhist_qoh_after - invhist_qoh_before))),
+            invhist_value_after 
+        INTO
+            v_totalcost_new_after, v_totalcost_after
+        FROM
+           invhist
+        WHERE
+            invhist_id = i_invhist_id;
+        
+    
+    -- new after = v_totalcost_before + (invsell_rec.calc_unitcost * (invhist_qoh_after - invhist_qoh_before))
+    
+    v_totalcost_delta := ROUND(v_totalcost_new_after - v_totalcost_after,2);
+    
+    
+    -- this may trigger the invsell update..
+    -- and be a little slow..
+    -- why is this updating all of the unit costs???
+    -- it seems wrong.
+    --RAISE NOTICE 'APPLY to trialbal';
+    
+    -- this needs to apply the 
+    
+    --RAISE NOTICE 'CHANGE unit cost to %', invsell_rec.invsell_calc_unitcost;
+    --RAISE NOTICE 'CHANGE delta cost by %', v_totalcost_delta;
+    --RAISE NOTICE 'ON invhist_id  %', i_invhist_id;
+    
+    UPDATE invhist SET
+        invhist_unitcost = ROUND(invsell_rec.invsell_calc_unitcost,2) ,
+        invhist_value_after = ROUND(invhist_value_after  +    v_totalcost_delta,2) 
+         
+    WHERE
+        invhist_id = i_invhist_id;
+    
+    
+    
+    --   ALTER TABLE invhist DISABLE TRIGGER USER;
+    
+    -- this should just update the tx after with the difference.
+    UPDATE invhist SET
+        invhist_value_after = ROUND(invhist_value_after  +    v_totalcost_delta,2),
+        invhist_value_before = ROUND(invhist_value_before +    v_totalcost_delta,2)
+    WHERE 
+        invhist_id > i_invhist_id
+        AND
+        invhist_itemsite_id = invsell_rec.invsell_itemsite_id;
+    
+    -- ALTER TABLE invhist ENABLE TRIGGER USER;   
+    
+    SELECT cohead_cust_id
+        INTO v_cohead_cust_id
+        FROM cohead 
+        WHERE cohead_number = CASE strpos(v_invhist_ordnumber, '-')
+                        WHEN 0 THEN v_invhist_ordnumber 
+                        ELSE substr(v_invhist_ordnumber, 1, strpos(v_invhist_ordnumber, '-') - 1)
+                    END;
+    
+    v_cogs_accnt_id = resolvecosaccount(invsell_rec.invsell_itemsite_id, v_cohead_cust_id);
+    
+    SELECT costcat_asset_accnt_id, costcat_shipasset_accnt_id
+        INTO v_costcat_asset_accnt_id, v_costcat_shipasset_accnt_id
+        FROM costcat, itemsite
+        WHERE 
+            costcat_id = itemsite_costcat_id
+            AND 
+            itemsite_id = invsell_rec.invsell_itemsite_id;
+    
+    
+    -- turn off the trigger on gltrans, so we can make changes.
+    
+    
+    ALTER TABLE gltrans DISABLE TRIGGER USER;
+    
+    UPDATE gltrans SET
+        gltrans_amount = invsell_rec.invsell_calc_unitcost * invsell_rec.invsell_qty
+    WHERE 
+        (
+            (
+                gltrans_doctype = 'SO'
+                AND
+                gltrans_source = 'S/R'
+            )
+            OR
+            (
+                gltrans_doctype = 'IN'
+                AND
+                gltrans_source = 'S/O'
+            )
+        )
+        AND 
+        gltrans_misc_id = i_invhist_id
+        AND
+        gltrans_accnt_id in (v_costcat_shipasset_accnt_id, v_cogs_accnt_id);
+        
+    UPDATE gltrans SET
+        gltrans_amount = - invsell_rec.invsell_calc_unitcost * invsell_rec.invsell_qty
+    WHERE 
+        (
+            (
+                gltrans_doctype = 'SO'
+                AND
+                gltrans_source = 'S/R'
+            )
+            OR
+            (
+                gltrans_doctype = 'IN'
+                AND
+                gltrans_source = 'S/O'
+            )
+        )
+        AND 
+        gltrans_misc_id = i_invhist_id
+        AND
+        gltrans_accnt_id = v_costcat_asset_accnt_id;
+    
+    ALTER TABLE gltrans ENABLE TRIGGER USER;
+    
+    RETURN 1;
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invsell_apply(integer, integer)
+  OWNER TO admin;
diff --git a/pgsql/old/x-fifo-invsell_apply_order.sql b/pgsql/old/x-fifo-invsell_apply_order.sql
new file mode 100644 (file)
index 0000000..1324097
--- /dev/null
@@ -0,0 +1,43 @@
+CREATE OR REPLACE FUNCTION invsell_apply_order(integer) RETURNS integer
+AS $BODY$
+DECLARE
+    i_invsell_invhist_id ALIAS FOR $1;
+
+    invsell_rec RECORD;
+    
+    v_totalcost_delta numeric(12, 2);
+    
+    v_invhist_ordnumber text;
+    
+BEGIN
+
+    SELECT * INTO invsell_rec
+            FROM invsell
+            WHERE invsell_invhist_id = i_invsell_invhist_id;
+    
+    v_totalcost_delta := invsell_rec.invsell_calc_totalcost - invsell_rec.invsell_current_totalcost;
+
+        
+    UPDATE itemsite 
+                SET 
+                itemsite_value = COALESCE(invsell_rec.invsell_totalcostbefore,0) + invsell_rec.invsell_calc_totalcost
+            WHERE
+                 itemsite_id = invsell_rec.invsell_itemsite_id;
+    
+    UPDATE coitem
+                SET
+                coitem_unitcost = invsell_rec.invsell_calc_unitcost
+            FROM cohead
+            WHERE 
+                coitem_cohead_id = cohead_id
+                AND
+                cohead_number || '.' || coitem_linenumber = invsell_rec.invsell_ordnumber;
+                
+    RETURN 1;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invsell_apply_order(integer)
+  OWNER TO admin;
diff --git a/pgsql/old/x-fifo-invsell_apply_trialbal.sql b/pgsql/old/x-fifo-invsell_apply_trialbal.sql
new file mode 100644 (file)
index 0000000..af48987
--- /dev/null
@@ -0,0 +1,60 @@
+CREATE OR REPLACE FUNCTION invsell_apply_trialbal (integer, timestamp with time zone) RETURNS integer
+AS $BODY$
+DECLARE
+    i_accnt_id   ALIAS FOR $1;
+    i_mininvsell_transdate ALIAS FOR $2;
+BEGIN
+
+    
+    
+    
+    
+    UPDATE trialbal t SET
+        trialbal_credits = ao_gltrans_credit,
+        trialbal_debits  = ao_gltrans_debit,
+        trialbal_ending = trialbal_beginning - trialbal_debits + trialbal_credits    
+    FROM 
+        (
+            SELECT 
+                a1_period_id ao_period_id, a1_gltrans_credit ao_gltrans_credit, 
+                a2_gltrans_debit ao_gltrans_debit
+            FROM
+                (
+                    SELECT period_id a1_period_id, sum(gltrans_amount) a1_gltrans_credit 
+                    FROM gltrans 
+                    JOIN period ON gltrans_date BETWEEN period_start AND period_end
+                    WHERE 
+                        gltrans_date > i_mininvsell_transdate
+                        AND
+                        gltrans_amount > 0
+                    GROUP BY
+                        period_id
+                ) a1,
+                
+                (
+                    SELECT period_id a2_period_id, sum(gltrans_amount) a2_gltrans_debit 
+                    FROM gltrans 
+                    JOIN period ON gltrans_date BETWEEN period_start AND period_end
+                    WHERE 
+                        gltrans_date > i_mininvsell_transdate
+                        AND
+                        gltrans_amount < 0
+                    GROUP BY
+                        period_id
+                ) a2
+            WHERE a1_period_id = a2_period_id
+        ) ao
+        
+    WHERE 
+        trialbal_period_id = ao_period_id
+        AND 
+        trialbal_accnt_id = i_accnt_id;
+    RETURN 1;
+        
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invsell_apply_trialbal(integer, timestamp with time zone)
+  OWNER TO admin;
diff --git a/pgsql/old/x-fifo-invsell_update_after.sql b/pgsql/old/x-fifo-invsell_update_after.sql
new file mode 100644 (file)
index 0000000..6476d4b
--- /dev/null
@@ -0,0 +1,121 @@
+-- method to update all rows after a invhist_id in the 
+
+ -- select invsell_update_after(63977);
+
+CREATE OR REPLACE FUNCTION invsell_update_after(integer ) RETURNS integer
+AS $BODY$
+DECLARE
+    i_invhist_id ALIAS FOR $1;
+
+    v_invsell_rec RECORD;
+    v_itemsite_id integer;
+    v_transdate date;
+    v_invsell_qty numeric(12, 2);
+    v_invsell_qtyafter numeric(12, 2);
+    v_max_invbuy_qtyafter numeric(12, 2);
+    v_unitcost numeric(12, 2);
+    v_invsell_totalcostafter numeric(16, 2);
+    
+    invsell_curs CURSOR (c_itemsite_id integer, c_first_transdate date,  c_first_invhist_id integer) FOR
+                SELECT
+                        * 
+                    FROM
+                        invsell
+                    WHERE
+                        invsell_itemsite_id = c_itemsite_id
+                    AND
+                    (
+                        invsell_transdate > c_first_transdate
+                        OR 
+                        (
+                            invsell_transdate = c_first_transdate 
+                            AND 
+                            invsell_invhist_id > c_first_invhist_id
+                        )
+                    )
+                ORDER BY
+                    invsell_transdate ASC, invsell_invhist_id ASC ;
+    
+BEGIN
+
+    -- fetch the specific row, and update that first,
+    
+    SELECT
+            invsell_itemsite_id,
+            invsell_transdate,
+            invsell_qtybefore + invsell_qty as invsell_qtyafter,
+            invsell_qty,
+            COALESCE(invsell_totalcostbefore,0)   as invsell_totalcostafter
+        INTO
+            v_itemsite_id,
+            v_transdate,
+            v_invsell_qtyafter,
+            v_invsell_qty,
+            v_invsell_totalcostafter
+        FROM
+            invsell
+        WHERE
+            invsell_invhist_id = i_invhist_id;
+    
+    
+    v_unitcost := invhist_sell_unitcost_calc(i_invhist_id);
+    -- update the current row..
+    
+    UPDATE 
+            invsell
+        SET
+            invsell_calc_unitcost = v_unitcost,
+            invsell_calc_totalcost = ROUND(v_unitcost * v_invsell_qty,2),
+            invsell_totalcostbefore = v_invsell_totalcostafter
+        WHERE
+            invsell_invhist_id = i_invhist_id;
+            
+    
+    v_invsell_totalcostafter := ROUND(v_invsell_totalcostafter + (v_unitcost * v_invsell_qty),2);
+    -- find our maximum stock..
+    SELECT max(invbuy_qtyafter)    
+            INTO
+                v_max_invbuy_qtyafter
+            FROM
+                invbuy
+            WHERE
+                invbuy_itemsite_id = v_itemsite_id;
+        
+    OPEN invsell_curs(v_itemsite_id, v_transdate, i_invhist_id );
+    
+    FETCH invsell_curs into v_invsell_rec;
+    WHILE FOUND LOOP
+    
+        v_unitcost := ROUND(invhist_sell_unitcost_calc(v_invsell_rec.invsell_invhist_id),2);
+        
+        UPDATE invsell
+            SET
+                invsell_qtybefore = v_invsell_qtyafter,
+                invsell_totalcostbefore = v_invsell_totalcostafter,
+                invsell_calc_unitcost = v_unitcost,
+                invsell_calc_totalcost = v_unitcost * v_invsell_rec.invsell_qty,
+                invsell_is_estimate = ((v_invsell_qtyafter + v_invsell_rec.invsell_qty) > v_max_invbuy_qtyafter)
+                
+            WHERE invsell_invhist_id = v_invsell_rec.invsell_invhist_id;
+        
+        v_invsell_qtyafter := v_invsell_qtyafter + v_invsell_rec.invsell_qty;
+        v_invsell_totalcostafter := v_invsell_totalcostafter + (v_unitcost * v_invsell_rec.invsell_qty );
+        
+        FETCH invsell_curs into v_invsell_rec;
+        
+    END LOOP;
+    CLOSE invsell_curs;
+    
+        
+        RETURN 1;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invsell_update_after(integer)
+  OWNER TO admin;
+
+
+    
diff --git a/pgsql/old/x-fifo-itemcost_acquire.sql b/pgsql/old/x-fifo-itemcost_acquire.sql
new file mode 100644 (file)
index 0000000..58f0502
--- /dev/null
@@ -0,0 +1,23 @@
+CREATE OR REPLACE FUNCTION itemcost_acquire (integer, numeric(16, 6)) RETURNS numeric(16, 6)
+AS $BODY$
+DECLARE
+  -- Variable naming :  i_ = INPUT,  v_ = Variables
+  i_itemsite_id         ALIAS FOR $1;
+  i_unitcost             ALIAS FOR $2;
+  
+BEGIN 
+
+    -- if FIFO method not used 
+    IF ( v_itemsite_costmethod <> 'F' AND NOT fetchMetricBool('UseStandardAsFIFO') ) THEN
+        RETURN stdcost(i_itemsite_id);
+    END IF;
+    
+    RETURN i_unitcost;
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  itemcost_acquire(integer, numeric(16, 6))
+  OWNER TO admin;
diff --git a/pgsql/old/x-fifo-itemcost_dispense.sql b/pgsql/old/x-fifo-itemcost_dispense.sql
new file mode 100644 (file)
index 0000000..7945072
--- /dev/null
@@ -0,0 +1,165 @@
+CREATE OR REPLACE FUNCTION itemcost_dispense (integer, numeric(18, 6))  RETURNS  numeric(16, 6)
+AS $BODY$
+DECLARE
+  -- Variable naming :  i_ = INPUT,  v_ = Variables
+  i_itemsite_id         ALIAS FOR $1;
+  i_invsell_qty         ALIAS FOR $2;
+  v_invsell_qtybefore numeric(18, 6) DEFAULT 0;
+   v_invsell_calc_totalcost numeric(12, 2) DEFAULT 0;
+  
+  v_invsell_qty numeric(18, 6) DEFAULT 0;
+  v_itemsite_costmethod character(1);
+  
+  v_totalcost_avail numeric(12, 2) DEFAULT 0;
+  v_qty_avail_before numeric(18, 6) DEFAULT 0;
+  v_qty_avail numeric(18, 6) DEFAULT 0;
+  v_qty_sold numeric(18, 6) DEFAULT 0;
+  
+  v_invsell_totalcostbefore numeric(18, 6) DEFAULT 0;
+  v_invsell_totalcostafter numeric(18, 6) DEFAULT 0;
+  
+
+  v_calc_unitcost numeric(16, 6) DEFAULT 0;
+  
+BEGIN 
+
+    -- find record by invhist_id and get orders
+    -- itemsite_id, qty and qtybefore
+
+    i_invsell_qty := abs(i_invsell_qty);
+
+    SELECT itemsite_costmethod INTO v_itemsite_costmethod
+        FROM itemsite 
+        WHERE itemsite_id = i_itemsite_id;
+    
+    -- if FIFO method not used 
+    IF ( v_itemsite_costmethod <> 'F' AND NOT fetchMetricBool('UseStandardAsFIFO') ) THEN
+        RAISE NOTICE 'NOT FIFO?';
+        RETURN stdcost(i_itemsite_id);
+    END IF;
+    
+    
+    -- how many do we have.
+    SELECT
+            COALESCE(max(invbuy_qtyafter), 0)
+        INTO
+           v_qty_avail_before
+        FROM
+            invbuy
+        WHERE
+            invbuy_itemsite_id = i_itemsite_id;
+             
+    
+    
+    -- how many have been sold, 
+    
+    SELECT
+            COALESCE(max(invsell_qtybefore + invsell_qty),0)
+        INTO
+            v_qty_sold
+        FROM
+            invsell
+        WHERE
+            invsell_itemsite_id = i_itemsite_id;
+             
+    v_qty_avail := v_qty_avail_before - v_qty_sold;
+   
+    -- not enough.. 
+    if (v_qty_avail < i_invsell_qty ) THEN
+    
+        -- find the last unitcost..
+        SELECT
+                invbuy_unitcost
+            INTO
+                v_calc_unitcost
+            FROM
+                invbuy
+            WHERE
+                invbuy_itemsite_id = i_itemsite_id    
+            ORDER BY
+                invbuy_qtyafter DESC
+            LIMIT
+                1;
+        
+        
+        RAISE NOTICE 'QTY < 0 or not found..';
+        RAISE NOTICE 'v_calc_unitcost=%', v_calc_unitcost;
+        -- if really not found any inventory for sell
+        
+        -- then use last unitcost for this itemsite
+        
+        -- if not found any inventory of this itemsite
+        -- then use standard cost for this itemsite
+        
+        IF (NOT FOUND) THEN
+            v_calc_unitcost = stdcost(i_itemsite_id);
+            -- what if that return nothing...
+        END IF;
+        
+        RAISE NOTICE 'v_calc_unitcost=%', v_calc_unitcost;
+        
+        RETURN v_calc_unitcost;
+
+    END IF;
+    
+    
+    -- FINALLY DO OUR PRICING...
+    -- same as calc code..
+    
+    SELECT
+        
+        invbuy_totalcostafter 
+            - ((invbuy_qtyafter - v_qty_sold) * invbuy_unitcost)
+        INTO
+            v_invsell_totalcostbefore
+        FROM
+            invbuy
+        WHERE
+            invbuy_qtyafter >= v_qty_sold
+            AND
+            invbuy_itemsite_id = i_itemsite_id
+        ORDER BY
+            invbuy_qtyafter ASC
+            
+        LIMIT 1;
+         
+    
+    RAISE NOTICE 'v_invsell_totalcostbefore=%', v_invsell_totalcostbefore;
+    
+    RAISE NOTICE 'v_qty_sold=%', v_qty_sold;
+    RAISE NOTICE 'i_invsell_qty=%', i_invsell_qty;
+    
+    -- NEXT JUST DO THE SAME AND find the quantity AFTER..
+    SELECT
+        invbuy_totalcostafter 
+             - ((invbuy_qtyafter - (v_qty_sold + i_invsell_qty)) * invbuy_unitcost)
+        INTO
+            v_invsell_totalcostafter
+        FROM
+            invbuy
+        WHERE
+            invbuy_qtyafter >= v_qty_sold + i_invsell_qty
+            AND
+            invbuy_itemsite_id = i_itemsite_id
+        ORDER BY
+            invbuy_qtyafter ASC
+        LIMIT 1;
+         
+    
+    RAISE NOTICE 'v_invsell_totalcostafter=%', v_invsell_totalcostafter;
+    
+    
+    
+    v_totalcost_avail := COALESCE(v_invsell_totalcostafter- v_invsell_totalcostbefore,0);
+    
+     
+    RETURN ABS(floor(( v_totalcost_avail/ i_invsell_qty) * 1000) / 1000);
+    
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  itemcost_dispense(integer, numeric(18, 6))
+  OWNER TO admin;
diff --git a/pgsql/old/x-netsuite-eoy-fix2009.sql b/pgsql/old/x-netsuite-eoy-fix2009.sql
new file mode 100644 (file)
index 0000000..c5a7dc0
--- /dev/null
@@ -0,0 +1,64 @@
+
+
+UPDATE accnt SET accnt_curr_id  = basecurrid() WHERE accnt_subaccnttype_code != 'CA';
+
+
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+        where period_end <= '2008-09-30' and period_closed = false and period_freeze = false order by period_start ASC;
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+        where period_end <= '2008-09-30' and period_closed = false and period_freeze = false order by period_start ASC;        
+SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2008-09-30';
+
+
+
+--
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+--
+SELECT  netsuite_eoyfix( '2009-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+
+
+
+
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2009-09-30' and period_closed = false and period_freeze = false order by period_start ASC;
+    
+-- try a couple of times
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2009-09-30' and period_closed = false and period_freeze = false order by period_start ASC;
+SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2009-09-30';
+
+---- expenses...
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'AP';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+--SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+----
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'AP';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+----
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+--
+
+
\ No newline at end of file
diff --git a/pgsql/old/x-netsuite-eoy-fix2010.sql b/pgsql/old/x-netsuite-eoy-fix2010.sql
new file mode 100644 (file)
index 0000000..36cd534
--- /dev/null
@@ -0,0 +1,46 @@
+
+
+
+
+
+---- expenses...
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+SELECT  netsuite_eoyfix( '2010-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+
+
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2010-09-30' and period_closed = false and period_freeze = false order by period_start ASC;
+-- try a couple of times
+select closeAccountingPeriod(period_id) ,  freezeAccountingPeriod(period_id) FROM period
+    where period_end <= '2010-09-30' and period_closed = false and period_freeze = false order by period_start ASC;
+    
+SELECT closeAccountingYearPeriod(yearperiod_id) FROM yearperiod where yearperiod_end = '2010-09-30';
+
+
+----
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'AP';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+----
+--SELECT  netsuite_eoyfix( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+--
+
+
\ No newline at end of file
diff --git a/pgsql/old/x-netsuite-eoyfix-sg-2011.sql b/pgsql/old/x-netsuite-eoyfix-sg-2011.sql
new file mode 100644 (file)
index 0000000..ed520f9
--- /dev/null
@@ -0,0 +1,71 @@
+
+----
+
+
+
+
+
+
+
+SELECT  netsuite_eoyfix( '2010-10-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2010-11-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2010-12-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-01-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-02-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-03-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-04-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-05-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-06-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-07-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+SELECT  netsuite_eoyfix( '2011-08-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code  IN
+        ( 'EXP',  'AP', 'AR',  'SI',  'FA',  'EDC',  'COGS',  'CAS', 'CL') OR  accnt_number  = '394';
+
+
+
+
+
+
+-- includes reatined earnings...
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'EDC';
+
+
+
+--
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXP' ORDER BY accnt_descrip ASC;
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', -1) from accnt where accnt_subaccnttype_code = 'EXPV' ORDER BY accnt_descrip ASC;
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG', 1) from accnt where accnt_subaccnttype_code = 'AP';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'AR';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'SI';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'FA';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  1) from accnt where accnt_subaccnttype_code = 'IN';
+
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',  -1) from accnt where accnt_subaccnttype_code = 'COGS';
+
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_subaccnttype_code = 'CAS';
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   -1) from accnt where accnt_subaccnttype_code = 'CL';
+--
+-- any CAS..
+-- Paypal USD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '416';
+--- HKD transfer
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '394';
+-- c/a joanna bush
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '285';
+--DBS current
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '283';
+-- DBS USD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '288';
+
+
+--paypal SGD
+SELECT  netsuite_eoyfix_based( '2011-09-30'::date, accnt_id,  'SG',   1) from accnt where accnt_number  = '415';
\ No newline at end of file
diff --git a/pgsql/postapcreditmemoapplication.sql b/pgsql/postapcreditmemoapplication.sql
new file mode 100644 (file)
index 0000000..bb70b31
--- /dev/null
@@ -0,0 +1,176 @@
+
+
+-- modified to allow date to be specified, and rounding on 'toApply'
+-- updated to match current version (12mar2013)
+
+
+-- Function: postapcreditmemoapplication(integer)
+
+-- DROP FUNCTION postapcreditmemoapplication(integer);
+
+CREATE OR REPLACE FUNCTION postapcreditmemoapplication(integer, date)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pApopenid ALIAS FOR $1;
+  i_applydate ALIAS FOR $2;
+  _src RECORD;
+  _r RECORD;
+  _totalAmount NUMERIC := 0;
+  _exchGain NUMERIC := 0.0; 
+  _apaccntid INTEGER;
+
+BEGIN
+
+  SELECT apopen_docnumber, (apopen_amount - apopen_paid) AS balance,
+--         ROUND(SUM(currtocurr(apcreditapply_curr_id, apopen_curr_id,
+--                 apcreditapply_amount, i_applydate)),2) AS toApply,
+     SUM(apcreditapply_amount) AS toApply,
+     apopen_curr_rate INTO _src
+  FROM apopen, apcreditapply
+  WHERE ( (apcreditapply_source_apopen_id=apopen_id)
+   AND (apopen_id=pApopenid) )
+  GROUP BY apopen_docnumber, apopen_amount, apopen_paid,
+       apopen_curr_rate;
+  IF (NOT FOUND) THEN
+    RETURN -1;
+  ELSIF (_src.toApply = 0) THEN
+    RETURN -2;
+  ELSIF (_src.toApply > _src.balance) THEN
+    RAISE NOTICE 'FAILED apply % is > balance %', _src.toApply , _src.balance;
+    RETURN -3;
+--  ELSIF (_src.toApply IS NULL AND _src.junk IS NOT NULL) THEN
+--    RETURN -4;        -- missing exchange rate
+  ELSIF (_src.toApply IS NULL) THEN
+    RETURN -6;        -- amount to apply is NULL for some unknown reason
+  END IF;
+
+  SELECT apopen_id, apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_amount,
+         apopen_curr_id, apopen_curr_rate, apopen_docdate, apopen_accnt_id INTO _src
+  FROM apopen
+  WHERE (apopen_id=pApopenid);
+  IF (NOT FOUND) THEN
+    RETURN -5;
+  END IF;
+
+  FOR _r IN SELECT apcreditapply_id, apcreditapply_target_apopen_id,
+           apcreditapply_amount AS apply_amountSource,
+                   currToCurr(apcreditapply_curr_id, apopen_curr_id,
+                              apcreditapply_amount, i_applydate) AS apply_amountTarget,
+                   apopen_id, apopen_doctype, apopen_docnumber, apopen_curr_id, apopen_curr_rate, apopen_docdate
+            FROM apcreditapply, apopen
+            WHERE ( (apcreditapply_source_apopen_id=pApopenid)
+             AND (apcreditapply_target_apopen_id=apopen_id) ) LOOP
+
+    IF (_r.apply_amountTarget IS NULL) THEN
+      RETURN -4;    -- missing exchange rate
+    END IF;
+
+    IF (_r.apply_amountTarget > 0) THEN
+
+--  Update the apopen item to post the paid amount
+      UPDATE apopen
+      SET apopen_paid = (apopen_paid + _r.apply_amountTarget)
+      WHERE (apopen_id=_r.apcreditapply_target_apopen_id);
+
+      UPDATE apopen
+      SET apopen_open = false,
+        apopen_closedate = current_date
+      WHERE ( (apopen_id=_r.apcreditapply_target_apopen_id)
+        AND (apopen_amount <= apopen_paid) );
+
+--  Cache the running amount posted
+      _totalAmount := (_totalAmount + _r.apply_amountSource);
+
+--  Record the application
+      INSERT INTO apapply
+      ( apapply_vend_id, apapply_amount,
+        apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
+        apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
+        apapply_postdate, apapply_journalnumber, apapply_username, apapply_curr_id )
+      VALUES
+      ( _src.apopen_vend_id, round(_r.apply_amountSource, 2),
+        pApopenid, 'C', _src.apopen_docnumber,
+        _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
+        i_applydate, 0, getEffectiveXtUser(), _src.apopen_curr_id );
+
+    END IF;
+
+--  Delete the posted apcreditapply record
+    DELETE FROM apcreditapply
+    WHERE (apcreditapply_id=_r.apcreditapply_id);
+
+  END LOOP;
+
+--  Record the amount posted and mark the source apopen as closed if it is completely posted
+  UPDATE apopen
+  SET apopen_paid = (apopen_paid + _totalAmount)
+  WHERE (apopen_id=pApopenid);
+
+  UPDATE apopen
+  SET apopen_open = false,
+    apopen_closedate = current_date
+  WHERE ( (apopen_id=pApopenid)
+    AND (apopen_amount <= apopen_paid) );
+  IF (_r.apopen_curr_id = _src.apopen_curr_id) THEN
+    IF (_r.apopen_docdate > _src.apopen_docdate) THEN
+      _exchGain := (_totalAmount / _r.apopen_curr_rate - _totalAmount / _src.apopen_curr_rate) * -1;
+    ELSE
+      _exchGain := _totalAmount / _src.apopen_curr_rate - _totalAmount / _r.apopen_curr_rate;
+    END IF;
+  END IF;
+
+
+  IF (_src.apopen_accnt_id > -1) THEN
+    _apaccntid := _src.apopen_accnt_id;
+  ELSE 
+    _apaccntid := findAPAccount(_src.apopen_vend_id);
+  END IF;
+
+  PERFORM insertGLTransaction(fetchJournalNumber('AP-MISC'), 'A/P', 'CM',
+                            _src.apopen_docnumber, 'CM Application',
+                            _apaccntid,
+                getGainLossAccntId(_apaccntid), -1,
+                            _exchGain,
+                            i_applydate);
+
+
+  RETURN pApopenid;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+ALTER FUNCTION postapcreditmemoapplication(integer,date)
+  OWNER TO admin;
+
+
+
+
+--- BC wrapper..
+
+CREATE OR REPLACE FUNCTION postapcreditmemoapplication(integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  i_id  ALIAS FOR $1;
+  v_ret INTEGER;
+  
+
+
+BEGIN
+    SELECT postapcreditmemoapplication(i_id, CURRENT_DATE) INTO v_ret;
+    RETURN v_ret;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postapcreditmemoapplication(integer)
+  OWNER TO admin;
+
diff --git a/pgsql/postitemlocseries.sql.sql b/pgsql/postitemlocseries.sql.sql
new file mode 100644 (file)
index 0000000..16f8812
--- /dev/null
@@ -0,0 +1,42 @@
+
+CREATE OR REPLACE FUNCTION postitemlocseries(integer)
+  RETURNS boolean AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pItemlocseries ALIAS FOR $1;
+  _result INTEGER;
+BEGIN
+    
+  PERFORM postIntoTrialBalance(itemlocpost_glseq)
+
+
+  FROM (
+    SELECT DISTINCT itemlocpost_glseq, gltrans_accnt_id
+    FROM itemlocpost
+      JOIN gltrans ON (itemlocpost_glseq=gltrans_sequence)
+    WHERE (itemlocpost_itemlocseries=pItemlocseries)
+    ORDER BY gltrans_accnt_id
+  ) AS data;
+  
+--RAISE EXCEPTION 'after post trialbal %', clock_timestamp() - v_ts;  -- shows 0.08s
+   --RAISE EXCEPTION 'after post trialbal %', clock_timestamp() - v_ts;
+
+  PERFORM postInvHist(invhist_id)
+  FROM invhist
+    JOIN itemsite ON (invhist_itemsite_id=itemsite_id)
+  WHERE ( (invhist_series=pItemlocseries)
+  AND ( NOT invhist_posted) 
+  AND ( NOT itemsite_freeze) );
+
+  DELETE FROM itemlocpost WHERE (itemlocpost_itemlocseries=pItemlocseries);
+--RAISE EXCEPTION 'after post trialbal %', clock_timestamp() - v_ts; -- shows 0.09
+  RETURN TRUE;
+  
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postitemlocseries(integer)
+  OWNER TO admin;
diff --git a/pgsql/postporeturncreditmemo.sql b/pgsql/postporeturncreditmemo.sql
new file mode 100644 (file)
index 0000000..502e5de
--- /dev/null
@@ -0,0 +1,192 @@
+-- modified to use poreject_date
+
+-- Function: postporeturncreditmemo(integer, numeric)
+
+-- DROP FUNCTION postporeturncreditmemo(integer, numeric);
+
+CREATE OR REPLACE FUNCTION postporeturncreditmemo(integer, numeric)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pPorejectId ALIAS FOR $1;
+  pAmount ALIAS FOR $2;
+  _p RECORD;
+  _a RECORD;
+  _itemsiteId INTEGER;
+  _docNumber TEXT;
+  _sequence INTEGER;
+  _journalNumber INTEGER;
+  _apopenid INTEGER;
+  _exchGainItem NUMERIC;
+  _itemAmount_base NUMERIC;
+  _itemAmount NUMERIC;
+  _glseriesTotal NUMERIC;
+  _tmpTotal NUMERIC;
+  _test INTEGER;
+  _exchDate DATE;
+  _tax RECORD;
+  _taxAmount NUMERIC := 0;
+  _taxAmount_base NUMERIC;
+  _apaccntid INTEGER;
+
+BEGIN
+--Set things up
+  SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
+  SELECT fetchGLSequence() INTO _sequence;
+  SELECT fetchJournalNumber('AP-MISC') INTO _journalNumber;
+  SELECT fetchapmemonumber() INTO _docNumber;
+  _glseriesTotal := 0;
+
+--Get poreject data
+  SELECT pohead_vend_id, pohead_number, pohead_curr_id, pohead_orderdate, pohead_taxzone_id,
+         poitem_id, poitem_itemsite_id,poitem_expcat_id, poitem_taxtype_id,
+        itemsite_costcat_id, poreject_qty, poreject_date,
+        ('Return of Item ' || COALESCE(item_number,poitem_vend_item_number)
+           || ', qty. ' || formatqty(poreject_qty)) AS notes,
+        poreject_value AS value,
+        currToBase(pohead_curr_id,(poitem_unitprice * poreject_qty),poreject_date) AS itemAmount_base,
+        (poitem_unitprice * poreject_qty) AS itemAmount
+        INTO _p
+  FROM pohead, poreject, poitem
+        LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
+        LEFT OUTER JOIN item ON (itemsite_item_id=item_id)
+  WHERE ((poreject_poitem_id=poitem_id)
+  AND (pohead_id=poitem_pohead_id)
+  AND (poreject_id=pPorejectId));
+
+  _itemAmount := _p.itemAmount;
+  _itemAmount_base := _p.itemAmount_base;
+  IF (pAmount IS NOT NULL) THEN
+    _itemAmount := pAmount;
+    _itemAmount_base := currToBase(_p.pohead_curr_id, pAmount, _p.poreject_date);
+  END IF;
+  
+
+--  Grab the G/L Accounts
+  IF (COALESCE(_p.poitem_itemsite_id, -1) = -1) THEN
+    SELECT pp.accnt_id AS pp_accnt_id,
+           lb.accnt_id AS lb_accnt_id INTO _a
+    FROM expcat, accnt AS pp, accnt AS lb
+    WHERE ( (expcat_purchprice_accnt_id=pp.accnt_id)
+     AND (expcat_liability_accnt_id=lb.accnt_id)
+     AND (expcat_id=_p.poitem_expcat_id) );
+    IF (NOT FOUND) THEN
+      RAISE EXCEPTION 'Cannot Post Credit Memo due to unassigned G/L Accounts.';
+    END IF;
+  ELSE
+    SELECT pp.accnt_id AS pp_accnt_id,
+           lb.accnt_id AS lb_accnt_id INTO _a
+    FROM costcat, accnt AS pp, accnt AS lb
+    WHERE ( (costcat_purchprice_accnt_id=pp.accnt_id)
+     AND (costcat_liability_accnt_id=lb.accnt_id)
+     AND (costcat_id=_p.itemsite_costcat_id) );
+    IF (NOT FOUND) THEN
+      RAISE EXCEPTION 'Cannot Post Credit Memo due to unassigned G/L Accounts.';
+    END IF;
+  END IF;
+
+--  AP Open Item record
+    INSERT INTO apopen
+    ( apopen_id, apopen_username, apopen_journalnumber,
+      apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
+      apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
+      apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_accnt_id, apopen_curr_id,
+      apopen_closedate )
+    VALUES
+    ( _apopenid, getEffectiveXtUser(), _journalNumber,
+      _p.pohead_vend_id, _docNumber, 'C', _p.pohead_number,
+      _p.poreject_date, _p.poreject_date, _p.poreject_date, -1,
+      round(_itemAmount, 2), 0, (round(_itemAmount, 2) <> 0), _p.notes, -1, _p.pohead_curr_id,
+      CASE WHEN (round(_itemAmount, 2) = 0) THEN _p.poreject_date END );
+
+-- Taxes
+    FOR _tax IN
+      SELECT taxdetail_tax_id, sum(taxdetail_tax) AS taxdetail_tax,
+        currToBase(_p.pohead_curr_id, round(sum(taxdetail_tax),2), _p.poreject_date) AS taxbasevalue
+      FROM calculateTaxDetail(_p.pohead_taxzone_id, _p.poitem_taxtype_id,
+                              _p.poreject_date, _p.pohead_curr_id, 
+                              _itemAmount) 
+      GROUP BY taxdetail_tax_id
+    LOOP
+      INSERT INTO apopentax (taxhist_basis,taxhist_percent,taxhist_amount,taxhist_docdate, taxhist_tax_id, taxhist_tax, 
+                             taxhist_taxtype_id, taxhist_parent_id, taxhist_journalnumber ) 
+      VALUES (0, 0, 0, _p.poreject_date, _tax.taxdetail_tax_id, _tax.taxdetail_tax, getadjustmenttaxtypeid(), 
+              _apopenid, _journalNumber);
+
+      _taxAmount := _taxAmount + _tax.taxdetail_tax;
+    END LOOP;
+
+    _taxAmount_base := addTaxToGLSeries(_sequence,
+                      'A/P', 'CM', _docNumber,
+                      _p.pohead_curr_id, _p.poreject_date, _p.poreject_date,
+                      'apopentax', _apopenid,
+                      _p.notes);
+
+    UPDATE apopen SET apopen_amount = round(_itemAmount + _taxAmount,2)
+    WHERE (apopen_id = _apopenid);
+
+--  Distribute from the clearing account
+    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
+                _a.lb_accnt_id,
+                round(_p.value, 2),
+                _p.poreject_date, _p.notes );
+    _glseriesTotal := _glseriesTotal + round(_p.value, 2);
+
+--  Distribute the remaining variance to the Purchase Price Variance account
+    IF (round(_itemAmount_base, 2) <> round(_p.value, 2)) THEN
+      _tmpTotal := round(_itemAmount_base, 2) - round(_p.value, 2);
+      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
+                                  _a.pp_accnt_id,
+                                  _tmpTotal,
+                                  _p.poreject_date, _p.notes );
+        _glseriesTotal := _glseriesTotal + _tmpTotal;
+    END IF;
+
+--  Post the reject item for this P/O Item as Invoiced
+    UPDATE poreject
+    SET poreject_invoiced=TRUE
+    WHERE poreject_id=pPorejectId;
+
+--  Update the qty vouchered field
+    UPDATE poitem
+       SET poitem_qty_vouchered = (poitem_qty_vouchered - _p.poreject_qty)
+     WHERE (poitem_id=_p.poitem_id);
+
+--  Post to A/P
+  SELECT findAPAccount(_p.pohead_vend_id) INTO _apaccntid;
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Post Credit Memo due to an unassigned A/P Account.';
+  END IF;
+
+  SELECT insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
+                             _apaccntid, round(_itemAmount_base + _taxAmount_base, 2) *-1,
+                             _p.poreject_date, _p.notes ) INTO _test;
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Post Credit Memo.';
+  END IF;
+
+-- Clean up loose ends
+
+  _glseriesTotal := _glseriesTotal + round(_itemAmount_base, 2)*-1;
+
+  IF (round(_glseriesTotal, 2) != 0) THEN
+        PERFORM insertIntoGLSeries(_sequence, 'A/P', 'CM',
+            'Currency Exchange Rounding - ' || _docNumber,
+            getGainLossAccntId(_apaccntid), round(_glseriesTotal, 2) * -1,
+           _p.poreject_date, _p.notes);
+  END IF;
+
+--  Post it all
+  PERFORM postGLSeries(_sequence, _journalNumber);
+
+  RETURN _journalNumber;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postporeturncreditmemo(integer, numeric)
+  OWNER TO admin;
diff --git a/pgsql/postporeturns.sql b/pgsql/postporeturns.sql
new file mode 100644 (file)
index 0000000..3574c77
--- /dev/null
@@ -0,0 +1,180 @@
+-- modified to use the poreject_date - rather than current date...
+
+-- Function: postporeturns(integer, boolean)
+
+-- DROP FUNCTION postporeturns(integer, boolean);
+
+CREATE OR REPLACE FUNCTION postporeturns(integer, boolean)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pPoheadid ALIAS FOR $1;
+  pCreateMemo ALIAS FOR $2;
+  _itemlocSeries INTEGER;
+  _p RECORD;
+  _returnval   INTEGER;
+  _pricevar   NUMERIC := 0.00;
+  _invhistid INTEGER;
+  _tmp        INTEGER;
+
+BEGIN
+
+  _itemlocSeries := 0;
+
+  FOR _p IN SELECT
+            pohead_number,
+            pohead_curr_id,
+            poreject_id,
+            poitem_prj_id,
+                  
+            poreject_poitem_id,
+            poitem_id,
+            poitem_expcat_id,
+            poitem_linenumber,
+                  
+            currToBase(pohead_curr_id, poitem_unitprice,  pohead_orderdate) AS poitem_unitprice_base,
+            COALESCE(itemsite_id, -1) AS itemsiteid,
+            poitem_invvenduomratio,
+            SUM(poreject_qty) AS totalqty,
+            itemsite_item_id,
+            itemsite_costmethod,
+            itemsite_controlmethod,
+            poreject_date
+        FROM
+            poreject, pohead, poitem 
+               LEFT OUTER JOIN
+            itemsite
+        ON
+            (poitem_itemsite_id=itemsite_id)
+        WHERE
+            (
+                (poreject_poitem_id=poitem_id)
+            AND
+                (poitem_pohead_id=pohead_id)
+            AND
+                (pohead_id=pPoheadid)
+            AND
+                (NOT poreject_posted) )
+            GROUP BY
+                poreject_id, pohead_number,
+                poreject_poitem_id, poitem_id,
+                poitem_prj_id, poitem_expcat_id,
+                poitem_linenumber, poitem_unitprice,
+                pohead_curr_id, pohead_orderdate,
+                itemsite_id, poitem_invvenduomratio,
+                itemsite_item_id, itemsite_costmethod,
+                itemsite_controlmethod,
+                poreject_date LOOP
+
+    IF (_p.itemsiteid = -1) THEN
+        SELECT insertGLTransaction( 'S/R', 'PO', _p.pohead_number, 'Return Non-Inventory to P/O',
+                                     expcat_liability_accnt_id, 
+                                     getPrjAccntId(_p.poitem_prj_id, expcat_exp_accnt_id), -1,
+                                     round(_p.poitem_unitprice_base * _p.totalqty * -1, 2),
+                                    _p.poreject_date ) INTO _returnval
+        FROM expcat
+        WHERE (expcat_id=_p.poitem_expcat_id);
+
+        UPDATE poreject
+        SET poreject_posted=TRUE, poreject_value= round(_p.poitem_unitprice_base * _p.totalqty, 2)
+        WHERE (poreject_id=_p.poreject_id);
+
+    ELSEIF (_p.itemsite_controlmethod='N') THEN
+      SELECT insertGLTransaction('S/R', 'PO', _p.pohead_number, 'Return Non-Controlled Inventory from PO',
+                                 costcat_liability_accnt_id,
+                                 getPrjAccntId(_p.poitem_prj_id, costcat_exp_accnt_id), -1,
+                                 round((_p.poitem_unitprice_base * _p.totalqty * -1), 2),
+                                 _p.poreject_date ) INTO _returnval
+      FROM itemsite, costcat
+      WHERE((itemsite_costcat_id=costcat_id)
+        AND (itemsite_id=_p.itemsiteid));
+      IF (_returnval = -3) THEN -- zero value transaction
+        _returnval := 0;
+      END IF;
+      UPDATE poreject
+      SET poreject_posted=TRUE, poreject_value= round(_p.poitem_unitprice_base * _p.totalqty, 2)
+      WHERE (poreject_id=_p.poreject_id);
+    ELSE
+      IF (_itemlocSeries = 0) THEN
+        SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+      END IF;
+
+      SELECT postInvTrans( itemsite_id, 'RP', (_p.totalqty * _p.poitem_invvenduomratio * -1),
+                           'S/R', 'PO', (_p.pohead_number || '-' || _p.poitem_linenumber::TEXT), '', 'Return Inventory to P/O',
+                           costcat_asset_accnt_id, costcat_liability_accnt_id, _itemlocSeries, _p.poreject_date) INTO _returnval
+      FROM itemsite, costcat
+      WHERE ( (itemsite_costcat_id=costcat_id)
+       AND (itemsite_id=_p.itemsiteid) );
+
+      UPDATE poreject
+      SET poreject_posted=TRUE, poreject_value=(invhist_unitcost *_p.totalqty * _p.poitem_invvenduomratio)
+      FROM invhist
+      WHERE ((poreject_id=_p.poreject_id)
+      AND (invhist_id=_returnval));
+
+    END IF;
+
+    IF (_returnval < 0) THEN
+      RETURN _returnval;
+    END IF;
+    
+    UPDATE poitem
+    SET poitem_qty_returned=(poitem_qty_returned + _p.totalqty),
+       poitem_status='O'
+    WHERE (poitem_id=_p.poitem_id);
+
+
+    IF (fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
+        _invhistid := _returnval;
+        -- Find the difference in the purchase price value expected from the P/O and the value of the transaction
+        SELECT (((_p.poitem_unitprice_base * _p.totalqty) - (invhist_value_before - invhist_value_after)) * -1) INTO _pricevar
+        FROM invhist, poitem
+        WHERE ((invhist_id = _invhistid)
+          AND  (poitem_id=_p.poitem_id));
+        -- If difference exists then
+        IF (_pricevar <> 0.00) THEN
+          -- Record an additional GL Transaction for the purchase price variance
+
+          SELECT insertGLTransaction(
+               'S/R', 'PO', _p.pohead_number,
+                                      'Void Purchase price variance adjusted for P/O ' || _p.pohead_number || ' for item ' || _p.poitem_linenumber::TEXT,
+                                      costcat_liability_accnt_id,
+                                      getPrjAccntId(_p.poitem_prj_id, costcat_purchprice_accnt_id), -1,
+                                      _pricevar,
+                                      _p.poreject_date::date ) INTO _tmp
+          FROM itemsite, costcat, poitem
+          WHERE ((itemsite_costcat_id=costcat_id)
+             AND (itemsite_id=poitem_itemsite_id) );
+          IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'Could not insert G/L transaction: no cost category found for itemsite_id %',
+            _p.itemsiteid;
+          ELSIF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
+            RETURN _tmp;
+          ELSE
+            -- Posting to trial balance is deferred to prevent locking
+            INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
+            VALUES ( _tmp, _itemlocSeries );
+          END IF;
+        END IF;
+      END IF;
+
+    IF (pCreateMemo) THEN
+       SELECT postPoReturnCreditMemo(_p.poreject_id) INTO _returnval;
+    END IF;
+
+    IF (_returnval < 0) THEN
+      RETURN _returnval;
+    END IF;
+
+  END LOOP;
+
+  RETURN _itemlocSeries;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postporeturns(integer, boolean)
+  OWNER TO admin;
diff --git a/pgsql/recallshipment.sql b/pgsql/recallshipment.sql
new file mode 100644 (file)
index 0000000..a5581a8
--- /dev/null
@@ -0,0 +1,324 @@
+-- modified to handle multiple shipments, and the fact that we broke something by accepting
+-- negative shipments...-- Function: recallshipment(integer, timestamp with time zone)
+
+-- nothing changed yet..
+
+-- DROP FUNCTION recallshipment(integer, timestamp with time zone);
+
+CREATE OR REPLACE FUNCTION recallshipment(integer, timestamp with time zone)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pshipheadid          ALIAS FOR $1;
+  _timestamp           TIMESTAMP WITH TIME ZONE := $2;
+  _allInvoiced         BOOLEAN;
+  _invoicePosted       BOOLEAN;
+  _in                   RECORD;
+  _co                  RECORD;
+  _cobill              RECORD;
+  _h                   RECORD;
+  _result               INTEGER;
+  _invhistid           INTEGER;
+  _itemlocSeries       INTEGER;
+  _qty                 NUMERIC;
+  _qtyToBill           NUMERIC;
+  _shiphead            RECORD;
+  _to                  RECORD;
+  _ti                  RECORD;
+  _value                NUMERIC;
+
+BEGIN
+
+  IF (_timestamp IS NULL) THEN
+    _timestamp := CURRENT_TIMESTAMP;
+  END IF;
+
+  SELECT * INTO _shiphead
+  FROM shiphead
+  WHERE (shiphead_id=pshipheadid);
+  IF (NOT FOUND OR NOT _shiphead.shiphead_shipped) THEN
+    RETURN -1;
+  END IF;
+
+
+
+  IF (_shiphead.shiphead_order_type = 'SO') THEN
+  
+    -- based on a sales order...
+  
+    SELECT cohead_number AS head_number, cohead_cust_id AS cust_id, cohead_prj_id INTO _h
+      FROM cohead
+     WHERE (cohead_id=_shiphead.shiphead_order_id);
+    IF (NOT FOUND) THEN
+      --- no order found!
+      RETURN -1;
+    END IF;
+
+    SELECT COALESCE(BOOL_AND(shipitem_invoiced), FALSE) INTO _allInvoiced
+     FROM cobill, shipitem
+    WHERE ((cobill_coitem_id=shipitem_orderitem_id)
+      AND  (shipitem_shiphead_id=pshipheadid));
+
+    IF (_allInvoiced AND NOT checkPrivilege('RecallInvoicedShipment')) THEN
+      -- not allowed to recall..
+      RETURN -2;
+    END IF;
+
+    -- Check for any associated posted Invoices
+    SELECT
+        COALESCE(BOOL_AND(invchead_posted), FALSE) INTO _invoicePosted
+        FROM
+            shipitem
+        JOIN
+            invcitem
+        ON
+            (invcitem_id=shipitem_invcitem_id)
+        JOIN
+            invchead ON (invchead_id=invcitem_invchead_id)
+    WHERE
+        (shipitem_shiphead_id=pshipheadid);
+
+    IF (_invoicePosted) THEN
+      RETURN -4;
+    END IF;
+
+    -- Delete any associated unposted Invoices
+    
+    
+    FOR _in IN SELECT DISTINCT invchead_id
+                 FROM shipitem JOIN invcitem ON (invcitem_id=shipitem_invcitem_id)
+                               JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
+                                                  (NOT invchead_posted) )
+                WHERE (shipitem_shiphead_id=pshipheadid) LOOP
+      SELECT deleteInvoice(_in.invchead_id) INTO _result;
+      IF (_result < 0) THEN
+        RETURN _result;
+      END IF;
+    END LOOP;
+
+     SELECT count(coitem_id) INTO _qty
+                 FROM coitem
+                  JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
+                WHERE(coitem_id IN (
+                        SELECT
+                            shipitem_orderitem_id
+                        FROM shipitem, shiphead
+                            WHERE((shipitem_shiphead_id=shiphead_id)
+                               AND (shiphead_shipped)
+                           AND (shiphead_id=pshipheadid))));
+                           
+    --RAISE EXCEPTION 'coitems num is: %',  _qty;
+
+
+    FOR _co IN SELECT coitem_id, coitem_itemsite_id,
+                    coitem_qty_invuomratio,
+                    coitem_warranty, coitem_cos_accnt_id,
+                   itemsite_controlmethod
+                 FROM coitem
+                  JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
+                WHERE(coitem_id IN (
+                        SELECT
+                            shipitem_orderitem_id
+                        FROM shipitem, shiphead
+                            WHERE((shipitem_shiphead_id=shiphead_id)
+                               AND (shiphead_shipped)
+                           AND (shiphead_id=pshipheadid)))) FOR UPDATE LOOP
+
+      SELECT SUM(shipitem_qty),SUM(COALESCE(shipitem_value, 0)) INTO _qty, _value
+             FROM shipitem
+            WHERE ( (shipitem_orderitem_id=_co.coitem_id)
+            AND (shipitem_shiphead_id=pshipheadid) );
+
+    
+     -- update the shipped qty..
+      UPDATE coitem
+            SET coitem_qtyshipped = (coitem_qtyshipped - _qty)
+            WHERE (coitem_id=_co.coitem_id);
+
+    -- delete or update any associated bills...
+
+      _qtyToBill := _qty;
+      FOR _cobill IN SELECT cobill_id, cobill_qty
+                        FROM cobill, shipitem
+                       WHERE ((cobill_coitem_id=shipitem_orderitem_id)
+                         AND  (shipitem_shiphead_id=pshipheadid)
+                         AND  (cobill_coitem_id=_co.coitem_id)) FOR UPDATE LOOP
+
+            IF (noNeg(_cobill.cobill_qty - _qtyToBill) = 0) THEN
+              DELETE FROM cobill WHERE (cobill_id=_cobill.cobill_id);
+            ELSE
+          UPDATE cobill
+          SET cobill_qty = noNeg(cobill_qty - _qtyToBill)
+          WHERE (cobill_id=_cobill.cobill_id);
+        END IF;
+    
+        _qtyToBill = _qtyToBill - _cobill.cobill_qty;
+        EXIT WHEN (_qtyToBill <= 0.0);
+    END LOOP;
+
+  --  Check to see if all of the cobills have been deleted for this cobmisc
+      IF (EXISTS(SELECT cobmisc_id
+                 FROM cobmisc JOIN cobill ON (cobill_cobmisc_id=cobmisc_id)
+                 WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted))) THEN
+  --  Lines exist, update the freight
+        UPDATE cobmisc SET cobmisc_freight = (cobmisc_freight - _shiphead.shiphead_freight)
+        WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted);
+      ELSE
+  --  No lines exist, delete the cobmisc
+        DELETE FROM cobmisc
+        WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted);
+      END IF;
+
+  --  Distribute to G/L, debit Shipping Asset, credit COS
+    --RAISE EXCEPTION 'control method is : %', _co.itemsite_controlmethod;
+      IF (_co.itemsite_controlmethod != 'N') THEN
+        PERFORM insertGLTransaction(
+            'S/R',
+            _shiphead.shiphead_order_type,
+                       _h.head_number::TEXT,
+            'Recall Shipment',
+            CASE WHEN
+                        (COALESCE(_co.coitem_cos_accnt_id, -1) != -1)
+                    THEN
+                        getPrjAccntId(_h.cohead_prj_id, _co.coitem_cos_accnt_id)
+                WHEN    (_co.coitem_warranty = TRUE)
+                    THEN
+                        getPrjAccntId(_h.cohead_prj_id, resolveCOWAccount(itemsite_id, _h.cust_id))
+                                   ELSE getPrjAccntId(_h.cohead_prj_id, resolveCOSAccount(itemsite_id, _h.cust_id))
+                END,
+                getPrjAccntId(_h.cohead_prj_id,costcat_shipasset_accnt_id), -1,
+                          _value,
+                          _timestamp::DATE )
+        FROM itemsite, costcat
+        WHERE ( (itemsite_costcat_id=costcat_id)
+         AND (itemsite_id=_co.coitem_itemsite_id) );
+         
+      --   RAISE EXCEPTION 'tried to post gltrans: %', _value;
+         
+       END IF;
+       
+       
+       
+       
+    END LOOP;
+
+-- Kit billing selection
+-- Set kit billing qty to zero since kits are shipped complete
+    FOR _cobill IN SELECT cobill_id, cobill_qty
+                   FROM shipitem JOIN coitem sub ON (sub.coitem_id=shipitem_orderitem_id)
+                                 JOIN coitem kit ON (kit.coitem_id <> sub.coitem_id AND
+                                                     kit.coitem_cohead_id = sub.coitem_cohead_id AND
+                                                     kit.coitem_linenumber = sub.coitem_linenumber AND
+                                                     kit.coitem_subnumber = 0)
+                                 JOIN cobill ON (cobill_coitem_id=kit.coitem_id)
+                   WHERE (shipitem_shiphead_id=pshipheadid)
+                     AND (sub.coitem_subnumber > 0)
+                   GROUP BY cobill_id, cobill_qty
+    LOOP
+      UPDATE cobill SET cobill_qty = 0.0
+      WHERE (cobill_id=_cobill.cobill_id);
+    END LOOP;
+
+  ELSEIF (_shiphead.shiphead_order_type = 'TO') THEN
+    SELECT * INTO _to
+      FROM tohead
+     WHERE (tohead_id=_shiphead.shiphead_order_id);
+    IF (NOT FOUND) THEN
+      RETURN -1;
+    END IF;
+    IF (_to.tohead_status = 'C') THEN
+      RETURN -6;
+    END IF;
+
+    FOR _ti IN SELECT toitem_id, toitem_item_id,
+                     toitem_qty_received, toitem_qty_ordered, SUM(shipitem_qty) AS qty
+             FROM toitem, shipitem
+             WHERE ((toitem_id=shipitem_orderitem_id)
+               AND  (shipitem_shiphead_id=pshipheadid))
+             GROUP BY toitem_id, toitem_item_id,
+                      toitem_qty_received, toitem_qty_ordered LOOP
+
+      _itemlocSeries := NEXTVAL('itemloc_series_seq');
+      
+      SELECT postInvTrans(si.itemsite_id, 'TS', (_ti.qty * -1.0), 'I/M',
+                         _shiphead.shiphead_order_type, formatToNumber(_ti.toitem_id),
+                         _to.tohead_number,
+                         'Recall Shipment from Transit To Src Warehouse',
+                         sc.costcat_asset_accnt_id,
+                         tc.costcat_shipasset_accnt_id,
+                         _itemlocSeries, _timestamp) INTO _invhistid
+      FROM itemsite AS ti, costcat AS tc,
+          itemsite AS si, costcat AS sc
+      WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
+        AND  (si.itemsite_costcat_id=sc.costcat_id)
+        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
+        AND  (si.itemsite_item_id=_ti.toitem_item_id)
+        AND  (ti.itemsite_warehous_id=_to.tohead_src_warehous_id)
+        AND  (si.itemsite_warehous_id=_to.tohead_trns_warehous_id) );
+
+      IF (_invhistid < 0) THEN
+            RETURN _invhistid;
+      END IF;
+
+      -- post the inventory history if lot/serial or location control
+      PERFORM postItemlocseries(_itemlocSeries);
+
+      -- record inventory history and qoh changes at transit warehouse but
+      -- there is only one g/l account to touch
+      SELECT postInvTrans(ti.itemsite_id, 'TR', (_ti.qty * -1.0), 'I/M',
+                         _shiphead.shiphead_order_type, formatToNumber(_ti.toitem_id),
+                         _to.tohead_number,
+                         'Recall Shipment from Transit To Src Warehouse',
+                         tc.costcat_asset_accnt_id,
+                         tc.costcat_asset_accnt_id,
+                         _itemlocSeries, _timestamp,
+                         (invhist_invqty * invhist_unitcost)) INTO _invhistid
+      FROM itemsite AS ti, costcat AS tc, invhist
+      WHERE ((ti.itemsite_costcat_id=tc.costcat_id)
+        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
+        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id)
+        AND  (invhist_id=_invhistid));
+
+      IF (_invhistid < 0) THEN
+       RETURN _invhistid;
+      END IF;
+
+      -- post the inventory history if lot/serial or location control
+      PERFORM postItemlocseries(_itemlocSeries);
+
+      UPDATE toitem
+      SET toitem_qty_shipped = (toitem_qty_shipped - _ti.qty)
+      WHERE (toitem_id=_ti.toitem_id);
+
+      UPDATE shipitem SET shipitem_shipdate=NULL, shipitem_shipped=FALSE
+      WHERE ((shipitem_orderitem_id=_ti.toitem_id)
+        AND  (shipitem_shiphead_id=pshipheadid));
+
+      DELETE FROM recv
+       WHERE ((recv_orderitem_id=_ti.toitem_id)
+         AND  (recv_order_type='TO')
+         AND  (NOT recv_posted));
+
+    END LOOP;
+
+  END IF;
+
+  UPDATE shiphead
+        SET shiphead_shipped=FALSE
+         WHERE (shiphead_id=pshipheadid);
+
+  RETURN _itemlocSeries;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION recallshipment(integer, timestamp with time zone)
+  OWNER TO admin;
+
+
+-- BEGIN;
+-- SELECT recallShipment(183, '2013-05-24') ;
+-- ROLLBACK;
\ No newline at end of file
diff --git a/pgsql/releasevonumber.sql b/pgsql/releasevonumber.sql
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pgsql/relocateinventory.sql b/pgsql/relocateinventory.sql
new file mode 100644 (file)
index 0000000..0505dbf
--- /dev/null
@@ -0,0 +1,196 @@
+
+
+-- MODIFIED TO HANDLE NEGATIVE STOCK!
+
+
+-- Function: relocateinventory(integer, integer, integer, numeric, text, timestamp with time zone)
+
+-- DROP FUNCTION relocateinventory(integer, integer, integer, numeric, text, timestamp with time zone);
+
+CREATE OR REPLACE FUNCTION relocateinventory(integer, integer, integer, numeric, text, timestamp with time zone)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pSourceItemlocid      ALIAS FOR $1;
+  pTargetLocationid     ALIAS FOR $2;
+  pItemsiteid           ALIAS FOR $3;
+  pQty                  ALIAS FOR $4;
+  pComments             ALIAS FOR $5;
+  _GlDistTS             TIMESTAMP WITH TIME ZONE := $6;
+  _targetItemlocid      INTEGER;
+  _invhistid            INTEGER;
+  _p RECORD;
+  _qty NUMERIC;
+  _itemlocSeries INTEGER := NEXTVAL('itemloc_series_seq');
+
+BEGIN
+
+    IF ((_GlDistTS IS NULL) OR (CAST(_GlDistTS AS date)=CURRENT_DATE)) THEN
+      _GlDistTS := CURRENT_TIMESTAMP;
+    END IF;
+
+--  Make sure the passed itemsite points to a real item
+  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
+         FROM itemsite, item
+         WHERE ( (itemsite_item_id=item_id)
+          AND (itemsite_id=pItemsiteid) ) ) ) THEN
+    RETURN 0;
+  END IF;
+
+--  Cache some parameters
+  SELECT itemloc_ls_id,
+         itemloc_itemsite_id AS itemsiteid,
+         itemloc_expiration,
+         itemloc_warrpurc,
+         itemloc_qty,
+         sourceloc.location_netable AS sourcenet,
+         targetloc.location_netable AS targetnet INTO _p
+  FROM itemloc, location AS sourceloc, location AS targetloc
+  WHERE ( (itemloc_location_id=sourceloc.location_id)
+   AND (targetloc.location_id=pTargetLocationid)
+   AND (itemloc_id=pSourceItemlocid) );
+
+--  Check to make sure the qty being transfered exists
+-- we need this not to work!
+  --IF (_p.itemloc_qty < pQty) THEN
+  --  RETURN -1;
+  --END IF;
+
+--  Create the RL transaction
+  SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
+  INSERT INTO invhist
+  ( invhist_id, invhist_itemsite_id,
+    invhist_transtype, invhist_invqty,
+    invhist_qoh_before, invhist_qoh_after,
+    invhist_comments,   invhist_transdate,
+    invhist_invuom, invhist_unitcost, invhist_costmethod,
+    invhist_value_before, invhist_value_after, invhist_series) 
+  SELECT _invhistid, itemsite_id,
+         'RL', 0,
+         itemsite_qtyonhand, itemsite_qtyonhand,
+         pComments, _GlDistTS,
+         uom_name,
+         CASE WHEN (itemsite_costmethod='A') THEN avgcost(itemsite_id)
+              ELSE stdCost(item_id)
+         END, itemsite_costmethod,
+         itemsite_value, itemsite_value, _itemlocSeries
+  FROM item, itemsite, uom
+  WHERE ((itemsite_item_id=item_id)
+   AND (item_inv_uom_id=uom_id)
+   AND (itemsite_controlmethod <> 'N')
+   AND (itemsite_id=pItemsiteid));
+
+--  Relocate the inventory from the source and record the transactions
+  INSERT INTO invdetail
+  ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+    invdetail_qty, invdetail_qty_before, invdetail_qty_after,
+    invdetail_expiration, invdetail_warrpurc )
+  SELECT _invhistid, itemloc_location_id, itemloc_ls_id,
+         (pQty * -1), itemloc_qty, (itemloc_qty - pQty),
+         itemloc_expiration, itemloc_warrpurc
+  FROM itemloc
+  WHERE (itemloc_id=pSourceItemlocid);
+
+  UPDATE itemloc
+  SET itemloc_qty=(itemloc_qty - pQty)
+  FROM itemsite
+  WHERE ( (itemloc_itemsite_id=itemsite_id)
+   AND (NOT itemsite_freeze)
+   AND (itemloc_id=pSourceItemlocid) );
+
+--  Check to see if there is anything left at the source Itemloc and delete if not
+  DELETE FROM itemloc
+  WHERE ( (itemloc_qty=0)
+   AND (itemloc_id=pSourceItemlocid) );
+
+--  Check to see if any of the current Lot/Serial #/Expiration exists at the target location
+  SELECT itemloc_id INTO _targetItemlocid
+  FROM itemloc 
+  WHERE ( (COALESCE(itemloc_ls_id, -1)=COALESCE(_p.itemloc_ls_id,-1))
+   AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_p.itemloc_expiration,endOfTime()))
+   AND (COALESCE(itemloc_warrpurc,endOfTime())=COALESCE(_p.itemloc_warrpurc,endOfTime()))
+   AND (itemloc_itemsite_id=pItemsiteid)
+   AND (itemloc_location_id=pTargetLocationid) );
+
+  IF (NOT FOUND) THEN
+    SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _targetItemlocid;
+    INSERT INTO itemloc
+    ( itemloc_id, itemloc_itemsite_id, itemloc_location_id,
+      itemloc_ls_id, itemloc_expiration, itemloc_warrpurc, itemloc_qty )
+    VALUES
+    ( _targetItemlocid, pItemsiteid, pTargetLocationid,
+      _p.itemloc_ls_id, _p.itemloc_expiration, _p.itemloc_warrpurc, 0 );
+  END IF;
+
+--  Relocate the inventory to the resultant target and record the transactions
+  INSERT INTO invdetail
+  ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
+    invdetail_qty, invdetail_qty_before, invdetail_qty_after,
+    invdetail_expiration, invdetail_warrpurc )
+  SELECT _invhistid, pTargetLocationid, _p.itemloc_ls_id,
+         pQty, itemloc_qty, (itemloc_qty + pQty), 
+         _p.itemloc_expiration, _p.itemloc_warrpurc
+  FROM itemloc
+  WHERE (itemloc_id=_targetItemlocid);
+
+  UPDATE itemloc
+  SET itemloc_qty=(itemloc_qty + pQty)
+  FROM itemsite
+  WHERE ( (itemloc_itemsite_id=itemsite_id)
+   AND (NOT itemsite_freeze)
+   AND (itemloc_id=_targetItemlocid) );
+
+  UPDATE invhist
+  SET invhist_hasdetail=TRUE
+  WHERE (invhist_id=_invhistid);
+
+--  Post in incomming or outgoing NN transaction if required
+  IF (_p.sourcenet <> _p.targetnet) THEN
+    IF (_p.targetnet) THEN
+      _qty = (pQty * -1);
+    ELSE
+      _qty = pQty;
+    END IF;
+
+    INSERT INTO invhist
+    ( invhist_itemsite_id,
+      invhist_transtype, invhist_invqty,
+      invhist_qoh_before, invhist_qoh_after,
+      invhist_docnumber, invhist_comments, invhist_transdate,
+      invhist_invuom, invhist_unitcost, invhist_costmethod,
+      invhist_value_before, invhist_value_after, invhist_series) 
+    SELECT itemsite_id,
+           'NN', (_qty * -1),
+           itemsite_qtyonhand, (itemsite_qtyonhand - _qty),
+           '', '', _GlDistTS,
+           uom_name,
+           CASE WHEN (itemsite_costmethod='A') THEN avgcost(itemsite_id)
+                ELSE stdcost(itemsite_id)
+           END, itemsite_costmethod,
+           itemsite_value, itemsite_value, _itemlocSeries
+    FROM item, itemsite, uom
+    WHERE ( (itemsite_item_id=item_id)
+     ANd (item_inv_uom_id=uom_id)
+     AND (itemsite_controlmethod <> 'N')
+     AND (itemsite_id=_p.itemsiteid) );
+
+    UPDATE itemsite
+    SET itemsite_qtyonhand = (itemsite_qtyonhand - _qty),
+        itemsite_nnqoh = (itemsite_nnqoh + _qty)
+    WHERE (itemsite_id=_p.itemsiteid);
+  END IF;
+
+--  Check to see if there is anything left at the target Itemloc and delete if not
+--  Could be zero if relocate increased a negative quantity to zero
+  DELETE FROM itemloc
+  WHERE ( (itemloc_qty=0)
+   AND (itemloc_id=_targetItemlocid) );
+
+--  Return the invhist_id
+  RETURN _invhistid;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION relocateinventory(integer, integer, integer, numeric, text, timestamp with time zone) OWNER TO "admin";
diff --git a/pgsql/sandbox.apply.sh b/pgsql/sandbox.apply.sh
new file mode 100755 (executable)
index 0000000..bff1b90
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+
+psql -Uadmin sandboxhk -f $1;
+psql -Uadmin sandboxcn -f $1;
+psql -Uadmin sandboxau -f $1;
+psql -Uadmin sandboxmy -f $1;
+psql -Uadmin sandboxsg -f $1;
+psql -Uadmin sandboxzh -f $1;
\ No newline at end of file
diff --git a/pgsql/shipshipment.sql b/pgsql/shipshipment.sql
new file mode 100644 (file)
index 0000000..a849e35
--- /dev/null
@@ -0,0 +1,370 @@
+--- modified to sort out coitem trigger catching 'C' change on shipped items.
+
+
+CREATE OR REPLACE FUNCTION shipShipment(INTEGER) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+BEGIN
+  RETURN shipShipment($1, CURRENT_TIMESTAMP);
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION shipShipment(INTEGER, TIMESTAMP WITH TIME ZONE) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pshipheadid          ALIAS FOR $1;
+  _timestamp           TIMESTAMP WITH TIME ZONE := $2;
+
+  _billedQty           NUMERIC;
+  _c                   RECORD;
+  _coholdtype          TEXT;
+  _gldate              DATE;
+  _invhistid           INTEGER;
+  _itemlocSeries       INTEGER;
+  _newQty              NUMERIC;
+  _result              INTEGER;
+  _s                   RECORD;
+  _shipcomplete                BOOLEAN;
+  _shiphead            RECORD;
+  _stdcost             NUMERIC;
+  _ti                  RECORD;
+  _to                  RECORD;
+  _variance            NUMERIC;
+  _k                    RECORD;
+  v_coitem_id  INTEGER;
+  v_close_items INTEGER ARRAY;
+
+BEGIN
+
+  IF (_timestamp IS NULL) THEN
+    _timestamp := CURRENT_TIMESTAMP;
+  END IF;
+  _gldate := _timestamp::DATE;
+
+  SELECT * INTO _shiphead
+  FROM shiphead WHERE (shiphead_id=pshipheadid);
+  IF (NOT FOUND) THEN
+    RETURN -50;
+  END IF;
+
+  IF (_shiphead.shiphead_order_type = 'SO') THEN
+
+    SELECT cohead_shipcomplete, cohead_holdtype INTO _shipcomplete, _coholdtype
+      FROM cohead, shiphead
+     WHERE ((shiphead_order_id=cohead_id)
+       AND  (NOT shiphead_shipped)
+       AND  (shiphead_order_type=_shiphead.shiphead_order_type)
+       AND  (shiphead_id=pshipheadid));
+
+    IF (_coholdtype = 'C') THEN
+      RETURN -12;
+    ELSIF (_coholdtype = 'P') THEN
+      RETURN -13;
+    ELSIF (_coholdtype = 'R') THEN
+      RETURN -14;
+    ELSIF (_coholdtype = 'S') THEN
+      RETURN -15;
+    END IF;
+
+---Must Ship Kit components (coitem_subnumber <> 0 complete---------------
+    IF ((
+         --  Test to see if order's customer accepts backorders and partials 
+         --  If not then test for shipping kit components complete 
+        SELECT cohead_number
+        FROM shiphead, cohead, custinfo
+        WHERE 
+          (shiphead_order_id = cohead_id) AND
+          (cohead_cust_id = cust_id) AND
+          (shiphead_order_type = 'SO') AND 
+          (cust_partialship) AND
+          (cust_backorder) AND
+          (shiphead_id = pshipheadid)
+         ) IS NULL) THEN
+      FOR _k IN SELECT (coitem_qtyord -
+                       (COALESCE(SUM(shipitem_qty),0) +
+                        (COALESCE(coitem_qtyshipped,0) - COALESCE(coitem_qtyreturned,0)))) AS remain
+                 FROM (coitem LEFT OUTER JOIN (itemsite JOIN item ON (itemsite_item_id=item_id)) ON (coitem_itemsite_id=itemsite_id)) LEFT OUTER JOIN
+                      shipitem ON (shipitem_orderitem_id=coitem_id
+                               AND shipitem_shiphead_id=pshipheadid)
+                WHERE ((coitem_status NOT IN ('C','X'))
+                   AND  (item_type != 'K')
+                  AND  (coitem_cohead_id=_shiphead.shiphead_order_id)
+                   AND  (coitem_subnumber <> 0)
+                  )
+             GROUP BY coitem_id, coitem_qtyshipped, coitem_qtyord,
+                      coitem_qtyreturned LOOP
+       IF (_k.remain > 0) THEN
+         RAISE EXCEPTION 'Kit component item not shipped complete.  Kits must be shipped and shipped complete or closed on the order.';
+       END IF;
+      END LOOP;
+    END IF;
+---End--------------------------------------------------------------------
+
+    IF ( _shipcomplete ) THEN
+      FOR _c IN SELECT (coitem_qtyord -
+                       (COALESCE(SUM(shipitem_qty),0) +
+                        (COALESCE(coitem_qtyshipped,0) - COALESCE(coitem_qtyreturned,0)))) AS remain
+                 FROM (coitem LEFT OUTER JOIN (itemsite JOIN item ON (itemsite_item_id=item_id)) ON (coitem_itemsite_id=itemsite_id)) LEFT OUTER JOIN
+                      shipitem ON (shipitem_orderitem_id=coitem_id
+                               AND shipitem_shiphead_id=pshipheadid)
+                WHERE ((coitem_status<>'X')
+                   AND  (item_type != 'K')
+                  AND  (coitem_cohead_id=_shiphead.shiphead_order_id))
+             GROUP BY coitem_id, coitem_qtyshipped, coitem_qtyord,
+                      coitem_qtyreturned LOOP
+       IF (_c.remain > 0) THEN
+         RETURN -99;
+       END IF;
+      END LOOP;
+    END IF;
+
+    FOR _c IN SELECT coitem_id, cohead_number, cohead_cust_id, cohead_billtoname, cohead_prj_id,
+                    itemsite_id, itemsite_item_id,
+                     coitem_qty_invuomratio,
+                     coitem_warranty, coitem_cos_accnt_id,
+                    SUM(shipitem_qty) AS _qty,
+                     SUM(shipitem_value) AS _value
+             FROM coitem, cohead, shiphead, shipitem, itemsite
+             WHERE ( (coitem_cohead_id=cohead_id)
+              AND (coitem_itemsite_id=itemsite_id)
+              AND (shiphead_order_id=cohead_id)
+              AND (shipitem_shiphead_id=shiphead_id)
+              AND (shipitem_orderitem_id=coitem_id)
+              AND (NOT shiphead_shipped)
+              AND (shiphead_id=pshipheadid) )
+             GROUP BY coitem_id, coitem_qty_invuomratio, cohead_number, cohead_cust_id, cohead_billtoname,
+                      itemsite_id, itemsite_item_id, coitem_warranty, coitem_cos_accnt_id, cohead_prj_id
+    LOOP
+
+      IF _c._value > 0 THEN
+  --    Distribute to G/L, credit Shipping Asset, debit COS
+       SELECT MIN(insertGLTransaction( 'S/R', 'SH', _shiphead.shiphead_number, ('Ship Order ' || _c.cohead_number || ' for Customer ' || _c.cohead_billtoname),
+                                    getPrjAccntId(_c.cohead_prj_id, costcat_shipasset_accnt_id),
+                                     CASE WHEN(COALESCE(_c.coitem_cos_accnt_id, -1) != -1) THEN getPrjAccntId(_c.cohead_prj_id, _c.coitem_cos_accnt_id)
+                                          WHEN(_c.coitem_warranty=TRUE) THEN getPrjAccntId(_c.cohead_prj_id, resolveCOWAccount(itemsite_id, _c.cohead_cust_id))
+                                          ELSE getPrjAccntId(_c.cohead_prj_id, resolveCOSAccount(itemsite_id, _c.cohead_cust_id))
+                                     END,
+                                     -1, _c._value, _gldate )) INTO _result
+       FROM itemsite, costcat
+       WHERE ( (itemsite_costcat_id=costcat_id)
+       AND (itemsite_id=_c.itemsite_id) );
+
+       IF (_result < 0 AND _result != -3) THEN -- ignore -3 as it just means it's not posting a 0 value
+         RETURN _result;
+       END IF;
+
+      END IF;
+
+      UPDATE coitem
+      SET coitem_qtyshipped = (coitem_qtyshipped + _c._qty)
+      WHERE (coitem_id=_c.coitem_id);
+
+      -- check to see if we have more invoiced than shipped items
+      -- if we do we will need to mark some of these records as invoiced
+      SELECT noNeg(( SELECT COALESCE(SUM(cobill_qty), 0.0)
+                    FROM cobill, cobmisc, coitem
+                    WHERE ( (cobill_cobmisc_id=cobmisc_id)
+                     AND (cobmisc_cohead_id=coitem_cohead_id)
+                     AND (cobill_coitem_id=coitem_id)
+                     AND (cobmisc_posted)
+                     AND (coitem_id=_c.coitem_id) )
+                  ) - ( SELECT COALESCE(SUM(shipitem_qty), 0.0)
+                        FROM shipitem, shiphead, coitem
+                        WHERE ( (shipitem_shiphead_id=shiphead_id)
+                         AND (shiphead_order_id=coitem_cohead_id)
+                         AND (shipitem_orderitem_id=coitem_id)
+                         AND (shiphead_order_type=_shiphead.shiphead_order_type)
+                         AND (shiphead_shipped)
+                         AND (coitem_id=_c.coitem_id) )
+                      ) ) INTO _billedQty;
+
+      IF (_billedQty > 0.0) THEN
+       FOR _s IN SELECT shipitem_id, shipitem_qty
+                 FROM shipitem, shiphead
+                 WHERE ( (shipitem_shiphead_id=shiphead_id)
+                  AND (shipitem_orderitem_id=_c.coitem_id)
+                  AND (shiphead_order_type=_shiphead.shiphead_order_type)
+                  AND (NOT shiphead_shipped)
+                  AND (shiphead_id=pshipheadid) )
+                 ORDER BY shipitem_qty LOOP
+
+         IF (_billedQty > 0.0) THEN
+
+           IF (_billedQty >= _s.shipitem_qty) THEN
+             UPDATE shipitem SET shipitem_invoiced=TRUE WHERE shipitem_id=_s.shipitem_id;
+              -- Close coitem where fully shipped and invoiced
+              
+              
+              
+              v_close_items := v_close_items || _c.coitem_id;
+              
+             -- UPDATE coitem SET coitem_status='C'
+            --     WHERE ( (coitem_id=_c.coitem_id)
+            --     AND   (coitem_qtyshipped >= coitem_qtyord) );
+                
+                
+             -- THIS DID NOT WORK..
+             -- 
+                
+           ELSE
+             _newQty := _s.shipitem_qty - _billedQty;
+             UPDATE shipitem SET shipitem_invoiced=TRUE, shipitem_qty=_billedQty WHERE shipitem_id=_s.shipitem_id;
+             INSERT INTO shipitem ( shipitem_orderitem_id, shipitem_shipdate,
+               shipitem_qty, shipitem_transdate, shipitem_invoiced,
+               shipitem_shiphead_id, shipitem_trans_username)
+             SELECT shipitem_orderitem_id, shipitem_shipdate,
+               _newQty, shipitem_transdate, FALSE,
+               shipitem_shiphead_id, shipitem_trans_username
+             FROM shipitem
+             WHERE (shipitem_id=_s.shipitem_id);
+           END IF;
+
+           _billedQty := _billedQty - _s.shipitem_qty;
+         END IF;
+       END LOOP;
+      END IF;
+
+    END LOOP;
+
+  ELSEIF (_shiphead.shiphead_order_type = 'TO') THEN
+    IF (_shiphead.shiphead_shipped) THEN
+      RETURN -8;
+    END IF;
+
+    SELECT tohead.* INTO _to
+      FROM tohead
+     WHERE (tohead_id=_shiphead.shiphead_order_id);
+
+    IF ( _to.tohead_shipcomplete ) THEN
+      -- use sufficientInventory...()?
+      FOR _ti IN SELECT (toitem_qty_ordered -
+                        (COALESCE(SUM(shipitem_qty),0) + toitem_qty_shipped)) AS remain
+                 FROM toitem LEFT OUTER JOIN
+                      shipitem ON (shipitem_orderitem_id=toitem_id)
+                WHERE ((toitem_status<>'X')
+                  AND  (toitem_tohead_id=_shiphead.shiphead_order_id))
+             GROUP BY toitem_qty_shipped, toitem_qty_ordered LOOP
+       IF (_ti.remain > 0) THEN
+         RETURN -99;
+       END IF;
+      END LOOP;
+    END IF;
+
+    FOR _ti IN SELECT toitem_id, toitem_item_id, SUM(shipitem_qty) AS qty, SUM(shipitem_value) AS value
+               FROM toitem, shipitem
+               WHERE ((toitem_tohead_id=_to.tohead_id)
+                 AND  (shipitem_orderitem_id=toitem_id)
+                 AND  (shipitem_shiphead_id=pshipheadid))
+               GROUP BY toitem_id, toitem_item_id LOOP
+
+      IF (NOT EXISTS(SELECT itemsite_id
+                    FROM itemsite
+                    WHERE ((itemsite_item_id=_ti.toitem_item_id)
+                    AND  (itemsite_warehous_id = _to.tohead_trns_warehous_id))
+                    )) THEN
+            RETURN -6;
+      END IF;
+
+      _itemlocSeries := NEXTVAL('itemloc_series_seq');
+
+      SELECT postInvTrans(si.itemsite_id, 'TS', _ti.qty,
+                          'I/M', _shiphead.shiphead_order_type,
+                          formatToNumber(_ti.toitem_id), _to.tohead_number,
+                         'Ship from Src to Transit Warehouse',
+                         tc.costcat_asset_accnt_id,
+                         sc.costcat_shipasset_accnt_id,
+                         _itemlocSeries, _timestamp, _ti.value) INTO _invhistid
+      FROM itemsite AS ti, costcat AS tc,
+          itemsite AS si, costcat AS sc
+      WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
+        AND  (si.itemsite_costcat_id=sc.costcat_id)
+        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
+        AND  (si.itemsite_item_id=_ti.toitem_item_id)
+        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id)
+        AND  (si.itemsite_warehous_id=_to.tohead_src_warehous_id) );
+
+      --We do not need to distribute lot/serial info for transit, post trans and discard dist detail
+      PERFORM postIntoTrialBalance(itemlocpost_glseq) FROM itemlocpost WHERE (itemlocpost_itemlocseries=_itemlocSeries);
+      PERFORM postInvHist(_invhistid);
+      DELETE FROM itemlocdist WHERE (itemlocdist_series=_itemlocSeries);
+      DELETE FROM itemlocpost WHERE (itemlocpost_itemlocSeries=_itemlocSeries);
+
+      IF (_result < 0) THEN
+            RETURN _result;
+      END IF;
+
+      -- record inventory history and qoh changes at transit warehouse but
+      -- there is only one g/l account to touch
+      SELECT postInvTrans(ti.itemsite_id, 'TR', _ti.qty,
+                          'I/M', _shiphead.shiphead_order_type,
+                          formatToNumber(_ti.toitem_id), _to.tohead_number,
+                         'Receive into Transit from Src Warehouse',
+                         tc.costcat_asset_accnt_id,
+                         tc.costcat_asset_accnt_id,
+                         _itemlocSeries, _timestamp, 
+                         _ti.value) INTO _invhistid
+      FROM itemsite AS ti, costcat AS tc
+      WHERE ((ti.itemsite_costcat_id=tc.costcat_id)
+        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
+        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id));
+      --We do not need to distribute lot/serial info for transit, post trans and discard dist detail
+      PERFORM postIntoTrialBalance(itemlocpost_glseq) FROM itemlocpost WHERE (itemlocpost_itemlocseries=_itemlocSeries);
+      PERFORM postInvHist(_invhistid);
+      DELETE FROM itemlocdist WHERE (itemlocdist_series=_itemlocSeries);
+      DELETE FROM itemlocpost WHERE (itemlocpost_itemlocSeries=_itemlocSeries);
+
+      --See if there was a change in values during the transfer, if so record the variance
+      SELECT (invhist_invqty * invhist_unitcost - _ti.value) INTO _variance
+      FROM invhist
+      WHERE (invhist_id=_invhistid);
+
+      IF (_variance > 0) THEN
+        PERFORM insertGLTransaction( 'S/R', _shiphead.shiphead_order_type, _to.tohead_number, 
+                                     'Transfer Order - Transfer Variance',
+                                     tc.costcat_invcost_accnt_id, tc.costcat_asset_accnt_id, _invhistid,
+                                     _variance,
+                                     CAST(_timestamp AS DATE) )
+        FROM itemsite AS ti, costcat AS tc
+        WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
+        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
+        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id) );
+      END IF;
+
+      IF (_result < 0) THEN
+       RETURN _result;
+      END IF;
+
+      UPDATE shipitem SET shipitem_shipdate=_timestamp, shipitem_shipped=TRUE
+      WHERE ((shipitem_orderitem_id=_ti.toitem_id)
+        AND  (shipitem_shiphead_id=pshipheadid));
+
+      UPDATE toitem
+      SET toitem_qty_shipped = (toitem_qty_shipped + _ti.qty)
+      WHERE (toitem_id=_ti.toitem_id);
+    END LOOP;
+  END IF;
+
+  UPDATE shiphead
+  SET shiphead_shipped=TRUE, shiphead_shipdate=_gldate
+  WHERE (shiphead_id=pshipheadid);
+
+    -- try and close the items.
+    IF v_coitem_id IS NOT NULL THEN 
+        FOREACH v_coitem_id  IN ARRAY v_close_items
+        LOOP
+            
+               UPDATE coitem SET coitem_status='C'
+                     WHERE ( (coitem_id = v_coitem_id)
+                     AND   (coitem_qtyshipped >= coitem_qtyord) );
+                    
+            
+        END LOOP;
+    END IF;
+
+
+
+  RETURN _itemlocSeries;
+
+END;
+$$ LANGUAGE 'plpgsql';
\ No newline at end of file
diff --git a/pgsql/sync_changes.sh b/pgsql/sync_changes.sh
new file mode 100644 (file)
index 0000000..c665dc3
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# the point here is that fifo development is stored in a separete folder at present
+# and has to be copied into here.
+
+# our other modifications are made public using the xtuple.modifications directory.
+
+
+#first copy fifo into here.
+cp ~/Dropbox/xtuple_stored_procs/xtuple.fifo/*.sql .
+
+
+#second copy our changes that are relivant to the xtuple.modifications folder.
+
+cp explodekit.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+cp x-dragon-deletesoitemcheck.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+cp triggers-coitem.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+
+#modified voidinvoice method?
+cp voidinvoice.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#other changes
+
+#planned applications.
+cp x-dragon-cobapply.sql  ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#showing the exact quantity of stock a particular time.
+cp x-dragon-invdetail-bydate.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#planned inventory transfers
+cp x-dragon-invhist-transfer.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#query optimizations
+cp x-dragon-optimize.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#usefull calculations
+cp x-dragon-salesordercalcs.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#source location and target ship id for planning sales orders and shipments.
+cp x-dragon-salesorder-planning.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+
+#netsuite import tools
+#ItemReciept grouping  and adding old id's for referencing during migration
+cp x-netsuite-recvgrp.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
+cp x-netsuite-mig-extra.sql ~/Dropbox/xtuple_stored_procs/xtuple.modifications/
\ No newline at end of file
diff --git a/pgsql/triggers-cobill.sql b/pgsql/triggers-cobill.sql
new file mode 100644 (file)
index 0000000..d26e055
--- /dev/null
@@ -0,0 +1,124 @@
+--- this has been modified to verify that coitem comes from the same cohead as cobmisc.
+
+
+
+
+CREATE OR REPLACE FUNCTION _cobillBeforeTrigger() RETURNS "trigger" AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+
+BEGIN
+  IF (TG_OP = 'DELETE') THEN
+    DELETE FROM cobilltax
+    WHERE (taxhist_parent_id=OLD.cobill_id);
+
+    RETURN OLD;
+  END IF;
+
+  RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+SELECT dropIfExists('TRIGGER', 'cobillBeforeTrigger');
+CREATE TRIGGER cobillBeforeTrigger
+  BEFORE INSERT OR UPDATE OR DELETE
+  ON cobill
+  FOR EACH ROW
+  EXECUTE PROCEDURE _cobillBeforeTrigger();
+
+CREATE OR REPLACE FUNCTION _cobillTrigger() RETURNS "trigger" AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _r RECORD;
+  v_cohead_id_from_misc NUMERIC;
+  v_cohead_id_from_item NUMERIC;
+  
+BEGIN
+  IF (TG_OP = 'DELETE') THEN
+    RETURN OLD;
+  END IF;
+
+-- Cache Billing Head
+  SELECT * INTO _r
+  FROM cobmisc
+  WHERE (cobmisc_id=NEW.cobill_cobmisc_id);
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Billing head not found';
+  END IF;
+
+
+
+-- verify data..
+   
+    SELECT
+            cobmisc_cohead_id
+        INTO
+            v_cohead_id_from_misc
+        FROM
+            cobmisc
+        WHERE
+            cobmisc_id = NEW.cobill_cobmisc_id;
+    
+    SELECT
+            coitem_cohead_id
+        INTO
+            v_cohead_id_from_item
+        FROM
+            coitem
+        WHERE
+            coitem_id = NEW.cobill_coitem_id;
+    
+    IF v_cohead_id_from_item != v_cohead_id_from_misc THEN
+        RAISE EXCEPTION 'error creating cobill - coitem does not match cohead';
+    END IF;
+     
+
+
+
+-- Insert new row
+  IF (TG_OP = 'INSERT') THEN
+
+  -- Calculate Tax
+      PERFORM calculateTaxHist( 'cobilltax',
+                                NEW.cobill_id,
+                                COALESCE(_r.cobmisc_taxzone_id, -1),
+                                NEW.cobill_taxtype_id,
+                                COALESCE(_r.cobmisc_shipdate, CURRENT_DATE),
+                                COALESCE(_r.cobmisc_curr_id, -1),
+                                (NEW.cobill_qty * coitem_qty_invuomratio) *
+                                (coitem_price / coitem_price_invuomratio) )
+      FROM coitem
+      WHERE (coitem_id=NEW.cobill_coitem_id);
+  END IF;
+
+-- Update row
+  IF (TG_OP = 'UPDATE') THEN
+
+  -- Calculate Tax
+    IF ( (NEW.cobill_qty <> OLD.cobill_qty) OR
+         (NEW.cobill_taxtype_id <> OLD.cobill_taxtype_id) ) THEN
+      PERFORM calculateTaxHist( 'cobilltax',
+                                NEW.cobill_id,
+                                COALESCE(_r.cobmisc_taxzone_id, -1),
+                                NEW.cobill_taxtype_id,
+                                COALESCE(_r.cobmisc_shipdate, CURRENT_DATE),
+                                COALESCE(_r.cobmisc_curr_id, -1),
+                                (NEW.cobill_qty * coitem_qty_invuomratio) *
+                                (coitem_price / coitem_price_invuomratio) )
+      FROM coitem
+      WHERE (coitem_id=NEW.cobill_coitem_id);
+    END IF;
+  END IF;
+
+  RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+SELECT dropIfExists('TRIGGER', 'cobilltrigger');
+CREATE TRIGGER cobilltrigger
+  AFTER INSERT OR UPDATE OR DELETE
+  ON cobill
+  FOR EACH ROW
+  EXECUTE PROCEDURE _cobillTrigger();
\ No newline at end of file
diff --git a/pgsql/triggers-coitem.sql b/pgsql/triggers-coitem.sql
new file mode 100644 (file)
index 0000000..4746aa7
--- /dev/null
@@ -0,0 +1,875 @@
+-- NOTE - only soitemAfterTrigger has been changed.
+-- The key change is related to non-destructive kit part exploding.
+
+
+
+CREATE OR REPLACE FUNCTION _soitemTrigger() RETURNS TRIGGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _cmnttypeid INTEGER;
+  _check BOOLEAN;
+  _kit BOOLEAN;
+  _shipped BOOLEAN;
+  _atShipping NUMERIC;
+  _tmp INTEGER;
+  _rec RECORD;
+BEGIN
+  -- Check
+  SELECT checkPrivilege('MaintainSalesOrders') OR checkPrivilege('ShipOrders') OR checkPrivilege('IssueStockToShipping') INTO _check;
+  IF NOT (_check) THEN
+    RAISE EXCEPTION 'You do not have privileges to alter a Sales Order.';
+  END IF;
+
+  IF (TG_OP IN ('INSERT','UPDATE')) THEN
+    IF (NEW.coitem_scheddate IS NULL) THEN
+      IF (fetchmetricbool('AllowASAPShipSchedules')) THEN
+        NEW.coitem_scheddate := current_date;
+      ELSE
+        RAISE EXCEPTION 'A schedule date is required.';
+      END IF;
+    END IF;
+  END IF;
+
+  IF(TG_OP = 'DELETE') THEN
+    _rec := OLD;
+  ELSE
+    _rec := NEW;
+  END IF;
+  SELECT COALESCE(item_type,'')='K'
+    INTO _kit
+    FROM itemsite, item
+   WHERE((itemsite_item_id=item_id)
+     AND (itemsite_id=_rec.coitem_itemsite_id));
+  _kit := COALESCE(_kit, false);
+  _shipped := false;
+  IF(_kit AND _rec.coitem_status <> 'C' AND _rec.coitem_status <> 'X') THEN
+    SELECT coitem_id
+      INTO _tmp
+      FROM coitem JOIN shipitem ON (shipitem_orderitem_id=coitem_id)
+                  JOIN shiphead ON (shiphead_id=shipitem_shiphead_id AND shiphead_order_type='SO')
+     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
+       AND (coitem_linenumber=_rec.coitem_linenumber)
+       AND (coitem_subnumber > 0))
+     GROUP BY coitem_id
+    HAVING (SUM(shipitem_qty) > 0)
+     LIMIT 1;
+    IF (FOUND) THEN
+      _shipped := true;
+    END IF;
+  END IF;
+  
+  IF (TG_OP ='UPDATE') THEN
+    IF ((OLD.coitem_status <> 'C') AND (NEW.coitem_status = 'C')) THEN
+      SELECT qtyAtShipping(NEW.coitem_id) INTO _atShipping;
+      IF (_atShipping > 0) THEN
+        RAISE EXCEPTION 'Line % cannot be Closed at this time as there is inventory at shipping.',NEW.coitem_linenumber;
+      END IF;
+    END IF;
+  END IF;
+
+  IF ( SELECT (metric_value='t')
+       FROM metric
+       WHERE (metric_name='SalesOrderChangeLog') ) THEN
+--  Cache the cmnttype_id for ChangeLog
+    SELECT cmnttype_id INTO _cmnttypeid
+    FROM cmnttype
+    WHERE (cmnttype_name='ChangeLog');
+  ELSE
+    _cmnttypeid := -1;
+  END IF;
+
+  IF (TG_OP = 'INSERT') THEN
+    INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
+                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
+    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
+           'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber)
+    FROM evntnot, evnttype, itemsite, item, cohead
+    WHERE ( (evntnot_evnttype_id=evnttype_id)
+     AND (evntnot_warehous_id=itemsite_warehous_id)
+     AND (itemsite_id=NEW.coitem_itemsite_id)
+     AND (itemsite_item_id=item_id)
+     AND (NEW.coitem_cohead_id=cohead_id)
+     AND (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
+     AND (evnttype_name='SoitemCreated') );
+
+    IF (_cmnttypeid <> -1) THEN
+      PERFORM postComment(_cmnttypeid, 'SI', NEW.coitem_id, 'Created');
+    END IF;
+
+    --Set defaults if no values passed
+    NEW.coitem_linenumber      := COALESCE(NEW.coitem_linenumber,
+                                          (SELECT (COALESCE(MAX(coitem_linenumber), 0) + 1)
+                                           FROM coitem
+                                           WHERE (coitem_cohead_id=NEW.coitem_cohead_id)));
+    NEW.coitem_status          := COALESCE(NEW.coitem_status,'O');
+    NEW.coitem_scheddate       := COALESCE(NEW.coitem_scheddate,
+                                          (SELECT MIN(coitem_scheddate)
+                                           FROM coitem
+                                           WHERE (coitem_cohead_id=NEW.coitem_cohead_id)));
+    NEW.coitem_memo            := COALESCE(NEW.coitem_memo,'');
+    NEW.coitem_prcost          := COALESCE(NEW.coitem_prcost,0);
+    NEW.coitem_warranty        := COALESCE(NEW.coitem_warranty,false);
+
+    IF (NEW.coitem_status='O') THEN
+      UPDATE cohead SET cohead_status = 'O'
+       WHERE ((cohead_id=NEW.coitem_cohead_id)
+         AND  (cohead_status='C'));
+    END IF;
+
+    RETURN NEW;
+
+  ELSIF (TG_OP = 'DELETE') THEN
+
+      IF(_kit) THEN
+        IF(_shipped) THEN
+          RAISE EXCEPTION 'You can not delete this Sales Order Line as it has several sub components that have already been shipped.';
+        END IF;
+      END IF;
+
+      DELETE FROM comment
+      WHERE ( (comment_source='SI')
+       AND (comment_source_id=OLD.coitem_id) );
+
+      DELETE FROM charass
+       WHERE ((charass_target_type='SI')
+         AND  (charass_target_id=OLD.coitem_id));
+      IF ((OLD.coitem_order_type = 'W') AND
+         (SELECT wo_status IN ('O', 'E')
+           FROM wo
+           WHERE (wo_id=OLD.coitem_order_id))) THEN
+        PERFORM deleteWo(OLD.coitem_order_id, TRUE);
+
+      ELSIF (OLD.coitem_order_type = 'R') THEN 
+        PERFORM deletePr(OLD.coitem_order_id);
+      END IF;
+
+    INSERT INTO evntlog ( evntlog_evnttime, evntlog_username,
+                         evntlog_evnttype_id, evntlog_ordtype,
+                         evntlog_ord_id, evntlog_warehous_id, evntlog_number )
+    SELECT CURRENT_TIMESTAMP, evntnot_username,
+          evnttype_id, 'S',
+          OLD.coitem_id, itemsite_warehous_id,
+          (cohead_number || '-' || OLD.coitem_linenumber)
+    FROM evntnot, evnttype, itemsite, item, cohead
+    WHERE ( (evntnot_evnttype_id=evnttype_id)
+     AND (evntnot_warehous_id=itemsite_warehous_id)
+     AND (itemsite_id=OLD.coitem_itemsite_id)
+     AND (itemsite_item_id=item_id)
+     AND (OLD.coitem_cohead_id=cohead_id)
+     AND (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
+     AND (evnttype_name='SoitemCancelled') );
+
+  ELSIF (TG_OP = 'UPDATE') THEN
+    IF (NEW.coitem_qtyord <> OLD.coitem_qtyord) THEN
+      IF(_kit) THEN
+        IF(_shipped) THEN
+          RAISE EXCEPTION 'You can not change the qty ordered for a Kit item when one or more of its components have shipped inventory.';
+        END IF;
+      END IF;
+      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
+                           evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
+                           evntlog_oldvalue, evntlog_newvalue )
+      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
+            'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber),
+            OLD.coitem_qtyord, NEW.coitem_qtyord
+      FROM evntnot, evnttype, itemsite, item, cohead
+      WHERE ( (evntnot_evnttype_id=evnttype_id)
+       AND (evntnot_warehous_id=itemsite_warehous_id)
+       AND (itemsite_id=NEW.coitem_itemsite_id)
+       AND (itemsite_item_id=item_id)
+       AND (NEW.coitem_cohead_id=cohead_id)
+       AND ( (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
+       OR   (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence)) )
+       AND (evnttype_name='SoitemQtyChanged') );
+
+      IF (_cmnttypeid <> -1) THEN
+       PERFORM postComment( _cmnttypeid, 'SI', NEW.coitem_id,
+                            ( 'Changed Qty. Ordered from ' || formatQty(OLD.coitem_qtyord) ||
+                              ' to ' || formatQty(NEW.coitem_qtyord) ) );
+      END IF;
+
+    END IF;
+
+    IF (NEW.coitem_scheddate <> OLD.coitem_scheddate) THEN
+      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
+                           evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
+                           evntlog_olddate, evntlog_newdate )
+      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
+            'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber),
+            OLD.coitem_scheddate, NEW.coitem_scheddate
+      FROM evntnot, evnttype, itemsite, item, cohead
+      WHERE ( (evntnot_evnttype_id=evnttype_id)
+       AND (evntnot_warehous_id=itemsite_warehous_id)
+       AND (itemsite_id=NEW.coitem_itemsite_id)
+       AND (itemsite_item_id=item_id)
+       AND (NEW.coitem_cohead_id=cohead_id)
+       AND ( (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
+       OR   (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence)) )
+       AND (evnttype_name='SoitemSchedDateChanged') );
+
+      IF (_cmnttypeid <> -1) THEN
+       PERFORM postComment( _cmnttypeid, 'SI', NEW.coitem_id,
+                            ( 'Changed Sched. Date from ' || formatDate(OLD.coitem_scheddate) ||
+                              ' to ' || formatDate(NEW.coitem_scheddate)) );
+      END IF;
+
+    END IF;
+
+    IF ((NEW.coitem_status = 'C') AND (OLD.coitem_status <> 'C')) THEN
+      NEW.coitem_closedate = CURRENT_TIMESTAMP;
+      NEW.coitem_close_username = getEffectiveXtUser();
+      NEW.coitem_qtyreserved := 0;
+
+      IF (_cmnttypeid <> -1) THEN
+       PERFORM postComment(_cmnttypeid, 'SI', NEW.coitem_id, 'Closed');
+      END IF;
+    END IF;
+
+    IF ((NEW.coitem_status <> 'C') AND (OLD.coitem_status = 'C')) THEN
+      NEW.coitem_closedate = NULL;
+      NEW.coitem_close_username = NULL;
+
+      IF (_cmnttypeid <> -1) THEN
+       PERFORM postComment(_cmnttypeid, 'SI', NEW.coitem_id, 'Reopened');
+      END IF;
+    END IF;
+
+    IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
+      IF ((OLD.coitem_order_type = 'W') AND
+         (SELECT wo_status IN ('O', 'E', 'R')
+           FROM wo
+           WHERE (wo_id=OLD.coitem_order_id))) THEN
+      -- Close any associated W/O
+        PERFORM closeWo(OLD.coitem_order_id, FALSE, CURRENT_DATE);
+      ELSIF (OLD.coitem_order_type = 'R') THEN 
+      -- Delete any associated P/R
+        PERFORM deletePr(OLD.coitem_order_id);
+      END IF;
+
+      NEW.coitem_qtyreserved := 0;
+
+      IF (_cmnttypeid <> -1) THEN
+       PERFORM postComment(_cmnttypeid, 'SI', NEW.coitem_id, 'Canceled');
+       PERFORM postComment(_cmnttypeid, 'S', NEW.coitem_cohead_id, 'Line # '|| NEW.coitem_linenumber ||' Canceled');
+      END IF;
+
+      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username,
+                           evntlog_evnttype_id, evntlog_ordtype,
+                           evntlog_ord_id, evntlog_warehous_id, evntlog_number )
+      SELECT CURRENT_TIMESTAMP, evntnot_username,
+            evnttype_id, 'S',
+            OLD.coitem_id, itemsite_warehous_id,
+            (cohead_number || '-' || OLD.coitem_linenumber)
+      FROM evntnot, evnttype, itemsite, item, cohead
+      WHERE ( (evntnot_evnttype_id=evnttype_id)
+       AND (evntnot_warehous_id=itemsite_warehous_id)
+       AND (itemsite_id=OLD.coitem_itemsite_id)
+       AND (itemsite_item_id=item_id)
+       AND (OLD.coitem_cohead_id=cohead_id)
+       AND (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
+       AND (evnttype_name='SoitemCancelled') );
+
+    END IF;
+
+    IF ((NEW.coitem_qtyreserved <> OLD.coitem_qtyreserved) AND (_cmnttypeid <> -1)) THEN
+      PERFORM postComment(_cmnttypeid, 'SI', NEW.coitem_id, 'Changed Qty Reserved to '|| NEW.coitem_qtyreserved);
+    END IF;
+
+  END IF;
+
+  IF (TG_OP = 'DELETE') THEN
+    RETURN OLD;
+  END IF;
+
+  NEW.coitem_lastupdated = CURRENT_TIMESTAMP;
+
+  -- Handle status for header
+  IF (TG_OP = 'DELETE') THEN
+    IF (OLD.coitem_status = 'O') THEN
+      IF ( (SELECT (count(*) < 1)
+              FROM coitem
+             WHERE ((coitem_cohead_id=OLD.coitem_cohead_id)
+               AND  (coitem_id != OLD.coitem_id)
+               AND  (coitem_status = 'O')) ) ) THEN
+        UPDATE cohead SET cohead_status = 'C'
+         WHERE ((cohead_id=OLD.coitem_pohead_id)
+           AND  (cohead_status='O'));
+      END IF;
+    END IF;
+
+    RETURN OLD;
+  END IF;
+
+  IF (TG_OP = 'UPDATE') THEN
+    IF (OLD.coitem_status <> NEW.coitem_status) THEN
+      IF ( (SELECT (count(*) < 1)
+              FROM coitem
+             WHERE ((coitem_cohead_id=NEW.coitem_cohead_id)
+               AND  (coitem_id != NEW.coitem_id)
+               AND  (coitem_status='O')) ) AND (NEW.coitem_status<>'O') ) THEN
+        UPDATE cohead SET cohead_status = 'C'
+         WHERE ((cohead_id=NEW.coitem_cohead_id)
+           AND  (cohead_status='O'));
+      ELSE
+        UPDATE cohead SET cohead_status = 'O'
+         WHERE ((cohead_id=NEW.coitem_cohead_id)
+           AND  (cohead_status='C'));
+      END IF;
+    END IF;
+  END IF;
+
+  RETURN NEW;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+DROP TRIGGER soitemTrigger ON coitem;
+CREATE TRIGGER soitemTrigger BEFORE INSERT OR UPDATE OR DELETE ON coitem FOR EACH ROW EXECUTE PROCEDURE _soitemTrigger();
+
+
+
+
+--BEFORE TRIGGER
+
+
+CREATE OR REPLACE FUNCTION _soitemBeforeTrigger() RETURNS TRIGGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _check NUMERIC;
+  _itemNumber TEXT;
+  _r RECORD;
+  _kit BOOLEAN;
+
+BEGIN
+
+  --Determine if this is a kit for later processing
+  SELECT COALESCE(item_type,'')='K'
+  INTO _kit
+  FROM itemsite, item
+  WHERE((itemsite_item_id=item_id)
+  AND (itemsite_id=NEW.coitem_itemsite_id));
+  _kit := COALESCE(_kit, false);
+  
+  IF (TG_OP = 'INSERT') THEN
+
+    -- If this is imported, go ahead and insert default characteristics
+    IF (NEW.coitem_imported) THEN
+      INSERT INTO charass (charass_target_type, charass_target_id, charass_char_id, charass_value, charass_price)
+      SELECT 'SI', NEW.coitem_id, char_id, charass_value,
+             itemcharprice(item_id,char_id,charass_value,cohead_cust_id,cohead_shipto_id,NEW.coitem_qtyord,cohead_curr_id,cohead_orderdate) 
+        FROM (
+           SELECT DISTINCT char_id, char_name, charass_value, item_id, cohead_cust_id, cohead_shipto_id, cohead_curr_id, cohead_orderdate
+             FROM cohead, charass, char, itemsite, item
+            WHERE((itemsite_id=NEW.coitem_itemsite_id)
+              AND (itemsite_item_id=item_id)
+              AND (charass_target_type='I') 
+              AND (charass_target_id=item_id)
+              AND (charass_default)
+              AND (char_id=charass_char_id)
+              AND (cohead_id=NEW.coitem_cohead_id))
+           ORDER BY char_name) AS data;
+    END IF;
+  END IF;
+
+  -- Create work order and process if flagged to do so
+  IF ((NEW.coitem_order_type='W') AND (NEW.coitem_order_id=-1)) THEN
+    SELECT createwo(CAST(cohead_number AS INTEGER),
+                    NEW.coitem_itemsite_id,
+                    1, -- priority
+                   validateOrderQty(NEW.coitem_itemsite_id, NEW.coitem_qtyord, TRUE),
+                    itemsite_leadtime,
+                    NEW.coitem_scheddate,
+                   NEW.coitem_memo,
+                    'S',
+                    NEW.coitem_id,
+                   cohead_prj_id) INTO NEW.coitem_order_id
+    FROM cohead, itemsite 
+    WHERE ((cohead_id=NEW.coitem_cohead_id)
+    AND (itemsite_id=NEW.coitem_itemsite_id));
+
+    INSERT INTO charass
+      (charass_target_type, charass_target_id,
+       charass_char_id, charass_value) 
+       SELECT 'W', NEW.coitem_order_id, charass_char_id, charass_value
+       FROM charass
+       WHERE ((charass_target_type='SI')
+       AND  (charass_target_id=NEW.coitem_id));
+  END IF;
+   
+  IF (TG_OP = 'UPDATE') THEN
+--  Update P/R date if applicable
+
+    IF (NEW.coitem_scheddate <> OLD.coitem_scheddate AND NEW.coitem_order_type='R' AND NEW.coitem_order_id > 1) THEN
+      UPDATE pr SET pr_duedate = NEW.coitem_scheddate WHERE (pr_order_id=NEW.coitem_id AND pr_order_type='S');
+    END IF;
+    
+--  If closing or cancelling and there is a job item work order, then close job and distribute remaining costs
+    IF ((NEW.coitem_status = 'C' AND OLD.coitem_status <> 'C')
+     OR (NEW.coitem_status = 'X' AND OLD.coitem_status <> 'X'))
+     AND (OLD.coitem_order_id > -1) THEN
+
+      SELECT wo_id, wo_wipvalue INTO _r
+       FROM wo,itemsite,item
+      WHERE ((wo_ordtype='S')
+      AND (wo_ordid=OLD.coitem_id)
+      AND (itemsite_id=wo_itemsite_id)
+      AND (item_id=itemsite_item_id)
+      AND (itemsite_costmethod = 'J'));
+
+      IF (FOUND) THEN
+        IF (_r.wo_wipvalue > 0) THEN
+        --  Distribute to G/L, debit Cost of Sales, credit WIP
+          PERFORM MIN(insertGLTransaction( 'W/O', 'WO', formatWoNumber(NEW.coitem_order_id), 'Job Closed Incomplete',
+                                       costcat_wip_accnt_id,
+                                       CASE WHEN(COALESCE(NEW.coitem_cos_accnt_id, -1) != -1) THEN NEW.coitem_cos_accnt_id
+                                          WHEN(NEW.coitem_warranty=TRUE) THEN resolveCOWAccount(itemsite_id, cohead_cust_id)
+                                          ELSE resolveCOSAccount(itemsite_id, cohead_cust_id)
+                                       END,
+                                       -1,  _r.wo_wipvalue, current_date ))
+          FROM itemsite, costcat, cohead
+          WHERE ((itemsite_id=NEW.coitem_itemsite_id)
+           AND (itemsite_costcat_id=costcat_id)
+           AND (cohead_id=NEW.coitem_cohead_id));
+        END IF;
+
+        UPDATE wo SET
+          wo_status = 'C',
+          wo_wipvalue = 0
+        WHERE (wo_id = _r.wo_id);
+
+      END IF;
+    END IF;
+
+--  Likewise, reopen the job if line reopened
+    IF ((NEW.coitem_status != 'C' AND OLD.coitem_status = 'C')
+     OR (NEW.coitem_status != 'X' AND OLD.coitem_status = 'X'))
+     AND (OLD.coitem_order_id > -1) THEN
+        UPDATE wo SET
+          wo_status = 'I'
+        FROM itemsite, item
+        WHERE ((wo_ordtype = 'S')
+         AND (wo_ordid=NEW.coitem_id)
+         AND (wo_itemsite_id=itemsite_id)
+         AND (itemsite_item_id=item_id)
+         AND (itemsite_costmethod='J'));
+    END IF;
+
+--  Handle links to Return Authorization
+    IF (fetchMetricBool('EnableReturnAuth')) THEN 
+      SELECT * INTO _r 
+      FROM raitem,rahead 
+      WHERE ((raitem_new_coitem_id=NEW.coitem_id)
+      AND (rahead_id=raitem_rahead_id));
+      IF (FOUND) THEN
+        IF ((_r.raitem_qtyauthorized <> NEW.coitem_qtyord OR
+            _r.raitem_qty_uom_id <> NEW.coitem_qty_uom_id OR
+            _r.raitem_qty_invuomratio <> NEW.coitem_qty_invuomratio OR
+            _r.raitem_price_uom_id <> NEW.coitem_price_uom_id OR
+            _r.raitem_price_invuomratio <> NEW.coitem_price_invuomratio)
+            AND NOT (NEW.coitem_status = 'X' AND _r.raitem_qtyauthorized = 0)) THEN
+          RAISE EXCEPTION 'Quantities for line item % may only be changed on the Return Authorization that created it.',NEW.coitem_linenumber;
+        END IF;
+        IF (OLD.coitem_warranty <> NEW.coitem_warranty) THEN
+          UPDATE raitem SET raitem_warranty = NEW.coitem_warranty
+           WHERE((raitem_new_coitem_id=NEW.coitem_id)
+             AND (raitem_warranty != NEW.coitem_warranty));
+        END IF;
+        IF (OLD.coitem_cos_accnt_id <> NEW.coitem_cos_accnt_id) THEN
+          UPDATE raitem SET raitem_cos_accnt_id = NEW.coitem_cos_accnt_id
+           WHERE((raitem_new_coitem_id=NEW.coitem_id)
+             AND (COALESCE(raitem_cos_accnt_id,-1) != COALESCE(NEW.coitem_cos_accnt_id,-1)));
+        END IF;
+        IF (OLD.coitem_taxtype_id <> NEW.coitem_taxtype_id) THEN
+          UPDATE raitem SET raitem_taxtype_id = NEW.coitem_taxtype_id
+           WHERE((raitem_new_coitem_id=NEW.coitem_id)
+             AND (COALESCE(raitem_taxtype_id,-1) != COALESCE(NEW.coitem_taxtype_id,-1)));
+        END IF;
+        IF (OLD.coitem_scheddate <> NEW.coitem_scheddate) THEN
+          UPDATE raitem SET raitem_scheddate = NEW.coitem_scheddate
+           WHERE((raitem_new_coitem_id=NEW.coitem_id)
+             AND (raitem_scheddate != NEW.coitem_scheddate));
+        END IF;
+        IF (OLD.coitem_memo <> NEW.coitem_memo) THEN
+          UPDATE raitem SET raitem_notes = NEW.coitem_memo
+           WHERE((raitem_new_coitem_id=NEW.coitem_id)
+             AND (raitem_notes != NEW.coitem_memo));
+        END IF;
+        IF ((OLD.coitem_qtyshipped <> NEW.coitem_qtyshipped) AND 
+           (NEW.coitem_qtyshipped >= _r.raitem_qtyauthorized) AND
+           ((_r.raitem_disposition = 'S') OR
+           (_r.raitem_status = 'O') AND
+           (_r.raitem_disposition IN ('P','V')) AND
+           (_r.raitem_qtyreceived >= _r.raitem_qtyauthorized))) THEN
+          UPDATE raitem SET raitem_status = 'C' 
+          WHERE (raitem_new_coitem_id=NEW.coitem_id);
+        END IF;
+      END IF;
+    END IF; 
+  END IF; 
+
+  RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+DROP TRIGGER soitemBeforeTrigger ON coitem;
+CREATE TRIGGER soitemBeforeTrigger BEFORE INSERT OR UPDATE ON coitem FOR EACH ROW EXECUTE PROCEDURE _soitemBeforeTrigger();
+-- TODO: there are two BEFORE triggers. should these be merged?
+
+
+-- AFTER TRIGGER
+
+
+CREATE OR REPLACE FUNCTION _soitemAfterTrigger() RETURNS TRIGGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  _check NUMERIC;
+  _custID INTEGER;
+  _po BOOLEAN;
+  _kit BOOLEAN;
+  _fractional BOOLEAN;
+  _purchase BOOLEAN;
+  _rec RECORD;
+  _kstat TEXT;
+  _pstat TEXT;
+  _result INTEGER;
+  _coitemid INTEGER;
+  _itemsrcid INTEGER;
+  _mustdelete INTEGER;
+  _subnumber INTEGER;  
+
+BEGIN
+
+  IF(TG_OP = 'DELETE') THEN
+    _rec := OLD;
+  ELSE
+    _rec := NEW;
+  END IF;
+
+  --Cache some information
+  SELECT cohead_cust_id INTO _custID
+  FROM cohead
+  WHERE (cohead_id=_rec.coitem_cohead_id);
+
+  --Determine if this is a kit for later processing
+  SELECT COALESCE(item_type,'')='K', item_fractional
+    INTO _kit, _fractional
+    FROM itemsite, item
+   WHERE((itemsite_item_id=item_id)
+     AND (itemsite_id=_rec.coitem_itemsite_id));
+  _kit := COALESCE(_kit, false);
+  _fractional := COALESCE(_fractional, false);
+
+ --Select purchase items
+  SELECT COALESCE(item_type,'')='P'
+    INTO _purchase
+    FROM itemsite JOIN item ON (itemsite_item_id=item_id)
+   WHERE (itemsite_id=_rec.coitem_itemsite_id);
+  _purchase := COALESCE(_purchase, false);
+ --Select salesorder related to purchaseorder 
+  SELECT itemsite_createsopo INTO _po 
+  FROM itemsite JOIN coitem ON  (itemsite_id=coitem_itemsite_id) 
+  WHERE (coitem_id=_rec.coitem_id);
+
+  IF (_kit) THEN
+  -- Kit Processing
+    IF (TG_OP = 'INSERT') THEN
+  -- Create Sub Lines for Kit Components
+      PERFORM explodeKit(NEW.coitem_cohead_id, NEW.coitem_linenumber, 0, NEW.coitem_itemsite_id,
+                         NEW.coitem_qtyord, NEW.coitem_scheddate, NEW.coitem_promdate, NEW.coitem_memo);
+      IF (fetchMetricBool('KitComponentInheritCOS')) THEN
+  -- Update kit line item COS
+        UPDATE coitem
+        SET coitem_cos_accnt_id = CASE WHEN (COALESCE(NEW.coitem_cos_accnt_id, -1) != -1) THEN NEW.coitem_cos_accnt_id
+                                       WHEN (NEW.coitem_warranty) THEN resolveCOWAccount(NEW.coitem_itemsite_id, _custID)
+                                       ELSE resolveCOSAccount(NEW.coitem_itemsite_id, _custID)
+                                  END
+        WHERE((coitem_cohead_id=NEW.coitem_cohead_id)
+          AND (coitem_linenumber = NEW.coitem_linenumber)
+          AND (coitem_subnumber > 0));
+      END IF;
+    END IF;
+    IF (TG_OP = 'UPDATE') THEN
+    
+    
+      IF (NEW.coitem_qtyord <> OLD.coitem_qtyord) THEN
+  -- Recreate Sub Lines for Kit Components
+  
+        
+        SELECT explodeKitMustDelete(
+        
+            NEW.coitem_cohead_id, NEW.coitem_linenumber,
+            0, NEW.coitem_itemsite_id
+        ) INTO _mustdelete;
+  
+    
+    
+        FOR _coitemid IN
+            SELECT coitem_id
+                FROM coitem
+                WHERE
+                    (
+                        (coitem_cohead_id=OLD.coitem_cohead_id)
+                        AND
+                        (coitem_linenumber=OLD.coitem_linenumber)
+                        AND
+                        (coitem_subnumber > 0)
+                    )
+        LOOP
+        
+          --SELECT deleteSoItem(_coitemid) INTO _result;
+            IF (_mustdelete > 0) THEN
+              SELECT deleteSoItem(_coitemid) INTO _result;
+            ELSE
+                -- if not delete, see if we could...
+                BEGIN
+                    SELECT deleteSoItemCheck(_coitemid) INTO _result;
+                EXCEPTION WHEN OTHERS THEN
+                    _result := 0;
+                    RAISE NOTICE 'ok to delete';
+
+                END;
+            END IF;
+            IF (_result < 0) THEN
+               RAISE EXCEPTION 'Error deleting kit components: deleteSoItemCheck(integer) Error:%', _result;
+            END IF;
+            
+        END LOOP;
+            
+            -- at this point we have not deleted anything..
+            -- we have checked that it is feasible though..
+            
+            
+        SELECT explodeKit(
+        
+                NEW.coitem_cohead_id, NEW.coitem_linenumber,
+                0, NEW.coitem_itemsite_id,
+                
+                NEW.coitem_qtyord, NEW.coitem_scheddate,
+                NEW.coitem_promdate
+            ) INTO  _subnumber;
+        
+        IF (_mustdelete < 1) THEN
+            -- if we where updating.. then trash all the extra lines..
+            -- we can ignore results, as we know it will work based on the check above..
+            PERFORM deleteSoItem(coitem_id) 
+                FROM coitem
+                WHERE
+                    (
+                        (coitem_cohead_id=OLD.coitem_cohead_id)
+                        AND
+                        (coitem_linenumber=OLD.coitem_linenumber)
+                        AND
+                        (coitem_subnumber > _subnumber)
+                    );
+        END IF;
+        
+                       
+                             
+                             
+                           
+      END IF;
+      IF ( (NEW.coitem_qtyord <> OLD.coitem_qtyord) OR
+           (NEW.coitem_cos_accnt_id <> OLD.coitem_cos_accnt_id) ) THEN
+        IF (fetchMetricBool('KitComponentInheritCOS')) THEN
+  -- Update kit line item COS
+          UPDATE coitem
+          SET coitem_cos_accnt_id = CASE WHEN (COALESCE(NEW.coitem_cos_accnt_id, -1) != -1) THEN NEW.coitem_cos_accnt_id
+                                         WHEN (NEW.coitem_warranty) THEN resolveCOWAccount(NEW.coitem_itemsite_id, _custID)
+                                         ELSE resolveCOSAccount(NEW.coitem_itemsite_id, _custID)
+                                    END
+          WHERE((coitem_cohead_id=NEW.coitem_cohead_id)
+            AND (coitem_linenumber = NEW.coitem_linenumber)
+            AND (coitem_subnumber > 0));
+        END IF;
+      END IF;
+    END IF;
+    IF (TG_OP = 'DELETE') THEN
+  -- Delete Sub Lines for Kit Components
+     FOR _coitemid IN
+        SELECT coitem_id
+        FROM coitem
+        WHERE ( (coitem_cohead_id=OLD.coitem_cohead_id)
+          AND   (coitem_linenumber=OLD.coitem_linenumber)
+          AND   (coitem_subnumber > 0) )
+      LOOP
+        SELECT deleteSoItem(_coitemid) INTO _result;
+        IF (_result < 0) THEN
+           RAISE EXCEPTION 'Error deleting kit components: deleteSoItem(integer) Error:%', _result;
+        END IF;
+      END LOOP;
+    END IF;
+  END IF;
+
+  IF (TG_OP = 'INSERT') THEN
+    -- Create Purchase Order if flagged to do so
+    IF ((NEW.coitem_order_type='P') AND (NEW.coitem_order_id=-1)) THEN
+      SELECT itemsrc_id INTO _itemsrcid
+      FROM itemsite JOIN itemsrc ON (itemsrc_item_id=itemsite_item_id AND itemsrc_default)
+      WHERE (itemsite_id=NEW.coitem_itemsite_id);
+      IF (FOUND) THEN
+        SELECT createPurchaseToSale(NEW.coitem_id,
+                                    _itemsrcid,
+                                    itemsite_dropship,
+                                    CASE WHEN (NEW.coitem_prcost=0.0) THEN NULL
+                                         ELSE NEW.coitem_prcost
+                                    END) INTO NEW.coitem_order_id
+        FROM itemsite
+        WHERE (itemsite_id=NEW.coitem_itemsite_id);
+      END IF;
+    END IF;
+  END IF;
+
+  IF (_purchase) THEN
+    --For purchase item processing
+--    IF (fetchmetricbool('EnableDropShipments')) THEN
+--      --Dropship processing
+      IF(_po) THEN
+        IF (TG_OP = 'UPDATE') THEN
+          IF ((NEW.coitem_qtyord <> OLD.coitem_qtyord) OR (NEW.coitem_qty_invuomratio <> OLD.coitem_qty_invuomratio) OR (NEW.coitem_scheddate <> OLD.coitem_scheddate)) THEN
+            --Update related poitem
+            UPDATE poitem
+            SET poitem_qty_ordered = roundQty(_fractional, (NEW.coitem_qtyord * NEW.coitem_qty_invuomratio / poitem_invvenduomratio)),
+                poitem_duedate = NEW.coitem_scheddate 
+            WHERE (poitem_id = OLD.coitem_order_id);
+
+            --Generate the PoItemUpdatedBySo event
+            INSERT INTO evntlog
+                        ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
+                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
+                          evntlog_number )
+            SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
+              'P', poitem_id, itemsite_warehous_id,
+            (pohead_number || '-'|| poitem_linenumber || ': ' || item_number)
+            FROM evntnot JOIN evnttype ON (evntnot_evnttype_id=evnttype_id)
+                 JOIN itemsite ON (evntnot_warehous_id=itemsite_warehous_id)
+                 JOIN item ON (itemsite_item_id=item_id)
+                 JOIN poitem ON (poitem_itemsite_id=itemsite_id)
+                 JOIN pohead ON (poitem_pohead_id=pohead_id)
+            WHERE( (poitem_id=OLD.coitem_order_id)
+            AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
+            AND (evnttype_name='PoItemUpdatedBySo') );
+          END IF;
+
+          --If soitem is cancelled
+          IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
+            --Generate the PoItemSoCancelled event
+            INSERT INTO evntlog
+                        ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
+                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
+                          evntlog_number )
+            SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
+            'P', poitem_id, itemsite_warehous_id,
+            (pohead_number || '-' || poitem_linenumber || ': ' || item_number)
+            FROM evntnot JOIN evnttype ON (evntnot_evnttype_id=evnttype_id)
+                 JOIN itemsite ON (evntnot_warehous_id=itemsite_warehous_id)
+                 JOIN item ON (itemsite_item_id=item_id)
+                 JOIN poitem ON (poitem_itemsite_id=itemsite_id)
+            JOIN pohead ON( poitem_pohead_id=pohead_id)
+            WHERE( (poitem_id=OLD.coitem_order_id)
+            AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
+            AND (evnttype_name='PoItemSoCancelled') );
+          END IF;
+        END IF;
+      END IF; 
+--    END IF;
+  END IF;
+
+  IF (_rec.coitem_subnumber > 0) THEN
+    SELECT coitem_status
+      INTO _kstat
+      FROM coitem
+     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
+       AND (coitem_linenumber=_rec.coitem_linenumber)
+       AND (coitem_subnumber = 0));
+    IF ((SELECT count(*)
+           FROM coitem
+          WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
+            AND (coitem_linenumber=_rec.coitem_linenumber)
+            AND (coitem_subnumber <> _rec.coitem_subnumber)
+            AND (coitem_subnumber > 0)
+            AND (coitem_status = 'O'))) > 0) THEN
+      _pstat := 'O';
+    ELSE
+      _pstat := _rec.coitem_status;
+    END IF;
+  END IF;
+
+  IF(TG_OP = 'INSERT') THEN
+    IF (_rec.coitem_subnumber > 0 AND _rec.coitem_status = 'O') THEN
+      _pstat := 'O';
+    END IF;
+  ELSIF (TG_OP = 'UPDATE') THEN
+    IF (_rec.coitem_subnumber > 0 AND _rec.coitem_status = 'O') THEN
+      _pstat := 'O';
+    END IF;
+
+    IF ((NEW.coitem_status = 'C') AND (OLD.coitem_status <> 'C')) THEN
+      IF(_kit) THEN
+        UPDATE coitem
+           SET coitem_status='C'
+         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
+           AND (coitem_linenumber=OLD.coitem_linenumber)
+           AND (coitem_status='O')
+           AND (coitem_subnumber > 0));
+      END IF;
+    END IF;
+
+    IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
+      IF(_kit) THEN
+        UPDATE coitem
+           SET coitem_status='X'
+         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
+           AND (coitem_linenumber=OLD.coitem_linenumber)
+           AND (coitem_status='O')
+           AND (coitem_subnumber > 0));
+      END IF;
+    END IF;
+
+    IF(NEW.coitem_status = 'O' AND OLD.coitem_status <> 'O') THEN
+      IF(_kit) THEN
+        UPDATE coitem
+           SET coitem_status='O'
+         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
+           AND (coitem_linenumber=OLD.coitem_linenumber)
+           AND ((COALESCE(coitem_qtyord,0) - COALESCE(coitem_qtyshipped,0) + COALESCE(coitem_qtyreturned,0)) > 0)
+           AND (coitem_subnumber > 0));
+      END IF;
+    END IF;
+
+  END IF;
+
+  IF ((_kstat IS NOT NULL) AND (_pstat IS NOT NULL) AND (_rec.coitem_subnumber > 0) AND (_kstat <> _pstat)) THEN
+    UPDATE coitem
+       SET coitem_status = _pstat
+     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
+       AND (coitem_subnumber = 0));
+  END IF;
+
+  IF(TG_OP = 'DELETE') THEN
+    RETURN OLD;
+  END IF;
+
+  --If auto calculate freight, recalculate cohead_freight
+  IF (SELECT cohead_calcfreight FROM cohead WHERE (cohead_id=NEW.coitem_cohead_id)) THEN
+    UPDATE cohead SET cohead_freight = COALESCE(
+      (SELECT SUM(freightdata_total) FROM freightDetail('SO',
+                                                        cohead_id,
+                                                        cohead_cust_id,
+                                                        cohead_shipto_id,
+                                                        cohead_orderdate,
+                                                        cohead_shipvia,
+                                                        cohead_curr_id)), 0)
+    WHERE cohead_id=NEW.coitem_cohead_id;
+  END IF;
+
+  RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+SELECT dropIfExists('TRIGGER', 'soitemAfterTrigger');
+CREATE TRIGGER soitemAfterTrigger AFTER INSERT OR UPDATE OR DELETE ON coitem FOR EACH ROW EXECUTE PROCEDURE _soitemAfterTrigger();
diff --git a/pgsql/valueatshipping.sql b/pgsql/valueatshipping.sql
new file mode 100644 (file)
index 0000000..5d7220a
--- /dev/null
@@ -0,0 +1,54 @@
+-- Function: valueatshipping(text, integer)
+
+-- DROP FUNCTION valueatshipping(text, integer);
+
+CREATE OR REPLACE FUNCTION valueatshipping(text, integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pordertype    ALIAS FOR $1;
+  plineitemid    ALIAS FOR $2;
+  _qty NUMERIC;
+  _cost NUMERIC;
+  _value NUMERIC;
+
+BEGIN
+
+  IF (pordertype NOT IN ('SO', 'TO')) THEN
+    RAISE EXCEPTION '% is not a valid order type', pordertype;
+  END IF;
+
+  SELECT COALESCE(SUM(shipitem_qty), 0.0) INTO _qty
+  FROM shipitem, shiphead
+  WHERE ((shipitem_shiphead_id=shiphead_id)
+    AND  (NOT shiphead_shipped)
+    AND  (shiphead_order_type=pordertype)
+    AND  (shipitem_orderitem_id=plineitemid) );
+
+  IF (pordertype = 'SO') THEN
+    SELECT COALESCE(CASE WHEN (itemsite_costmethod = 'N') THEN 0
+                         WHEN (itemsite_costmethod = 'S') THEN itemcost_dispense(itemsite_item_id, _qty)
+                         ELSE avgCost(itemsite_item_id)
+                    END, 0.0) INTO _cost
+    FROM coitem JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
+    WHERE (coitem_id=plineitemid);
+  ELSE
+    SELECT COALESCE(CASE WHEN (itemsite_costmethod = 'N') THEN 0
+                         WHEN (itemsite_costmethod = 'S') THEN stdCost(itemsite_item_id)
+                         ELSE avgCost(itemsite_item_id)
+                    END, 0.0) INTO _cost
+    FROM toitem JOIN tohead ON (tohead_id=toitem_tohead_id)
+                JOIN itemsite ON ((itemsite_item_id=toitem_item_id) AND
+                                  (itemsite_warehous_id=tohead_src_warehous_id))
+    WHERE (toitem_id=plineitemid);
+  END IF;
+
+  _value := _qty * _cost;
+
+  RETURN _value;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION valueatshipping(text, integer) OWNER TO "admin";
diff --git a/pgsql/voheadaftertrigger.sql b/pgsql/voheadaftertrigger.sql
new file mode 100644 (file)
index 0000000..74c930c
--- /dev/null
@@ -0,0 +1,47 @@
+
+CREATE OR REPLACE FUNCTION _voheadAfterTrigger() RETURNS "trigger" AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+BEGIN
+  IF (TG_OP = 'DELETE') THEN
+  
+    IF OLD.vohead_number  ~ E'^\\d+$' THEN 
+        PERFORM releaseVoNumber(CAST(OLD.vohead_number AS INTEGER));
+    END IF;
+    
+    RETURN OLD;
+  END IF;
+
+  IF (TG_OP = 'INSERT') THEN
+  
+    -- PERFORM clearNumberIssue('VcNumber', NEW.vohead_number);
+    RETURN NEW;
+  END IF;
+
+  IF (TG_OP = 'UPDATE') THEN
+    IF ( (COALESCE(NEW.vohead_taxzone_id,-1) <> COALESCE(OLD.vohead_taxzone_id,-1)) OR
+         (NEW.vohead_docdate <> OLD.vohead_docdate) OR
+         (NEW.vohead_curr_id <> OLD.vohead_curr_id) ) THEN
+      PERFORM calculateTaxHist( 'voitemtax',
+                                voitem_id,
+                                NEW.vohead_taxzone_id,
+                                voitem_taxtype_id,
+                                NEW.vohead_docdate,
+                                NEW.vohead_curr_id,
+                                (vodist_amount * -1) )
+      FROM voitem JOIN vodist ON ( (vodist_vohead_id=voitem_vohead_id) AND
+                                   (vodist_poitem_id=voitem_poitem_id) )
+      WHERE (voitem_vohead_id = NEW.vohead_id);
+    END IF;
+
+    -- Touch any Misc Tax Distributions so voheadtax is recalculated
+    IF (NEW.vohead_docdate <> OLD.vohead_docdate) THEN
+      UPDATE vodist SET vodist_vohead_id=NEW.vohead_id
+      WHERE ( (vodist_vohead_id=OLD.vohead_id)
+        AND   (vodist_tax_id <> -1) );
+    END IF;
+  END IF;
+
+  RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
diff --git a/pgsql/voidapcreditmemoapplication.sql b/pgsql/voidapcreditmemoapplication.sql
new file mode 100644 (file)
index 0000000..07fb7e0
--- /dev/null
@@ -0,0 +1,325 @@
+-- effort to void ar cm apply , so that invoice void works.. 
+-- it basically creates a DM/CM pair and moves the application to that..
+  
+-- verify that curr_id on both source and target are the esame, if they are not, then we can not do this..
+
+
+
+-- NEED TO VERIFY THIS WILL WORK
+
+-- process : create invoice , create check payment and credit it- look at all gltrans that have been made..
+
+
+-- before start last gltrans_id = 656889
+
+-- GLTRANS:
+-- Invoice  SALES (ADD) / AR (DEDUCT)
+-- Check  AR (ADD) / Bank (DEDUCT)
+
+
+-- AROPEN:
+-- Only one item created.. - paid is filled in... (I)
+
+-- ARAPPLY (id = 7475)
+-- Funds type 'C'  sourcedoc = 'K' targetdoc = 'I'
+--?? JOURNAL ENTRY?? - which one..
+
+-- now try our CM/DM process.
+-- Credit MEMO
+-- aropon = doctype = 'C'
+-- gltrans : AR (ADD) / Customer Credit (DEDUCT)
+
+-- >> DM - set Prepaid account to Customer Credits...
+-- aropen = doctype = 'D'
+-- gltrans : AR( MINUS) / Customer Credit (ADD)
+
+-- fundstype ==> 'emty'
+-- refnumber ==> empty
+-- journalnumber=> 0
+
+-- reftype => blank
+-- ref_id => null
+
+
+
+
+
+CREATE OR REPLACE FUNCTION voidapcreditmemoapplication(integer)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+    i_id ALIAS FOR $1;
+    
+    r_apply RECORD;
+    
+    v_source_curr_id  INTEGER;
+    v_target_curr_id  INTEGER;
+    
+  
+    v_debit_id  INTEGER;
+    v_credit_id INTEGER;
+    v_credit_jid INTEGER;
+    v_id INTEGER;
+
+    is_rcpt_void BOOLEAN;
+    
+BEGIN
+  
+    -- the record we are voiding..
+       
+    SELECT
+          *
+        INTO
+            r_apply
+        FROM
+            apapply
+        WHERE
+            apapply_id = i_id;
+            
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'voidapcreditmemoapplication: apapply % not found', i_id;
+    END IF;
+    
+    -- see if we have already done this..
+    
+    
+    SELECT
+            apopen_id
+        INTO
+            v_id
+        FROM
+            apopen
+        WHERE
+            apopen_docnumber = 'AP-APPLICATION-VOID-DEBIT-' || i_id
+        LIMIT 1;
+    
+    IF FOUND THEN
+        RAISE EXCEPTION 'this application has already been voided';
+    END IF;
+        
+    
+    
+    -- fetch the currencies from the affected records..
+    is_rcpt_void := false;
+    
+    IF r_apply.apapply_source_doctype = 'K' THEN
+    
+        -- still need to fix unposted applications ??? -
+        -- in voidinvoice?
+        
+        -- verify that cshrcpt is void.
+        
+        -- RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+            
+        -- if source is a 
+        
+        -- if it's a cash reciept void then we have to -ve the number being applied...
+        
+        -- cary on and create a pair of Cm/DM
+        
+        SELECT 
+                cashrcpt_curr_id,
+                cashrcpt_void
+            INTO
+                v_source_curr_id,
+                is_rcpt_void
+            FROM
+                cashrcpt
+            WHERE
+                cashrcpt_number = r_apply.apapply_source_docnumber;
+        
+        
+        IF (NOT is_rcpt_void) THEN
+            RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+        END IF;
+        
+    ELSE
+        IF r_apply.apapply_source_apopen_id < 0 THEN
+            RAISE EXCEPTION 'source_apopen_id < 0 - can not handle this.';
+        END IF;
+    
+        SELECT
+                apopen_curr_id
+            INTO
+                v_source_curr_id
+            FROM
+                apopen
+            WHERE
+                apopen_id = r_apply.apapply_source_apopen_id;
+      
+    
+    END IF;
+    
+    IF r_apply.apapply_target_doctype = 'R' THEN
+    
+        -- there is a GL transaction for 'R' in applyarapplication....
+        -- so we need to add that in later...
+        RAISE EXCEPTION 'Target doctype = R not supported yet';
+    END IF;
+    
+    IF r_apply.apapply_target_doctype = 'K' THEN
+             RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+            SELECT
+                cashrcpt_curr_id
+            INTO
+                v_target_curr_id
+            FROM
+                cashrcpt
+            WHERE
+                cashrcpt_number = r_apply.apapply_target_docnumber;
+                
+    ELSE
+        IF r_apply.apapply_target_apopen_id < 0 THEN
+            RAISE EXCEPTION 'source_apopen_id < 0 - can not handle this.';
+        END IF;
+    
+    
+        SELECT
+              apopen_curr_id
+            INTO
+                v_target_curr_id
+            FROM
+                apopen
+            WHERE
+                apopen_id = r_apply.apapply_target_apopen_id;
+    
+    END IF;
+    
+    
+   
+    --IF v_target_curr_id !=  v_source_curr_id THEN
+    --    RAISE EXCEPTION 'voiding a multi currency application does not work yet...';
+    --END IF;
+
+    
+    -- now create a debit and credit to move the application to.. (equivlant to the payment..) = source...
+    
+    
+    SELECT createapCreditMemo (
+        NULL,
+        r_apply.apapply_vend_id,
+        NULL, -- journaln o.
+       'AP-APPLICATION-VOID-CREDIT-' || i_id,
+         '', -- po nm
+        r_apply.apapply_postdate,
+        ABS(r_apply.apapply_target_paid),
+        'AP Application Voided (Credit) - ' || r_apply.apapply_source_docnumber || ' - ' || r_apply.apapply_target_docnumber,  
+        -1, -- account
+        r_apply.apapply_postdate,
+        (SELECT vend_terms_id FROM vendinfo where vend_id = r_apply.apapply_vend_id),
+         r_apply.apapply_curr_id
+    ) INTO  v_credit_jid;
+    
+    IF (v_credit_jid < 1) THEN
+        RAISE EXCEPTION 'createapdebitmemo FAILED';
+    END IF;
+    
+    SELECT apopen_id INTO v_credit_id FROM apopen where apopen_journalnumber  = v_credit_jid;
+    
+    IF NOT FOUND OR (v_credit_id < 1) THEN
+        RAISE EXCEPTION 'createapdebitmemo FAILED';
+    END IF;
+    
+    
+    SELECT createapdebitmemo(
+        NULL,
+        r_apply.apapply_vend_id,
+        NULL,
+        'AP-APPLICATION-VOID-DEBIT-' || i_id,
+        '',
+        r_apply.apapply_postdate,
+        ABS(r_apply.apapply_target_paid),
+        'AP Application Voided (Debit) - ' || r_apply.apapply_source_docnumber || ' - ' || r_apply.apapply_target_docnumber,  
+        (SELECT apopen_accnt_id FROM apopen where apopen_id = v_credit_id),
+        r_apply.apapply_postdate,
+         (SELECT vend_terms_id FROM vendinfo where vend_id = r_apply.apapply_vend_id),
+        r_apply.apapply_curr_id
+    ) INTO v_debit_id;
+    IF (v_debit_id < 1) THEN
+        RAISE EXCEPTION 'createapdebitmemo FAILED';
+    END IF;
+    
+    
+    
+    
+    UPDATE apapply SET
+       apapply_source_apopen_id = v_credit_id,
+       apapply_source_doctype = 'C',
+       apapply_source_docnumber = 'AP-APPLICATION-VOID-CREDIT-' || i_id,
+       
+       apapply_target_apopen_id = v_debit_id, 
+       apapply_target_doctype = 'D',
+       apapply_target_docnumber =  'AP-APPLICATION-VOID-DEBIT-' || i_id,
+       
+       apapply_journalnumber = 0 ,
+       -- fix the applied amounts..
+        apapply_target_paid = ABS(r_apply.apapply_target_paid),
+        apapply_amount = ABS(r_apply.apapply_amount)
+    WHERE
+       apapply_id     =  i_id;
+    -- not sure if record will be updated by the above...
+    -- hope not.. it would be a bit wierd...
+    -- remove the payments from the aropen account - note that cashrecipts will
+    -- not have a aropen_id (it's '-1' ) so they will get ignored.
+    
+    UPDATE
+        apopen
+    SET
+        apopen_paid = apopen_paid - currtocurr(r_apply.apapply_curr_id, apopen_curr_id, ABS(r_apply.apapply_target_paid) , r_apply.apapply_postdate),
+        apopen_open = true,
+        apopen_closedate = NULL
+    WHERE
+        apopen_id IN (r_apply.apapply_target_apopen_id  ,  r_apply.apapply_source_apopen_id) ;
+    
+    -- FOR OUR NEW ONES...
+    UPDATE
+        apopen
+    SET
+        apopen_paid = apopen_amount,
+        apopen_open = false,
+        apopen_closedate = r_apply.apapply_postdate
+    WHERE
+        apopen_id IN (v_credit_id, v_debit_id) ;
+    
+    
+    -- if it's a cash reciept, then we need to change the cashrcptitem
+    IF (is_rcpt_void) THEN
+    
+        --RAISE EXCEPTION 'attempt to set cashrcpt aropen_id to % WHERE cashrcptitem_cashrcpt_id  IN (cashrcptitem_aropen_id = %',
+        --   v_debit_id,r_apply.apapply_target_aropen_id;
+            
+        ALTER TABLE cashrcptitem DISABLE TRIGGER USER;
+        UPDATE
+                cashrcptitem
+            SET
+                cashrcptitem_apopen_id = v_debit_id
+        WHERE
+           
+                cashrcptitem_apopen_id = r_apply.apapply_target_aropen_id;
+            
+        
+        ALTER TABLE cashrcptitem ENABLE TRIGGER USER;
+    
+    END IF;
+    
+    
+    RETURN i_id;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION voidapcreditmemoapplication(integer)
+  OWNER TO admin;
+  
+  
+  
+--select voidapcreditmemoapplication(7475);
+--select voidapcreditmemoapplication(7477);
diff --git a/pgsql/voidapopenvoucher.sql b/pgsql/voidapopenvoucher.sql
new file mode 100644 (file)
index 0000000..117ca26
--- /dev/null
@@ -0,0 +1,354 @@
+-- based on the latest code in subversion.
+-- changes?
+
+
+CREATE OR REPLACE FUNCTION voidApopenVoucher(INTEGER) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pApopenid ALIAS FOR $1;
+BEGIN
+  RETURN voidApopenVoucher(pApopenid, fetchJournalNumber('AP-VO'));
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION voidApopenVoucher(INTEGER, INTEGER) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pApopenid ALIAS FOR $1;
+  pJournalNumber ALIAS FOR $2;
+  _apopenid INTEGER;
+  _apcreditapplyid INTEGER;
+  _reference    TEXT;
+  _result INTEGER;
+  _sequence INTEGER;
+  _totalAmount_base NUMERIC;
+  _totalAmount NUMERIC;
+  _itemAmount_base NUMERIC;
+  _itemAmount NUMERIC;
+  _test INTEGER;
+  _a RECORD;
+  _d RECORD;
+  _g RECORD;
+  _p RECORD;
+  _n RECORD;
+  _r RECORD;
+  _costx RECORD;
+  _pExplain BOOLEAN;
+  _pLowLevel BOOLEAN;
+  _exchGainFreight NUMERIC;
+  _firstExchDateFreight        DATE;
+  _tmpTotal            NUMERIC;
+  _glDate              DATE;
+
+BEGIN
+
+  _totalAmount_base := 0;
+  _totalAmount := 0;
+  SELECT fetchGLSequence() INTO _sequence;
+
+--  Cache APOpen Information
+  SELECT apopen.* INTO _n
+  FROM apopen
+  WHERE ( (apopen_doctype='V')
+    AND   (apopen_id=pApopenid) );
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Void Voucher #% as apopen not found', pApopenid;
+  END IF;
+
+--  Cache Voucher Infomation
+  SELECT vohead.*,
+        vend_number || '-' || vend_name || ' ' || vohead_reference
+                                                         AS glnotes,
+        COALESCE(pohead_orderdate, vohead_docdate) AS pohead_orderdate,
+        COALESCE(pohead_curr_id, vohead_curr_id) AS pohead_curr_id INTO _p
+  FROM vohead JOIN vendinfo ON (vend_id=vohead_vend_id)
+              LEFT OUTER JOIN pohead ON (vohead_pohead_id = pohead_id)
+  WHERE (vohead_number=_n.apopen_docnumber);
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Void Voucher #% as vohead not found', _n.apopen_docnumber;
+  END IF;
+
+  _glDate := COALESCE(_p.vohead_gldistdate, _p.vohead_distdate);
+
+-- there is no currency gain/loss on items, see issue 3892,
+-- but there might be on freight, which is first encountered at p/o receipt
+  SELECT recv_date::DATE INTO _firstExchDateFreight
+  FROM recv
+  WHERE (recv_vohead_id = _p.vohead_id);
+
+--  Start by handling taxes
+  FOR _r IN SELECT tax_sales_accnt_id, 
+              round(sum(taxdetail_tax),2) AS tax,
+              currToBase(_p.vohead_curr_id, round(sum(taxdetail_tax),2), _p.vohead_docdate) AS taxbasevalue
+            FROM tax 
+             JOIN calculateTaxDetailSummary('VO', _p.vohead_id, 'T') ON (taxdetail_tax_id=tax_id)
+           GROUP BY tax_id, tax_sales_accnt_id LOOP
+
+    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', _p.vohead_number,
+                                _r.tax_sales_accnt_id, 
+                                (_r.taxbasevalue * -1),
+                                _glDate, _p.glnotes );
+
+    _totalAmount_base := (_totalAmount_base - _r.taxbasevalue);
+    _totalAmount := (_totalAmount - _r.tax);
+     
+  END LOOP;
+
+--  Loop through the vodist records for the passed vohead that
+--  are posted against a P/O Item
+  FOR _g IN SELECT DISTINCT poitem_id, voitem_qty, poitem_expcat_id,
+                            poitem_invvenduomratio,
+                            COALESCE(itemsite_id, -1) AS itemsiteid,
+                            COALESCE(itemsite_costcat_id, -1) AS costcatid,
+                            COALESCE(itemsite_item_id, -1) AS itemsite_item_id,
+                            (SELECT SUM(value) 
+                             FROM (
+                                SELECT SUM(recv_value) AS value
+                                FROM recv
+                                WHERE (recv_voitem_id=voitem_id)
+                             UNION
+                                SELECT SUM(poreject_value)*-1 AS value
+                                FROM poreject
+                                WHERE (poreject_voitem_id=voitem_id)) as data)
+                            AS value_base,
+                            (poitem_freight_vouchered / poitem_qty_vouchered) * voitem_qty AS vouchered_freight,
+                            currToBase(_p.pohead_curr_id, (poitem_freight_vouchered / poitem_qty_vouchered) * voitem_qty, _firstExchDateFreight ) AS vouchered_freight_base,
+                           voitem_freight,
+                           currToBase(_p.vohead_curr_id, voitem_freight,
+                                       _p.vohead_distdate) AS voitem_freight_base
+            FROM vodist, voitem,
+                 poitem LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
+            WHERE ( (vodist_poitem_id=poitem_id)
+             AND (voitem_poitem_id=poitem_id)
+             AND (voitem_vohead_id=vodist_vohead_id)
+             AND (vodist_vohead_id=_p.vohead_id)) LOOP
+
+--  Grab the G/L Accounts
+    IF (_g.costcatid = -1) THEN
+      SELECT pp.accnt_id AS pp_accnt_id,
+             lb.accnt_id AS lb_accnt_id INTO _a
+      FROM expcat, accnt AS pp, accnt AS lb
+      WHERE ( (expcat_purchprice_accnt_id=pp.accnt_id)
+       AND (expcat_liability_accnt_id=lb.accnt_id)
+       AND (expcat_id=_g.poitem_expcat_id) );
+      IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Cannot Void Voucher #% due to unassigned G/L Accounts.', _p.vohead_number;
+      END IF;
+    ELSE
+      SELECT pp.accnt_id AS pp_accnt_id,
+             lb.accnt_id AS lb_accnt_id INTO _a
+      FROM costcat, accnt AS pp, accnt AS lb
+      WHERE ( (costcat_purchprice_accnt_id=pp.accnt_id)
+       AND (costcat_liability_accnt_id=lb.accnt_id)
+       AND (costcat_id=_g.costcatid) );
+      IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Cannot Void Voucher #% due to unassigned G/L Accounts.', _p.vohead_number;
+      END IF;
+    END IF;
+
+--  Clear the Item Amount accumulator
+    _itemAmount_base := 0;
+    _itemAmount := 0;
+
+--  Figure out the total posted value for this line item
+    FOR _d IN SELECT vodist_id, vodist_amount,
+                    _p.vohead_curr_id, vodist_costelem_id,
+                    currToBase(_p.vohead_curr_id, vodist_amount,
+                               _p.vohead_distdate) AS vodist_amount_base
+              FROM vodist
+              WHERE ( (vodist_vohead_id=_p.vohead_id)
+               AND (vodist_poitem_id=_g.poitem_id) ) LOOP
+
+       _pExplain := TRUE;
+       SELECT * INTO _costx
+         FROM itemcost
+        WHERE ( (itemcost_item_id = _g.itemsite_item_id)
+          AND   (itemcost_costelem_id = _d.vodist_costelem_id) );
+
+       IF (FOUND) THEN
+         _pExplain := _costx.itemcost_lowlevel;
+       END IF;
+
+--  Add the Distribution Amount to the Item Amount
+      _itemAmount_base := _itemAmount_base + ROUND(_d.vodist_amount_base, 2);
+      _itemAmount := _itemAmount + _d.vodist_amount;
+
+    END LOOP;
+
+--  Distribute from the clearing account
+    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
+                                _a.lb_accnt_id,
+                                round(_g.value_base + _g.vouchered_freight_base, 2),
+                                _glDate, _p.glnotes );
+
+--  Attribute the correct portion to currency gain/loss
+    _exchGainFreight := 0;
+    SELECT currGain(_p.pohead_curr_id, _g.vouchered_freight,
+                   _firstExchDateFreight, _p.vohead_distdate )
+                   INTO _exchGainFreight;
+    IF (round(_exchGainFreight, 2) <> 0) THEN
+      PERFORM insertIntoGLSeries(_sequence, 'A/P', 'VO',
+                                 text(_p.vohead_number),
+                                 getGainLossAccntId(_a.lb_accnt_id), round(_exchGainFreight, 2) * -1,
+                                 _glDate, _p.glnotes);
+    END IF;
+
+--  Distribute the remaining variance to the Purchase Price Variance account
+    IF (round(_itemAmount_base, 2) <> round(_g.value_base, 2)) THEN
+      _tmpTotal := round(_itemAmount_base, 2) - round(_g.value_base, 2);
+      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
+                                  _a.pp_accnt_id,
+                                  _tmpTotal,
+                                  _glDate, _p.glnotes );
+    END IF;
+
+--  Distribute the remaining freight variance to the Purchase Price Variance account
+    IF (round(_g.voitem_freight_base + _exchGainFreight, 2) <> round(_g.vouchered_freight_base, 2)) THEN
+      _tmpTotal := round(_g.voitem_freight_base + _exchGainFreight, 2) - round(_g.vouchered_freight_base, 2);
+      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
+                                  _a.pp_accnt_id,
+                                  _tmpTotal,
+                                  _glDate, _p.glnotes );
+    END IF;
+
+--  Add the distribution amount to the total amount to distribute
+    _totalAmount_base := (_totalAmount_base + _itemAmount_base + _g.voitem_freight_base);
+    _totalAmount := (_totalAmount + _itemAmount + _g.voitem_freight);
+
+--  Reverse the posting for all the Tagged Receivings for this P/O Item
+    UPDATE recv
+    SET recv_invoiced=FALSE,
+        recv_recvcost_curr_id=basecurrid(),
+        recv_recvcost=0,
+        recv_vohead_id=NULL,
+        recv_voitem_id=NULL
+    FROM poitem
+    WHERE ( (recv_orderitem_id=poitem_id)
+      AND   (recv_order_type='PO')
+      AND   (recv_orderitem_id=_g.poitem_id)
+      AND   (recv_vohead_id=_p.vohead_id) );
+
+--  Reverse the posting for all the Tagged Rejections for this P/O Item
+    UPDATE poreject
+    SET poreject_invoiced=FALSE,
+        poreject_vohead_id=NULL,
+        poreject_voitem_id=NULL
+    WHERE ( (poreject_poitem_id=_g.poitem_id)
+      AND   (poreject_vohead_id=_p.vohead_id) );
+
+--  Update the qty and freight vouchered fields
+    UPDATE poitem
+       SET poitem_qty_vouchered = (poitem_qty_vouchered - _g.voitem_qty),
+           poitem_freight_vouchered = (poitem_freight_vouchered - _g.voitem_freight)
+    WHERE (poitem_id=_g.poitem_id);
+
+  END LOOP;
+
+--  Loop through the vodist records for the passed vohead that
+--  are not posted against a P/O Item
+--  Skip the tax distributions
+  FOR _d IN SELECT vodist_id,
+                  currToBase(_p.vohead_curr_id, vodist_amount,
+                             _p.vohead_distdate) AS vodist_amount_base,
+                  vodist_amount,
+                  vodist_accnt_id, vodist_expcat_id
+            FROM vodist
+            WHERE ( (vodist_vohead_id=_p.vohead_id)
+              AND   (vodist_poitem_id=-1)
+              AND   (vodist_tax_id=-1) ) LOOP
+
+--  Distribute from the misc. account
+    IF (_d.vodist_accnt_id = -1) THEN
+      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
+                                  expcat_exp_accnt_id,
+                                  round(_d.vodist_amount_base, 2),
+                                  _glDate, _p.glnotes )
+      FROM expcat
+      WHERE (expcat_id=_d.vodist_expcat_id);
+    ELSE
+      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
+                                  _d.vodist_accnt_id,
+                                  round(_d.vodist_amount_base, 2),
+                                  _glDate, _p.glnotes );
+    END IF;
+
+--  Add the Distribution Amount to the Total Amount
+    _totalAmount_base := _totalAmount_base + ROUND(_d.vodist_amount_base, 2);
+    _totalAmount := _totalAmount + _d.vodist_amount;
+
+  END LOOP;
+
+  SELECT insertIntoGLSeries( _sequence, 'A/P', 'VO', text(vohead_number),
+                             accnt_id, round(_totalAmount_base, 2) * -1,
+                             _glDate, _p.glnotes ) INTO _test
+  FROM vohead LEFT OUTER JOIN accnt ON (accnt_id=findAPAccount(vohead_vend_id))
+  WHERE ( (findAPAccount(vohead_vend_id)=0 OR accnt_id > 0) -- G/L interface might be disabled
+    AND   (vohead_id=_p.vohead_id) );
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Void Voucher #% due to an unassigned A/P Account.', _p.vohead_number;
+  END IF;
+
+  PERFORM postGLSeries(_sequence, pJournalNumber);
+
+--  Create the A/P Open Item
+  SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
+  _reference := ('Void Voucher #' || _n.apopen_docnumber);
+  INSERT INTO apopen
+  ( apopen_id, apopen_username, apopen_journalnumber,
+    apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
+    apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id, apopen_curr_id,
+    apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_discount, apopen_curr_rate )
+  SELECT _apopenid, getEffectiveXtUser(), pJournalnumber,
+         apopen_vend_id, apopen_docnumber, 'C', apopen_ponumber,
+         CURRENT_DATE, CURRENT_DATE, CURRENT_DATE, -1, apopen_curr_id,
+         apopen_amount - apopen_paid, 0, TRUE, _reference, TRUE, apopen_curr_rate
+    FROM apopen
+   WHERE (apopen_id=_n.apopen_id);
+
+  SELECT apcreditapply_id INTO _apcreditapplyid
+    FROM apcreditapply
+   WHERE ( (apcreditapply_source_apopen_id=_apopenid)
+     AND   (apcreditapply_target_apopen_id=_n.apopen_id) );
+  IF (FOUND) THEN
+    UPDATE apcreditapply
+       SET apcreditapply_amount=_n.apopen_amount-_n.apopen_paid
+     WHERE (apcreditapply_id=_apcreditapplyid);
+  ELSE
+    SELECT nextval('apcreditapply_apcreditapply_id_seq') INTO _apcreditapplyid;
+    INSERT INTO apcreditapply
+           ( apcreditapply_id, apcreditapply_source_apopen_id,
+             apcreditapply_target_apopen_id, apcreditapply_amount,
+             apcreditapply_curr_id )
+    VALUES ( _apcreditapplyid, _apopenid, _n.apopen_id, _n.apopen_amount-_n.apopen_paid, _n.apopen_curr_id );
+  END IF;
+
+  SELECT postAPCreditMemoApplication(_apopenid) INTO _result;
+
+  IF (_result < 0) THEN
+    RAISE EXCEPTION 'Credit application failed with result %.', _result;
+  END IF;
+
+--  Reopen all of the P/O Items that were closed by this Voucher
+  UPDATE poitem
+  SET poitem_status='O'
+  FROM voitem
+  WHERE ( (voitem_poitem_id=poitem_id)
+    AND   (voitem_close)
+    AND   (voitem_vohead_id=_p.vohead_id) );
+
+--  Reopen the P/O
+  UPDATE pohead
+  SET pohead_status='O'
+  WHERE (pohead_id=_p.vohead_pohead_id);
+
+--  Mark as voided
+  UPDATE apopen
+  SET apopen_void=TRUE
+  WHERE (apopen_id=_n.apopen_id);
+
+  RETURN pJournalNumber;
+
+END;
+$$ LANGUAGE 'plpgsql';
\ No newline at end of file
diff --git a/pgsql/voidarcreditmemoapplication.sql b/pgsql/voidarcreditmemoapplication.sql
new file mode 100644 (file)
index 0000000..45f7b79
--- /dev/null
@@ -0,0 +1,386 @@
+-- effort to void ar cm apply , so that invoice void works.. 
+-- it basically creates a DM/CM pair and moves the application to that..
+  
+-- verify that curr_id on both source and target are the esame, if they are not, then we can not do this..
+
+
+
+-- NEED TO VERIFY THIS WILL WORK
+
+-- process : create invoice , create check payment and credit it- look at all gltrans that have been made..
+
+
+-- before start last gltrans_id = 656889
+
+-- GLTRANS:
+-- Invoice  SALES (ADD) / AR (DEDUCT)
+-- Check  AR (ADD) / Bank (DEDUCT)
+
+
+-- AROPEN:
+-- Only one item created.. - paid is filled in... (I)
+
+-- ARAPPLY (id = 7475)
+-- Funds type 'C'  sourcedoc = 'K' targetdoc = 'I'
+--?? JOURNAL ENTRY?? - which one..
+
+-- now try our CM/DM process.
+-- Credit MEMO
+-- aropon = doctype = 'C'
+-- gltrans : AR (ADD) / Customer Credit (DEDUCT)
+
+-- >> DM - set Prepaid account to Customer Credits...
+-- aropen = doctype = 'D'
+-- gltrans : AR( MINUS) / Customer Credit (ADD)
+
+-- fundstype ==> 'emty'
+-- refnumber ==> empty
+-- journalnumber=> 0
+
+-- reftype => blank
+-- ref_id => null
+
+
+
+
+
+CREATE OR REPLACE FUNCTION voidarcreditmemoapplication(integer)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+    i_id ALIAS FOR $1;
+    
+    r_apply RECORD;
+    
+    v_source_curr_id  INTEGER;
+    v_target_curr_id  INTEGER;
+    
+  
+    v_debit_id  INTEGER;
+    v_credit_id INTEGER;
+    
+    v_id INTEGER;
+    v_num_gl INTEGER;
+
+    is_rcpt_void BOOLEAN;
+    
+BEGIN
+  
+    -- the record we are voiding..
+       
+    SELECT
+          *
+        INTO
+            r_apply
+        FROM
+            arapply
+        WHERE
+            arapply_id = i_id;
+            
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'voidarcreditmemoapplication: arapply % not found', i_id;
+    END IF;
+    
+    -- see if we have already done this..
+    
+    
+    SELECT
+            aropen_id
+        INTO
+            v_id
+        FROM
+            aropen
+        WHERE
+            aropen_docnumber = 'AR-APPLICATION-VOID-DEBIT-' || i_id
+        LIMIT 1;
+    
+    IF FOUND THEN
+        RAISE EXCEPTION 'this application has already been voided';
+    END IF;
+        
+    
+    
+    -- fetch the currencies from the affected records..
+    is_rcpt_void := false;
+    
+    IF r_apply.arapply_source_doctype = 'K' THEN
+    
+        -- still need to fix unposted applications ??? -
+        -- in voidinvoice?
+        
+        -- verify that cshrcpt is void.
+        
+        -- RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+            
+        -- if source is a 
+        
+        -- if it's a cash reciept void then we have to -ve the number being applied...
+        
+        -- cary on and create a pair of Cm/DM
+        
+        SELECT 
+                cashrcpt_curr_id,
+                cashrcpt_void
+            INTO
+                v_source_curr_id,
+                is_rcpt_void
+            FROM
+                cashrcpt
+            WHERE
+                cashrcpt_number = r_apply.arapply_source_docnumber;
+        
+        
+        IF (NOT is_rcpt_void) THEN
+            RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+        END IF;
+        
+    ELSE
+        IF r_apply.arapply_source_aropen_id < 0 THEN
+            RAISE EXCEPTION 'source_aropen_id < 0 - can not handle this.';
+        END IF;
+    
+        SELECT
+                aropen_curr_id
+            INTO
+                v_source_curr_id
+            FROM
+                aropen
+            WHERE
+                aropen_id = r_apply.arapply_source_aropen_id;
+      
+    
+    END IF;
+    
+    IF r_apply.arapply_target_doctype = 'R' THEN
+    
+        -- there is a GL transaction for 'R' in applyarapplication....
+        -- so we need to add that in later...
+        RAISE EXCEPTION 'Target doctype = R not supported yet';
+    END IF;
+    
+    IF r_apply.arapply_target_doctype = 'K' THEN
+             RAISE EXCEPTION ' a payment has been made on this invoice - void the payment first.';
+            SELECT
+                cashrcpt_curr_id
+            INTO
+                v_target_curr_id
+            FROM
+                cashrcpt
+            WHERE
+                cashrcpt_number = r_apply.arapply_target_docnumber;
+                
+    ELSE
+        IF r_apply.arapply_target_aropen_id < 0 THEN
+            RAISE EXCEPTION 'source_aropen_id < 0 - can not handle this.';
+        END IF;
+    
+    
+        SELECT
+              aropen_curr_id
+            INTO
+                v_target_curr_id
+            FROM
+                aropen
+            WHERE
+                aropen_id = r_apply.arapply_target_aropen_id;
+    
+    END IF;
+    
+    
+   
+    IF v_target_curr_id !=  v_source_curr_id THEN
+        -- need to see if there was a glentry for this..
+        
+        -- post application creates 1 possible GL Transactions
+        -- A/P  CM   src_docnumber, 'CM Application'
+        
+        -- b) -- if <payment_type>=='R' then  gl from custdeposit to ar account.
+        -- date matches?
+        
+        SELECT
+                COALESCE(count( distinct gltrans_sequence),0)
+            INTO
+                v_num_gl
+            FROM
+                gltrans
+            WHERE
+                    gltrans_notes = 'CM Application'
+                AND
+                    gltrans_source = 'A/R'
+                AND
+                    gltrans_doctype = 'CD'
+                AND
+                    gltrans_docnumber = r_apply.arapply_source_doctype 
+                AND
+                    gltrans_date = r_apply.arapply_postdate
+            LIMIT 1;
+                 
+                 
+        IF v_num_gl > 1 THEN
+            
+            RAISE EXCEPTION 'voiding a application with different currencies does not work when there are multiple applications of it in the same day or a curr adjustment was posted. ';
+        END IF;
+        
+        IF v_num_gl > 0 THEN
+        
+            SELECT
+                    distinct gltrans_sequence
+                INTO
+                    v_num_gl
+                FROM
+                    gltrans
+                WHERE
+                        gltrans_notes = 'CM Application'
+                    AND
+                        gltrans_source = 'A/R'
+                    AND
+                        gltrans_doctype = 'CD'
+                    AND
+                        gltrans_docnumber = r_apply.arapply_source_doctype 
+                    AND
+                        gltrans_date = r_apply.arapply_postdate
+                LIMIT 1;
+            
+            SELECT deleteglseries(v_num_gl, 'CREDIT MEMO APPLICATION VOIDED');
+        END IF;
+                     
+        
+        
+    END IF;
+
+    
+    -- now create a debit and credit to move the application to..
+    
+    
+    SELECT createARCreditMemo (
+        NULL,
+        r_apply.arapply_cust_id,
+       'AR-APPLICATION-VOID-CREDIT-' || i_id,
+         '',
+        r_apply.arapply_distdate,
+        ABS(r_apply.arapply_target_paid),
+        'AR Application Voided (Credit) -' || r_apply.arapply_refnumber,  
+        -1,
+        -1,
+        -1, 
+        r_apply.arapply_distdate,
+        (SELECT cust_terms_id FROM custinfo where cust_id = r_apply.arapply_cust_id),
+         (SELECT cust_salesrep_id FROM custinfo where cust_id = r_apply.arapply_cust_id),
+        0,
+         r_apply.arapply_curr_id
+    ) INTO  v_credit_id;
+    
+    IF (v_credit_id < 1) THEN
+        RAISE EXCEPTION 'createardebitmemo FAILED';
+    END IF;
+    
+    
+    
+    SELECT createardebitmemo(
+        NULL,
+        r_apply.arapply_cust_id,
+        NULL,
+        'AR-APPLICATION-VOID-DEBIT-' || i_id,
+        '',
+        r_apply.arapply_distdate,
+        ABS(r_apply.arapply_target_paid),
+        'AR Application Voided (Debit) - ' || r_apply.arapply_refnumber,  
+       
+        -1,
+        -1,
+         (SELECT aropen_accnt_id FROM aropen where aropen_id = v_credit_id),
+        r_apply.arapply_distdate,
+        (SELECT cust_terms_id FROM custinfo where cust_id = r_apply.arapply_cust_id),
+        (SELECT cust_salesrep_id FROM custinfo where cust_id = r_apply.arapply_cust_id),
+        0,
+        r_apply.arapply_curr_id
+    ) INTO v_debit_id;
+    IF (v_debit_id < 1) THEN
+        RAISE EXCEPTION 'createardebitmemo FAILED';
+    END IF;
+    
+    
+    
+    
+    UPDATE arapply SET
+       arapply_source_aropen_id = v_credit_id,
+       arapply_source_doctype = 'C',
+       arapply_source_docnumber = 'AR-APPLICATION-VOID-CREDIT-' || i_id,
+       
+       arapply_target_aropen_id = v_debit_id, 
+       arapply_target_doctype = 'D',
+       arapply_target_docnumber =  'AR-APPLICATION-VOID-DEBIT-' || i_id,
+       arapply_fundstype = NULL,
+       arapply_refnumber = NULL,
+       arapply_journalnumber = 0 ,
+       -- fix the applied amounts..
+        arapply_target_paid = ABS(r_apply.arapply_target_paid),
+        arapply_applied = ABS(r_apply.arapply_applied)
+    WHERE
+       arapply_id     =  i_id;
+    -- not sure if record will be updated by the above...
+    -- hope not.. it would be a bit wierd...
+    -- remove the payments from the apopen account - note that cashrecipts will
+    -- not have a aropen_id (it's '-1' ) so they will get ignored.
+    
+    UPDATE
+        aropen
+    SET
+        aropen_paid = aropen_paid - ABS(r_apply.arapply_target_paid),
+        aropen_open = true,
+        aropen_closedate = NULL
+    WHERE
+        aropen_id IN (r_apply.arapply_target_aropen_id  ,  r_apply.arapply_source_aropen_id) ;
+    
+    -- FOR OUR NEW ONES...
+    UPDATE
+        aropen
+    SET
+        aropen_paid = aropen_amount,
+        aropen_open = false,
+        aropen_closedate = r_apply.arapply_distdate
+    WHERE
+        aropen_id IN (v_credit_id, v_debit_id) ;
+    
+    
+    -- if it's a cash reciept, then we need to change the cashrcptitem
+    IF (is_rcpt_void) THEN
+    
+        --RAISE EXCEPTION 'attempt to set cashrcpt aropen_id to % WHERE cashrcptitem_cashrcpt_id  IN (cashrcptitem_aropen_id = %',
+        --   v_debit_id,r_apply.arapply_target_aropen_id;
+            
+        ALTER TABLE cashrcptitem DISABLE TRIGGER USER;
+        UPDATE
+                cashrcptitem
+            SET
+                cashrcptitem_aropen_id = v_debit_id
+        WHERE
+           
+                cashrcptitem_aropen_id = r_apply.arapply_target_aropen_id;
+            
+        
+        ALTER TABLE cashrcptitem ENABLE TRIGGER USER;
+    
+    END IF;
+    
+    
+    RETURN i_id;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION voidarcreditmemoapplication(integer)
+  OWNER TO admin;
+  
+  
+  
+--select voidarcreditmemoapplication(7475);
+--select voidarcreditmemoapplication(7477);
diff --git a/pgsql/voidbankreconciliation.sql b/pgsql/voidbankreconciliation.sql
new file mode 100644 (file)
index 0000000..0394189
--- /dev/null
@@ -0,0 +1,69 @@
+
+CREATE OR REPLACE FUNCTION voidbankreconciliation(i_bankrec_id INTEGER)
+    RETURNS INTEGER
+AS $BODY$
+DECLARE    
+    v_bankrec_posted BOOLEAN;
+    v_bankaccnt_id INTEGER;
+BEGIN
+   
+    SELECT 
+            bankrec_posted,
+            bankrec_bankaccnt_id
+            
+    INTO
+            v_bankrec_posted,
+            v_bankaccnt_id
+    FROM
+            bankrec
+    WHERE
+            bankrec_id = i_bankrec_id;
+
+    -- first of all, check if the bankrec exist...
+    IF (NOT FOUND) THEN
+        RETURN -1;
+    END IF;
+
+    -- check if the bankrec is posted 
+    IF (NOT v_bankrec_posted) THEN
+        RETURN -2;
+    END IF;
+
+    UPDATE
+            bankrec
+    SET
+            bankrec_posted = FALSE,
+            bankrec_postdate = NULL
+    WHERE
+            bankrec_id = i_bankrec_id;
+
+    UPDATE
+            gltrans
+    SET
+            gltrans_rec = FALSE
+
+    WHERE
+            gltrans_id IN (
+                            SELECT 
+                                    bankrecitem_source_id
+                            FROM
+                                    bankrecitem
+                            WHERE
+                                    bankrecitem_source = 'GL'
+                                AND
+                                    bankrecitem_cleared
+                                AND
+                                    bankrecitem_bankrec_id = i_bankrec_id
+                           );
+            
+    
+    RETURN i_bankrec_id;
+
+
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  voidbankreconciliation(INTEGER)
+  OWNER TO admin;
diff --git a/pgsql/voidinvoice.sql b/pgsql/voidinvoice.sql
new file mode 100644 (file)
index 0000000..9c44a28
--- /dev/null
@@ -0,0 +1,465 @@
+
+-- this is a slightly modified version which tries to retain the
+-- invoice number (that was removed)
+
+-- renames the voided invoice XXXXX-VOID  - as DM/CM may have the same number..
+
+
+alter table invchead add column invchead_void boolean default false;
+
+
+CREATE OR REPLACE FUNCTION voidInvoice(INTEGER) RETURNS INTEGER AS $$
+DECLARE
+  pInvcheadid ALIAS FOR $1;
+  _glSequence INTEGER := 0;
+  _glJournal INTEGER := 0;
+  _itemlocSeries INTEGER := 0;
+   _aropenid INTEGER := 0;
+  _invhistid INTEGER := 0;
+  _amount NUMERIC;
+  _roundedBase NUMERIC;
+  _r RECORD;
+  _p RECORD;
+  _n RECORD;
+  _test INTEGER;
+  _totalAmount          NUMERIC := 0;
+  _totalRoundedBase     NUMERIC := 0;
+  _totalAmountBase      NUMERIC := 0;
+  _appliedAmount        NUMERIC := 0;
+  _commissionDue        NUMERIC := 0;
+  _tmpAccntId INTEGER;
+  _tmpCurrId  INTEGER;
+  _firstExchDate        DATE;
+  _glDate              DATE;
+  _exchGain             NUMERIC := 0;
+   
+
+BEGIN
+
+--  Cache Invoice information
+  SELECT invchead.*,
+         findFreightAccount(invchead_cust_id) AS freightaccntid,
+         findARAccount(invchead_cust_id) AS araccntid,
+         aropen_id,
+         ( SELECT COALESCE(SUM(taxhist_tax), 0)
+           FROM invcheadtax
+           WHERE ( (taxhist_parent_id = invchead_id)
+             AND   (taxhist_taxtype_id = getFreightTaxtypeId()) ) ) AS freighttax,
+         ( SELECT COALESCE(SUM(taxhist_tax), 0)
+           FROM invcheadtax
+           WHERE ( (taxhist_parent_id = invchead_id)
+             AND   (taxhist_taxtype_id = getAdjustmentTaxtypeId()) ) ) AS adjtax
+       INTO _p 
+  FROM invchead JOIN aropen ON (aropen_doctype='I' AND aropen_docnumber=invchead_invcnumber)
+  WHERE (invchead_id=pInvcheadid);
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Void Invoice as invchead not found';
+  END IF;
+  IF (NOT _p.invchead_posted) THEN
+    RETURN -10;
+  END IF;
+
+--  Cache AROpen Information
+  SELECT aropen.* INTO _n
+  FROM aropen
+  WHERE ( (aropen_doctype='I')
+    AND   (aropen_docnumber=_p.invchead_invcnumber) );
+  IF (NOT FOUND) THEN
+    RAISE EXCEPTION 'Cannot Void Invoice as aropen not found';
+  END IF;
+
+--  Check for ARApplications
+  SELECT
+        arapply_id
+    INTO
+        _test
+    FROM
+        arapply
+    WHERE
+        (arapply_target_aropen_id=_n.aropen_id)
+    LIMIT
+        1;
+        
+    IF (FOUND) THEN
+  
+    -- try and void the applicatoins..
+        
+        PERFORM
+                voidarcreditmemoapplication( arapply_id )
+            FROM
+                arapply
+            WHERE
+                arapply_target_aropen_id=_n.aropen_id;
+                
+            
+        SELECT
+              arapply_id
+          INTO
+              _test
+          FROM
+              arapply
+          WHERE
+              (arapply_target_aropen_id=_n.aropen_id)
+          LIMIT
+              1;
+        IF (FOUND) THEN 
+            RETURN -20;
+        END IF;
+        
+    
+    
+  END IF;
+  
+  
+  -- check to see if any pending applicataions on unposted cashrcpts use this.
+  
+  SELECT
+        cashrcptitem_id
+    INTO
+        _test
+    FROM
+        cashrcptitem
+    WHERE
+        ( cashrcptitem_aropen_id = _n.aropen_id )
+    LIMIT
+        1;
+  
+    IF (FOUND) THEN 
+        RETURN -20;
+    END IF;
+
+  SELECT fetchGLSequence() INTO _glSequence;
+  SELECT fetchJournalNumber('AR-IN') INTO _glJournal;
+  _glDate := COALESCE(_p.invchead_gldistdate, _p.invchead_invcdate);
+
+-- the 1st MC iteration used the cohead_orderdate so we could get curr exch
+-- gain/loss between the sales and invoice dates, but see issue 3892.  leave
+-- this condition TRUE until we make this configurable or decide not to.
+  IF TRUE THEN
+      _firstExchDate := _p.invchead_invcdate;
+  ELSE
+-- can we save a select by using: _firstExchDate := _p.invchead_orderdate;
+      SELECT cohead_orderdate INTO _firstExchDate
+      FROM cohead
+      WHERE (cohead_number = _p.invchead_ordernumber);
+  END IF;
+
+--  Start by handling taxes (reverse sense)
+  FOR _r IN SELECT tax_sales_accnt_id, 
+              round(sum(taxdetail_tax),2) AS tax,
+              currToBase(_p.invchead_curr_id, round(sum(taxdetail_tax),2), _firstExchDate) AS taxbasevalue
+            FROM tax 
+             JOIN calculateTaxDetailSummary('I', _p.invchead_id, 'T') ON (taxdetail_tax_id=tax_id)
+           GROUP BY tax_id, tax_sales_accnt_id LOOP
+
+    PERFORM insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                _r.tax_sales_accnt_id, 
+                                (_r.taxbasevalue * -1.0),
+                                _glDate, ('Void-' || _p.invchead_billto_name) );
+
+    _totalAmount := _totalAmount + _r.tax;
+    _totalRoundedBase := _totalRoundedBase + _r.taxbasevalue;  
+  END LOOP;
+
+--  March through the Non-Misc. Invcitems
+  FOR _r IN SELECT *
+            FROM invoiceitem
+            WHERE ( (invcitem_invchead_id = _p.invchead_id)
+              AND   (invcitem_item_id <> -1) ) LOOP
+
+--  Cache the amount due for this line
+    _amount := _r.extprice;
+
+    IF (_amount > 0) THEN
+--  Credit the Sales Account for the invcitem item (reverse sense)
+      IF (_r.itemsite_id IS NULL) THEN
+       SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
+       INTO _tmpAccntId
+       FROM salesaccnt
+       WHERE (salesaccnt_id=findSalesAccnt(_r.invcitem_item_id, 'I',
+                                           _p.invchead_cust_id));
+      ELSE
+       SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
+       INTO _tmpAccntId
+       FROM salesaccnt
+       WHERE (salesaccnt_id=findSalesAccnt(_r.itemsite_id, 'IS',
+                                           _p.invchead_cust_id));
+      END IF;
+
+--  If the Sales Account Assignment was not found then punt
+      IF (NOT FOUND) THEN
+        PERFORM deleteGLSeries(_glSequence);
+        RETURN -11;
+      END IF;
+
+      _roundedBase := round(currToBase(_p.invchead_curr_id, _amount, _firstExchDate), 2);
+      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                 _tmpAccntId,
+                                 (_roundedBase * -1.0),
+                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
+
+      _totalAmount := (_totalAmount + _amount);
+      _totalRoundedBase := _totalRoundedBase + _roundedBase;
+      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
+    END IF;
+
+    _totalAmount := _totalAmount;
+    _totalRoundedBase := _totalRoundedBase;
+
+  END LOOP;
+
+--  March through the Misc. Invcitems
+  FOR _r IN SELECT *
+            FROM invoiceitem JOIN salescat ON (salescat_id = invcitem_salescat_id)
+            WHERE ( (invcitem_item_id = -1)
+              AND   (invcitem_invchead_id=_p.invchead_id) ) LOOP
+
+--  Cache the amount due for this line and the commission due for such
+    _amount := _r.extprice;
+
+    IF (_amount > 0) THEN
+--  Credit the Sales Account for the invcitem item (reverse sense)
+      _roundedBase = round(currToBase(_p.invchead_curr_id, _amount,
+                                      _firstExchDate), 2);
+      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                 getPrjAccntId(_p.invchead_prj_id, _r.salescat_sales_accnt_id), 
+                                 (_roundedBase * -1.0),
+                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
+
+      IF (_test < 0) THEN
+        PERFORM deleteGLSeries(_glSequence);
+        RETURN _test;
+      END IF;
+
+      _totalAmount := (_totalAmount + _amount);
+      _totalRoundedBase :=  _totalRoundedBase + _roundedBase;
+      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
+    END IF;
+
+  END LOOP;
+
+--  Credit the Freight Account for Freight Charges (reverse sense)
+  IF (_p.invchead_freight <> 0) THEN
+    IF (_p.freightaccntid <> -1) THEN
+      _roundedBase = round(currToBase(_p.invchead_curr_id, _p.invchead_freight,
+                                      _firstExchDate), 2);
+      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                 getPrjAccntId(_p.invchead_prj_id,_p.freightaccntid), 
+                                 (_roundedBase * -1.0),
+                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
+
+--  Cache the Freight Amount distributed
+        _totalAmount := (_totalAmount + _p.invchead_freight);
+        _totalRoundedBase := _totalRoundedBase + _roundedBase;
+    ELSE
+      _test := -14;
+    END IF;
+
+--  If the Freight Account was not found then punt
+    IF (_test < 0) THEN
+      PERFORM deleteGLSeries(_glSequence);
+      RETURN _test;
+    END IF;
+
+  END IF;
+
+--  Credit the Misc. Account for Miscellaneous Charges (reverse sense)
+  IF (_p.invchead_misc_amount <> 0) THEN
+    _roundedBase := round(currToBase(_p.invchead_curr_id, _p.invchead_misc_amount,
+                                     _firstExchDate), 2);
+    SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                               getPrjAccntId(_p.invchead_prj_id, _p.invchead_misc_accnt_id), 
+                               (_roundedBase * -1.0),
+                               _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
+
+--  If the Misc. Charges Account was not found then punt
+    IF (_test < 0) THEN
+      PERFORM deleteGLSeries(_glSequence);
+      RETURN _test;
+    END IF;
+
+--  Cache the Misc. Amount distributed
+    _totalAmount := (_totalAmount + _p.invchead_misc_amount);
+    _totalRoundedBase := _totalRoundedBase + _roundedBase;
+
+  END IF;
+
+-- ToDo: handle rounding errors (reverse sense)
+    _exchGain := currGain(_p.invchead_curr_id, _totalAmount,
+                          _firstExchDate, _glDate);
+    IF (_exchGain <> 0) THEN
+        SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                   getGainLossAccntId(_p.araccntid),
+                                   round(_exchGain, 2),
+                                   _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test ;
+        IF (_test < 0) THEN
+          PERFORM deleteGLSeries(_glSequence);
+          RETURN _test;
+        END IF;
+    END IF;
+
+--  Debit A/R for the total Amount (reverse sense)
+  IF (_totalRoundedBase <> 0) THEN
+    IF (_p.araccntid != -1) THEN
+      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
+                                 _p.araccntid,
+                                 round(_totalRoundedBase, 2),
+                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
+    ELSE
+      PERFORM deleteGLSeries(_glSequence);
+      RETURN _test;
+    END IF;
+  END IF;
+
+--  Commit the GLSeries;
+  SELECT postGLSeries(_glSequence, _glJournal) INTO _test;
+  IF (_test < 0) THEN
+    PERFORM deleteGLSeries(_glSequence);
+    RETURN _test;
+  END IF;
+
+--  Delete sales history
+  DELETE FROM cohisttax
+  WHERE (taxhist_parent_id IN (SELECT cohist_id
+                               FROM cohist
+                               WHERE (cohist_doctype='I' AND cohist_invcnumber=_p.invchead_invcnumber)));
+
+  DELETE FROM cohist
+  WHERE (cohist_doctype='I' AND cohist_invcnumber=_p.invchead_invcnumber);
+
+--  Create the Credit aropen item
+  SELECT nextval('aropen_aropen_id_seq') INTO _aropenid;
+  INSERT INTO aropen
+  ( aropen_id, aropen_username, aropen_journalnumber,
+    aropen_open, aropen_posted,
+    aropen_cust_id, aropen_ponumber,
+    aropen_docnumber, aropen_applyto, aropen_doctype,
+    aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id,
+    aropen_amount, aropen_paid,
+    aropen_salesrep_id, aropen_commission_due, aropen_commission_paid,
+    aropen_ordernumber, aropen_notes, aropen_cobmisc_id,
+    aropen_curr_id )
+  VALUES
+  ( _aropenid, getEffectiveXtUser(), _glJournal,
+    TRUE, FALSE,
+    _p.invchead_cust_id, _p.invchead_ponumber,
+    _p.invchead_invcnumber || '-VOID', _p.invchead_invcnumber, 'C',
+    _p.invchead_invcdate, determineDueDate(_p.invchead_terms_id, _p.invchead_invcdate), _glDate, _p.invchead_terms_id,
+    round(_totalAmount, 2), round(_totalAmount, 2), 
+    _p.invchead_salesrep_id, _commissionDue, FALSE,
+    _p.invchead_ordernumber::text, _p.invchead_notes, pInvcheadid,
+    _p.invchead_curr_id );
+
+--  Alter the Invoice A/R Open Item to reflect the application
+    UPDATE aropen
+    SET aropen_paid = round(_totalAmount, 2)
+    WHERE (aropen_id=_p.aropen_id);
+
+--  Record the application
+    INSERT INTO arapply
+    ( arapply_cust_id,
+      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
+      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
+      arapply_fundstype, arapply_refnumber,
+      arapply_applied, arapply_closed,
+      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_curr_id )
+    VALUES
+    ( _p.invchead_cust_id,
+      _aropenid, 'C', _p.invchead_invcnumber || '-VOID',
+      _p.aropen_id, 'I', _p.invchead_invcnumber,
+      '', '',
+      round(_totalAmount, 2), TRUE,
+      CURRENT_DATE, _p.invchead_invcdate, 0, _p.invchead_curr_id );
+
+-- Handle the Inventory and G/L Transactions for any billed Inventory where invcitem_updateinv is true (reverse sense)
+  FOR _r IN SELECT itemsite_id AS itemsite_id, invcitem_id,
+                   (invcitem_billed * invcitem_qty_invuomratio) AS qty,
+                   invchead_invcnumber, invchead_cust_id AS cust_id, item_number,
+                   invchead_prj_id
+            FROM invchead JOIN invcitem ON ( (invcitem_invchead_id=invchead_id) AND
+                                             (invcitem_billed <> 0) AND
+                                             (invcitem_updateinv) )
+                          JOIN itemsite ON ( (itemsite_item_id=invcitem_item_id) AND
+                                             (itemsite_warehous_id=invcitem_warehous_id) )
+                          JOIN item ON (item_id=invcitem_item_id)
+            WHERE (invchead_id=_p.invchead_id) LOOP
+
+--  Issue billed stock from inventory
+    IF (_itemlocSeries = 0) THEN
+      SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
+    END IF;
+    SELECT postInvTrans( itemsite_id, 'SH', (_r.qty * -1.0),
+                         'S/O', 'IN', _r.invchead_invcnumber, '',
+                         ('Invoice Voided ' || _r.item_number),
+                         getPrjAccntId(_r.invchead_prj_id, resolveCOSAccount(itemsite_id, _r.cust_id)), costcat_asset_accnt_id,
+                         _itemlocSeries, _glDate) INTO _invhistid
+    FROM itemsite, costcat
+    WHERE ( (itemsite_costcat_id=costcat_id)
+     AND (itemsite_id=_r.itemsite_id) );
+
+
+-- This should also to a invdist reverse...
+    
+
+
+
+  END LOOP;
+
+--  Reopen Billing
+  UPDATE shipitem
+  SET shipitem_invoiced=FALSE,
+      shipitem_invcitem_id=NULL
+  WHERE (shipitem_invcitem_id IN (SELECT invcitem_id
+                                  FROM invcitem
+                                  WHERE (invcitem_invchead_id=_p.invchead_id)));
+  UPDATE cobill
+  SET cobill_invcnum=NULL,
+      cobill_invcitem_id=NULL
+  WHERE (cobill_invcitem_id IN (SELECT invcitem_id
+                                FROM invcitem
+                                WHERE (invcitem_invchead_id=_p.invchead_id)));
+
+
+--  This stuff is modified from original code..
+
+--  cobmisc_invcnumber=NULL, PRESERVE so it can be used again..
+
+-- cobmisc- increase revision (this is used by our FE code to generate a revised invoice number)
+
+  UPDATE cobmisc
+    SET
+        cobmisc_posted=FALSE,
+        cobmisc_invchead_id=NULL,
+        cobmisc_rev = cobmisc_rev + 1,
+        cobmisc_invcnumber=NULL
+    WHERE (cobmisc_invchead_id=_p.invchead_id);
+
+  UPDATE invchead
+        SET invchead_void=TRUE,
+            invchead_notes=(invchead_notes || 'Voided on ' || current_date || ' by ' || current_user)
+  --        invchead_invcnumber =  _p.invchead_invcnumber || 'x-' || _p.invchead_id
+    WHERE (invchead_id=_p.invchead_id);
+  
+
+--  Mark the invoice as voided - rename - trick the system to rename it.
+  --ALTER TABLE invchead DISABLE TRIGGER USER;
+  
+  --UPDATE invchead
+  --    SET invchead_void=TRUE,
+  --        invchead_notes=(invchead_notes || 'Voided on ' || current_date || ' by ' || current_user),
+  --        invchead_invcnumber =  _p.invchead_invcnumber || 'x-' || _p.invchead_id
+  --    WHERE (invchead_id=_p.invchead_id);
+  
+    
+  --ALTER TABLE invchead ENABLE TRIGGER USER;
+  RETURN _itemlocSeries;
+
+END;
+$$ LANGUAGE plpgsql;
+
+ALTER FUNCTION voidInvoice(INTEGER) 
+  OWNER TO admin;
+  
diff --git a/pgsql/voidpostedcheck.sql b/pgsql/voidpostedcheck.sql
new file mode 100644 (file)
index 0000000..d463f7f
--- /dev/null
@@ -0,0 +1,314 @@
+-- updted to match svn version.
+--- added checkhead_voided
+
+ALTER TABLE checkhead add column checkhead_voided DATE;
+
+CREATE OR REPLACE FUNCTION voidPostedCheck(INTEGER, INTEGER, DATE) RETURNS INTEGER AS $$
+-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pCheckid             ALIAS FOR $1;
+  pJournalNumber       ALIAS FOR $2;
+  pVoidDate            ALIAS FOR $3;
+  _amount_base         NUMERIC := 0;
+  _result               INTEGER;
+  _apopenid            INTEGER;
+  _credit_glaccnt      INTEGER;
+  _docnumber           TEXT;
+  _exchGain            NUMERIC := 0;
+  _exchGainTmp         NUMERIC := 0;
+  _gltransNote         TEXT;
+  _p                   RECORD;
+  _r                   RECORD;
+  _sequence            INTEGER;
+  _amount_check         NUMERIC := 0;
+
+BEGIN
+
+  SELECT fetchGLSequence() INTO _sequence;
+
+  SELECT checkhead.*,
+         checkhead_amount / checkhead_curr_rate AS checkhead_amount_base,
+         bankaccnt_accnt_id AS bankaccntid,
+         findPrepaidAccount(checkhead_recip_id) AS prepaidaccntid,
+        checkrecip.* INTO _p
+  FROM bankaccnt, checkhead LEFT OUTER JOIN
+       checkrecip ON ((checkrecip_type=checkhead_recip_type)
+                 AND (checkrecip_id=checkhead_recip_id))
+  WHERE ((checkhead_bankaccnt_id=bankaccnt_id)
+    AND  (checkhead_id=pCheckid));
+
+  IF (NOT _p.checkhead_posted) THEN
+    RETURN -10;
+  END IF;
+
+  IF (_p.checkrecip_id IS NULL) THEN   -- outer join failed
+    RETURN -11;
+  END IF;
+
+  -- Cannot void if already reconciled
+  SELECT trans_id INTO _result
+  FROM ( SELECT gltrans_id AS trans_id
+         FROM gltrans
+         WHERE ((gltrans_doctype='CK')
+           AND  (gltrans_misc_id=_p.checkhead_id)
+           AND  (gltrans_rec))
+         UNION ALL
+         SELECT sltrans_id AS trans_id
+         FROM sltrans
+         WHERE ((sltrans_doctype='CK')
+           AND  (sltrans_misc_id=_p.checkhead_id)
+           AND  (sltrans_rec)) ) AS data;
+  IF (FOUND) THEN
+    RETURN -14;
+  END IF;
+
+  _gltransNote := 'Void Posted Check #' || _p.checkhead_number || ' ' ||
+                 _p.checkrecip_number || '-' || _p.checkrecip_name;
+
+  IF (_p.checkhead_misc) THEN
+    IF (COALESCE(_p.checkhead_expcat_id, -1) < 0) THEN
+      IF (_p.checkhead_recip_type = 'V') THEN
+       PERFORM createAPDebitMemo(_p.checkhead_recip_id, pJournalNumber,
+                                 CAST(fetchAPMemoNumber() AS text), '',
+                                 pVoidDate, _p.checkhead_amount,
+                                 _gltransNote || ' '|| _p.checkhead_notes,
+                                 -1, pVoidDate, -1, _p.checkhead_curr_id );
+       _credit_glaccnt := findAPPrepaidAccount(_p.checkhead_recip_id);
+
+      ELSIF (_p.checkhead_recip_type = 'C') THEN
+       PERFORM createARCreditMemo(NULL, _p.checkhead_recip_id,
+                                 fetchARMemoNumber(), '', 
+                                 pVoidDate, _p.checkhead_amount,
+                                 _gltransNote || ' '|| _p.checkhead_notes,
+                                 -1, -1, -1, pVoidDate, -1, NULL, 0.0,
+                                 pJournalNumber, _p.checkhead_curr_id );
+       _credit_glaccnt := _p.prepaidaccntid;
+
+      ELSIF (_p.checkhead_recip_type = 'T') THEN
+       -- TODO: should we create a debit memo for the tax authority? how?
+       _credit_glaccnt := _p.checkrecip_accnt_id;
+
+      END IF; -- recip type
+
+    ELSE
+      SELECT expcat_exp_accnt_id INTO _credit_glaccnt
+      FROM expcat
+      WHERE (expcat_id=_p.checkhead_expcat_id);
+      IF (NOT FOUND) THEN
+        RETURN -12;
+      END IF;
+    END IF;
+
+    IF (COALESCE(_credit_glaccnt, -1) < 0) THEN
+      RETURN -13;
+    END IF;
+
+    PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source, 'CK',
+                               text(_p.checkhead_number),
+                               _credit_glaccnt,
+                               round(_p.checkhead_amount_base, 2),
+                               pVoidDate, _gltransNote, pCheckid);
+
+    _amount_base := _p.checkhead_amount_base;
+
+  ELSE
+    FOR _r IN SELECT checkitem_amount, checkitem_discount,
+                     CASE WHEN (checkitem_apopen_id IS NOT NULL) THEN
+                       checkitem_amount / apopen_curr_rate
+                     ELSE
+                       currToBase(checkitem_curr_id,
+                                  checkitem_amount,
+                                  COALESCE(checkitem_docdate, _p.checkhead_checkdate)) 
+                     END AS checkitem_amount_base,
+                       checkitem_amount / checkitem_curr_rate   AS amount_check,
+                     apopen_id, apopen_doctype, apopen_docnumber, apopen_curr_rate, apopen_docdate,
+                     aropen_id, aropen_doctype, aropen_docnumber,
+                     checkitem_curr_id, checkitem_curr_rate,
+                     COALESCE(checkitem_docdate, _p.checkhead_checkdate) AS docdate
+              FROM (checkitem LEFT OUTER JOIN
+                   apopen ON (checkitem_apopen_id=apopen_id)) LEFT OUTER JOIN
+                   aropen ON (checkitem_aropen_id=aropen_id)
+              WHERE (checkitem_checkhead_id=pcheckid) LOOP
+
+      _exchGainTmp := 0;
+      IF (_r.apopen_id IS NOT NULL) THEN
+       -- undo the APDiscount Credit Memo if a discount was taken
+        IF(_r.checkitem_discount > 0) THEN
+          SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
+          SELECT fetchAPMemoNumber() INTO _docnumber;
+          INSERT INTO apopen
+          ( apopen_id, apopen_username, apopen_journalnumber,
+            apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
+            apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
+            apopen_amount, apopen_paid, apopen_open,
+           apopen_notes,
+           apopen_accnt_id, apopen_curr_id, apopen_discount, apopen_curr_rate,
+            apopen_closedate )
+          VALUES
+          ( _apopenid, getEffectiveXtUser(), pJournalNumber,
+            _p.checkhead_recip_id, _docnumber, 'D', '',
+            pVoidDate, pVoidDate, pVoidDate, -1,
+            _r.checkitem_discount, _r.checkitem_discount, FALSE,
+            ('Reverse Posted Discount ' || _r.apopen_doctype || ' ' ||
+             _r.apopen_docnumber),
+           -1, _p.checkhead_curr_id, TRUE, _r.apopen_curr_rate,
+            current_date );
+
+
+          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
+                                     'DS', _r.apopen_docnumber,
+                                      findAPDiscountAccount(_p.checkhead_recip_id),
+                                      round(_r.checkitem_discount / _r.apopen_curr_rate, 2) * -1,
+                                      pVoidDate, _gltransNote, pCheckid);
+
+          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
+                                     'DS', _r.apopen_docnumber,
+                                      findAPAccount(_p.checkhead_recip_id),
+                                      round(_r.checkitem_discount / _r.apopen_curr_rate, 2),
+                                      pVoidDate, _gltransNote, pCheckid);
+
+         --  Post the application
+          INSERT INTO apapply
+          ( apapply_vend_id, apapply_postdate, apapply_username,
+            apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
+            apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
+            apapply_journalnumber, apapply_amount, apapply_curr_id )
+          VALUES
+          ( _p.checkhead_recip_id, pVoidDate, getEffectiveXtUser(),
+            _apopenid, 'D', _docnumber,
+            _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
+            pJournalNumber, (_r.checkitem_discount * -1), _r.checkitem_curr_id );
+        END IF; -- discount was taken
+
+        UPDATE apopen
+       SET apopen_paid = round(apopen_paid -
+                               (_r.checkitem_amount + noNeg(_r.checkitem_discount)), 2),
+            apopen_open = round(apopen_amount, 2) >
+                         round(apopen_paid -
+                               (_r.checkitem_amount + noNeg(_r.checkitem_discount)), 2),
+            apopen_closedate = CASE WHEN (round(apopen_amount, 2) >
+                                         round(apopen_paid -
+                                          (_r.checkitem_amount + noNeg(_r.checkitem_discount)))) THEN NULL ELSE apopen_closedate END
+        WHERE (apopen_id=_r.apopen_id);
+
+       --  Post the application
+        INSERT INTO apapply
+        ( apapply_vend_id, apapply_postdate, apapply_username,
+          apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
+          apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
+          apapply_journalnumber, apapply_amount, apapply_curr_id )
+        VALUES
+        ( _p.checkhead_recip_id, pVoidDate, getEffectiveXtUser(),
+          -1, 'K', _p.checkhead_number,
+          _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
+          pJournalNumber, (_r.checkitem_amount * -1), _r.checkitem_curr_id );
+      END IF; -- if check item's apopen_id is not null
+
+      IF (_r.aropen_id IS NOT NULL) THEN
+        UPDATE aropen
+        SET aropen_paid = round(aropen_paid -_r.checkitem_amount, 2),
+            aropen_open = round(aropen_amount, 2) >
+                         round(aropen_paid - _r.checkitem_amount, 2)
+        WHERE (aropen_id=_r.aropen_id);
+
+       --  Post the application
+        INSERT INTO arapply
+        ( arapply_cust_id, arapply_postdate, arapply_distdate, arapply_username,
+          arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
+          arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
+          arapply_journalnumber, arapply_applied, arapply_curr_id )
+        VALUES
+        ( _p.checkhead_recip_id, pVoidDate, pVoidDate, getEffectiveXtUser(),
+          -1, 'K', _p.checkhead_number,
+          _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
+          pJournalNumber, (_r.checkitem_amount * -1), _r.checkitem_curr_id );
+
+      END IF; -- if check item's aropen_id is not null
+
+--  calculate currency gain/loss
+      IF (_r.apopen_id IS NOT NULL) THEN
+        IF (_p.checkhead_curr_id = _r.checkitem_curr_id) THEN
+          IF (_r.apopen_docdate > _p.checkhead_checkdate) THEN
+            _exchGainTmp := ((_r.checkitem_amount/_p.checkhead_curr_rate) - (_r.checkitem_amount / _r.apopen_curr_rate)) * -1;
+          ELSE
+            _exchGainTmp := ((_r.checkitem_amount / _r.apopen_curr_rate) - (_r.checkitem_amount/_p.checkhead_curr_rate));
+          END IF;
+        ELSE
+          -- unusual condition where bank overridden and different currency from voucher
+          IF (_r.apopen_docdate > _p.checkhead_checkdate) THEN
+            _exchGainTmp := ((_r.checkitem_amount/_r.checkitem_curr_rate) - (_r.checkitem_amount / _r.apopen_curr_rate)) * -1;
+          ELSE
+            _exchGainTmp := ((_r.checkitem_amount / _r.apopen_curr_rate) - (_r.checkitem_amount/_r.checkitem_curr_rate));
+          END IF;
+        END IF;
+      ELSE
+        SELECT arCurrGain(_r.aropen_id,_r.checkitem_curr_id, _r.checkitem_amount,
+                        _p.checkhead_checkdate)
+              INTO _exchGainTmp;
+      END IF;
+      _exchGain := _exchGain + _exchGainTmp;
+
+      PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
+                                 'CK', text(_p.checkhead_number),
+                                  _p.checkrecip_accnt_id,
+                                  round(_r.checkitem_amount_base, 2),
+                                  pVoidDate, _gltransNote, pCheckid);
+      IF (_exchGainTmp <> 0) THEN
+          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
+                                     'CK', text(_p.checkhead_number),
+                                     getGainLossAccntId(_p.checkrecip_accnt_id),
+                                     round(_exchGainTmp, 2) * -1,
+                                     pVoidDate, _gltransNote, pCheckid);
+      END IF;
+
+      _amount_check := (_amount_check + _r.amount_check);
+      _amount_base := (_amount_base + _r.checkitem_amount_base);
+
+    END LOOP;
+
+    IF( (_amount_check - _p.checkhead_amount) <> 0.0 ) THEN 
+      _exchGainTmp :=  (_amount_check - _p.checkhead_amount) / _p.checkhead_curr_rate;
+      _exchGain := _exchGain + _exchGainTmp;
+    END IF;
+
+    --  ensure that the check balances, attribute rounding errors to gain/loss
+    IF round(_amount_base, 2) - round(_exchGain, 2) <> round(_p.checkhead_amount_base, 2) THEN
+      IF round(_amount_base - _exchGain, 2) = round(_p.checkhead_amount_base, 2) THEN
+       PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
+                                   'CK',
+                                   text(_p.checkhead_number), getGainLossAccntId(_p.bankaccntid),
+                                   (round(_amount_base, 2) -
+                                    round(_exchGain, 2) -
+                                    round(_p.checkhead_amount_base, 2)) * -1,
+                                   pVoidDate, _gltransNote, pCheckid);
+      ELSE
+       RAISE EXCEPTION 'checkhead_id % does not balance (% - % <> %)', pCheckid,
+             _amount_base, _exchGain, _p.checkhead_amount_base;
+      END IF;
+    END IF;
+  END IF;
+
+  PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source, 'CK',
+                             text(_p.checkhead_number),
+                              _p.bankaccntid,
+                             round(_p.checkhead_amount_base, 2) * -1,
+                              pVoidDate, _gltransNote, pCheckid);
+
+  PERFORM postGLSeries(_sequence, pJournalNumber);
+
+  UPDATE gltrans
+     SET gltrans_misc_id=pCheckid
+   WHERE gltrans_sequence=_sequence;
+
+  UPDATE checkhead
+  SET checkhead_posted=false,
+      checkhead_void=true,
+      checkhead_voided=pVoidDate,
+      checkhead_journalnumber=pJournalNumber
+  WHERE (checkhead_id=pCheckid);
+
+  RETURN pJournalNumber;
+
+END;
+$$ LANGUAGE 'plpgsql';
\ No newline at end of file
diff --git a/pgsql/x-dragon-accnt.sql b/pgsql/x-dragon-accnt.sql
new file mode 100644 (file)
index 0000000..2ada236
--- /dev/null
@@ -0,0 +1,8 @@
+
+-- kingdee code for the account ---
+ALTER TABLE accnt ADD COLUMN accnt_code_alt TEXT DEFAULT '';
+
+-- chinese name for the account ---
+ALTER TABLE accnt ADD COLUMN accnt_descrip_alt TEXT DEFAULT '';
+
+CREATE INDEX accnt_code_descrip_alt  ON accnt USING btree  (accnt_code_alt, accnt_descrip_alt);
diff --git a/pgsql/x-dragon-apopen_isposted.sql b/pgsql/x-dragon-apopen_isposted.sql
new file mode 100644 (file)
index 0000000..44d4fa8
--- /dev/null
@@ -0,0 +1,51 @@
+
+CREATE OR REPLACE FUNCTION apopen_isreversed(integer, text, text)
+    RETURNS  BOOLEAN
+    
+AS $BODY$
+DECLARE        
+    i_apopen_id  ALIAS FOR $1;
+    i_docnumber ALIAS FOR $2;
+    i_doctype ALIAS FOR $3;
+    v_posted BOOLEAN;
+    
+BEGIN
+    --RAISE NOTICE 'test %', i_docnumber ;
+    IF i_doctype != 'C' THEN
+      --  RAISE NOTICE 'original not posted';
+        RETURN FALSE;
+    END IF;
+
+    -- posted = true or null
+    
+    SELECT
+        apopen_posted
+    INTO
+        v_posted
+    FROM
+        apopen
+    WHERE
+        apopen_id != i_apopen_id
+        AND
+        apopen_docnumber = i_docnumber
+        AND
+        apopen_doctype = 'V';
+    
+    IF NOT FOUND THEN
+    --    RAISE NOTICE 'no match found';
+        RETURN FALSE;
+    END IF;
+    
+    --RAISE NOTICE 'match is not posted';
+    RETURN TRUE;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION apopen_isreversed(integer, text, text)
+  OWNER TO admin;
+
+-- test..
+--select apopen_isposted(10088,'NSVB-4668-92170', null);
diff --git a/pgsql/x-dragon-apopen_isreversed.sql b/pgsql/x-dragon-apopen_isreversed.sql
new file mode 100644 (file)
index 0000000..a36aa99
--- /dev/null
@@ -0,0 +1,69 @@
+
+-- credit memo applied to voucher - voiding it out..
+CREATE OR REPLACE FUNCTION apopen_isreversed(integer, text, text , text)
+    RETURNS  BOOLEAN
+    
+AS $BODY$
+DECLARE        
+    i_apopen_id  ALIAS FOR $1;
+    i_docnumber ALIAS FOR $2;
+    i_doctype ALIAS FOR $3;
+    i_status ALIAS FOR $4;
+
+    v_id INTEGER;
+    
+BEGIN
+    IF i_status != 'C' THEN
+        RETURN FALSE;
+    END IF;
+
+    --RAISE NOTICE 'test %', i_docnumber ;
+    IF i_doctype != 'C' AND  i_doctype != 'V'  THEN
+      --  RAISE NOTICE 'original not posted';
+        RETURN FALSE;
+    END IF;
+    
+
+    -- posted = true or null
+    
+    SELECT
+        apopen_id
+    INTO
+        v_id
+    FROM
+        apopen
+    WHERE
+        apopen_id != i_apopen_id
+        AND
+        apopen_docnumber = i_docnumber
+        AND
+        apopen_doctype != i_doctype
+        AND
+        (apopen_doctype = 'C' OR apopen_doctype = 'V')
+        AND
+        
+        -- and it both must be posted on the same day...
+        apopen_doctype = (SELECT apopen_doctype  FROM apopen where apopen_id = i_apopen_id)
+        AND
+        
+        -- and it has to be closed..
+        apopen_status = 'C';
+    
+    IF NOT FOUND THEN
+    --    RAISE NOTICE 'no match found';
+        RETURN FALSE;
+    END IF;
+    
+    --RAISE NOTICE 'match is not posted';
+    RETURN TRUE;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION apopen_isreversed(integer, text, text, text)
+  OWNER TO admin;
+
+-- test..
+--select apopen_isposted(10088,'NSVB-4668-92170', null);
diff --git a/pgsql/x-dragon-aropen-accountcheck.sql b/pgsql/x-dragon-aropen-accountcheck.sql
new file mode 100644 (file)
index 0000000..b075b77
--- /dev/null
@@ -0,0 +1,230 @@
+
+CREATE OR REPLACE FUNCTION aropen_accountcheck_all()
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE   
+    _r RECORD;
+    v_gltrans_val NUMERIC;
+
+BEGIN
+    FOR _r IN SELECT
+                        araging_docnumber,
+                        araging_doctype,
+                        araging_total_val
+              FROM
+                        araging(current_date,TRUE)
+              ORDER BY
+                        araging_docnumber LOOP
+
+            SELECT aropen_accountcheck(_r.araging_docnumber) INTO v_gltrans_val;
+            
+            IF _r.araging_total_val + v_gltrans_val <> 0 THEN
+                RAISE EXCEPTION 'araging_docnumber = % , araging_doctype = % , GL is = % , AR is = %',_r.araging_docnumber,_r.araging_doctype,v_gltrans_val,_r.araging_total_val;
+            END IF;
+    END LOOP;
+    
+    RETURN 'OK';
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION aropen_accountcheck_all()
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION aropen_accountcheck(i_docnumber TEXT)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE   
+    v_related TEXT[];
+    v_gltrans_related TEXT[];
+    v_cashrcpt_related INT[];
+    v_ar_accnt_id INTEGER;
+    v_cd_accnt_id INTEGER;
+    v_cashrcptitem_id INTEGER;
+    v_result NUMERIC;
+BEGIN
+
+    SELECT 
+            araccnt_ar_accnt_id 
+    INTO
+            v_ar_accnt_id
+    FROM
+            araccnt
+    WHERE
+            araccnt_custtype = '.*'
+    LIMIT 1;
+
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Missing Account Receivable Account';
+    END IF;
+
+    SELECT 
+            accnt_id
+    INTO
+            v_cd_accnt_id
+    FROM
+            accnt
+    WHERE
+            accnt_descrip = 'Customer Deposits'
+    LIMIT 1;
+
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Missing Customer Deposits Account';
+    END IF;
+    v_related:= ARRAY[]::TEXT[];
+    v_gltrans_related := ARRAY[]::TEXT[];
+    v_cashrcpt_related := ARRAY[]::INT[];
+
+    SELECT aropen_related(i_docnumber, v_related) INTO v_related;
+
+    FOR i IN 1 .. array_upper(v_related,1) LOOP
+        IF (TRUE = ((SELECT strpos(v_related[i]::TEXT, '::')) > 0)) THEN
+
+            SELECT split_part(v_related[i]::TEXT, '::', 2) INTO v_cashrcptitem_id;
+
+            SELECT array_append(v_cashrcpt_related, v_cashrcptitem_id) INTO v_cashrcpt_related;
+        ELSE
+            SELECT array_append(v_gltrans_related, v_related[i]) INTO v_gltrans_related;
+        END IF;
+    END LOOP;
+
+    SELECT
+            SUM(COALESCE(gltrans_amount,0))
+    INTO
+            v_result
+    FROM
+            gltrans
+    WHERE
+            gltrans_docnumber = ANY (v_gltrans_related)
+        AND
+            gltrans_accnt_id IN (v_ar_accnt_id, v_cd_accnt_id)
+        AND
+            gltrans_posted
+        AND
+            NOT gltrans_deleted;
+
+
+    SELECT
+            SUM(COALESCE(gltrans_amount,0)) + v_result
+    INTO
+            v_result
+    FROM
+            gltrans
+    WHERE
+            gltrans_misc_id IN (SELECT
+                                        DISTINCT(cashrcpt_id)
+                                FROM
+                                        cashrcpt
+                                LEFT JOIN 
+                                        cashrcptitem
+                                ON
+                                        cashrcptitem_cashrcpt_id = cashrcpt_id
+                                WHERE
+                                        cashrcptitem_id = ANY (v_cashrcpt_related))
+        AND
+            gltrans_source = 'A/R'
+        AND
+            gltrans_doctype = 'CR'
+        AND
+            gltrans_accnt_id IN (v_ar_accnt_id, v_cd_accnt_id)
+        AND
+            gltrans_posted
+        AND
+            NOT gltrans_deleted;
+
+
+    RAISE NOTICE 'GL IS %',v_result;
+
+    SELECT
+            
+            SUM(araging_total_val)
+
+    INTO
+            v_result
+    FROM
+            araging(current_date,TRUE)
+    WHERE
+            araging_docnumber = ANY (v_gltrans_related);
+RAISE NOTICE 'AR IS %',v_result;
+
+    RETURN v_result;
+
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION aropen_accountcheck(TEXT)
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION aropen_related(i_docnumber TEXT, i_related TEXT[])
+    RETURNS  TEXT[]
+    
+AS $BODY$
+DECLARE   
+    _r RECORD;
+    v_number TEXT;
+BEGIN
+
+    IF (NOT ARRAY[i_docnumber] <@ i_related) THEN
+        SELECT array_append(i_related, i_docnumber) INTO i_related;
+    END IF;
+
+    SELECT split_part(i_docnumber, '::', 1) INTO i_docnumber;
+
+    FOR _r IN SELECT
+            *
+    FROM 
+            arapply
+    WHERE  
+            (arapply_target_docnumber = i_docnumber)
+        OR 
+            (arapply_source_docnumber = i_docnumber) LOOP
+
+        IF (_r.arapply_source_docnumber IS NOT NULL) THEN
+            v_number = _r.arapply_source_docnumber;
+        END IF;
+        
+        IF (_r.arapply_source_aropen_id = -1 AND _r.arapply_reftype IS NOT NULL AND _r.arapply_ref_id IS NOT NULL) THEN
+            v_number = _r.arapply_source_docnumber || '::' || _r.arapply_ref_id;
+        END IF;
+        
+        IF (NOT ARRAY[v_number] <@ i_related) THEN
+            SELECT aropen_related(v_number, i_related) INTO i_related;
+        END IF;
+        
+        IF (_r.arapply_target_docnumber IS NOT NULL) THEN
+            v_number = _r.arapply_target_docnumber;
+        END IF;
+        
+        IF (_r.arapply_target_aropen_id = -1 AND _r.arapply_reftype IS NOT NULL AND _r.arapply_ref_id IS NOT NULL) THEN
+            v_number = _r.arapply_target_docnumber || '::' || _r.arapply_ref_id;
+        END IF;
+
+        IF (NOT ARRAY[v_number] <@ i_related) THEN
+            SELECT aropen_related(v_number, i_related) INTO i_related;
+        END IF;
+        
+    END LOOP;
+    
+    RETURN i_related;
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION aropen_related(TEXT, TEXT[])
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-dragon-aropen_isposted.sql b/pgsql/x-dragon-aropen_isposted.sql
new file mode 100644 (file)
index 0000000..73018db
--- /dev/null
@@ -0,0 +1,15 @@
+
+       
+CREATE OR REPLACE FUNCTION arpopen_isposted(integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_id  ALIAS FOR $1;
+   
+    v_ret NUMERIC;
+    v_cohead_number TEXT;
+    
+BEGIN
+
+    SELECT coh
\ No newline at end of file
diff --git a/pgsql/x-dragon-bankrec-fix-historical.sql b/pgsql/x-dragon-bankrec-fix-historical.sql
new file mode 100644 (file)
index 0000000..5010e0a
--- /dev/null
@@ -0,0 +1,315 @@
+-- fix the bankrec historical data, use the new working flow
+
+CREATE OR REPLACE FUNCTION bankrec_fix_historical_all()
+  RETURNS BOOLEAN AS
+$BODY$
+DECLARE
+    v_start_date DATE;
+    v_end_date DATE;
+    v_bankaccnt INT[];
+    _r RECORD;
+    
+BEGIN
+    
+    SELECT
+            MIN(bankrec_opendate),
+            MAX(bankrec_enddate)
+    INTO
+            v_start_date,
+            v_end_date
+    FROM
+            bankrec
+    WHERE
+            bankrec_posted = TRUE;
+
+    RAISE NOTICE 'MIN Date : %, MAX Date : %', v_start_date, v_end_date;
+    
+    IF (v_start_date IS NULL OR v_end_date IS NULL) THEN
+        -- delete all the bankrec data and fix the sequence
+        DELETE FROM bankrec;
+        DELETE FROM bankrecitem;
+
+        ALTER SEQUENCE bankrec_bankrec_id_seq RESTART WITH 1;
+        ALTER SEQUENCE bankrecitem_bankrecitem_id_seq RESTART WITH 1;
+        
+        RETURN TRUE;
+    END IF;
+
+    v_bankaccnt := ARRAY[]::INT[];
+
+    FOR _r IN SELECT
+            bankrec_bankaccnt_id
+    FROM
+            bankrec
+    WHERE
+            bankrec_posted = TRUE LOOP
+
+            IF (NOT ARRAY[_r.bankrec_bankaccnt_id] <@ v_bankaccnt) THEN
+                SELECT array_append(v_bankaccnt, _r.bankrec_bankaccnt_id) INTO v_bankaccnt;
+            END IF;
+
+    END LOOP;
+
+    RAISE NOTICE 'v_bankaccnt = % ', v_bankaccnt;
+            
+    PERFORM
+            voidbankreconciliation(bankrec_id)
+    FROM
+            bankrec
+    WHERE
+            bankrec_posted = TRUE;
+            
+            
+    -- delete all the bankrec data and fix the sequence
+    DELETE FROM bankrec;
+    DELETE FROM bankrecitem;
+    
+    ALTER SEQUENCE bankrec_bankrec_id_seq RESTART WITH 1;
+    ALTER SEQUENCE bankrecitem_bankrecitem_id_seq RESTART WITH 1;
+
+    FOR i IN 1 .. array_upper(v_bankaccnt,1) LOOP
+
+        PERFORM bankrec_fix_historical(v_bankaccnt[i]::INTEGER, v_start_date, v_end_date);
+
+    END LOOP;
+    
+            
+
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION bankrec_fix_historical_all()
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION bankrec_fix_historical(i_bankaccnt_id INTEGER, i_start_date DATE, i_end_date DATE)
+  RETURNS BOOLEAN AS
+$BODY$
+DECLARE
+    v_accnt_id INTEGER;
+    v_openbal NUMERIC;
+    v_closebal NUMERIC;
+    _r RECORD;
+    v_bankrec_id INTEGER;
+    v_result INTEGER;
+    v_bankrec_posted BOOLEAN;
+BEGIN
+    
+    RAISE NOTICE 'Doing bankaccnt_id is %', i_bankaccnt_id;
+    
+    SELECT
+            bankaccnt_accnt_id
+    INTO
+            v_accnt_id
+    FROM
+            bankaccnt
+    WHERE
+            bankaccnt_id = i_bankaccnt_id;
+
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Bank Account not found i_bankaccnt_id = %', i_bankaccnt_id;
+    END IF;
+    
+    SELECT
+            COALESCE(SUM(gltrans_amount * -1), 0)
+    INTO
+            v_openbal
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_accnt_id
+    AND
+            gltrans_date < i_start_date
+    AND
+            gltrans_posted = TRUE
+    AND
+            NOT gltrans_deleted;
+
+
+    FOR _r IN SELECT 
+            gltrans_date,
+            SUM(ROUND(gltrans_amount,2)) OVER (ORDER BY gltrans_date ASC) AS v_balance
+    FROM
+    (
+        SELECT
+                DISTINCT(gltrans_date) AS gltrans_date,
+                COALESCE(SUM(gltrans_amount * -1), 0) AS gltrans_amount
+        FROM
+                gltrans
+        WHERE
+                gltrans_accnt_id = v_accnt_id
+        AND
+                gltrans_date BETWEEN i_start_date AND i_end_date
+        AND
+                gltrans_posted = TRUE
+        AND
+                NOT gltrans_deleted
+
+        GROUP BY gltrans_date
+    ) AS x LOOP
+        
+        v_closebal := v_openbal + _r.v_balance;
+        
+        SELECT
+                bankrec_id,
+                bankrec_posted
+        INTO
+                v_bankrec_id,
+                v_bankrec_posted
+        FROM
+                bankrec
+        WHERE
+                bankrec_bankaccnt_id = i_bankaccnt_id
+            AND
+                bankrec_opendate = _r.gltrans_date
+            AND
+                bankrec_enddate = _r.gltrans_date;
+            
+        IF (FOUND AND v_bankrec_posted) THEN
+            RAISE NOTICE 'Skip - already posted';
+            RETURN TRUE;
+        END IF;
+
+        IF (FOUND AND NOT v_bankrec_posted) THEN
+            DELETE FROM bankrec WHERE bankrec_id = v_bankrec_id;
+            DELETE FROM bankrecitem WHERE bankrecitem_bankrec_id = v_bankrec_id;
+        END IF;
+
+        INSERT INTO bankrec (
+            bankrec_created, bankrec_username,
+            bankrec_bankaccnt_id, bankrec_opendate,
+            bankrec_enddate, bankrec_openbal,
+            bankrec_endbal, bankrec_posted,
+            bankrec_postdate 
+        ) VALUES (
+            NOW(), 'admin',
+            i_bankaccnt_id, _r.gltrans_date,
+            _r.gltrans_date, v_openbal,
+            v_closebal, FALSE, 
+            null
+        );
+
+
+        SELECT
+                bankrec_id
+        INTO
+                v_bankrec_id
+        FROM
+                bankrec
+        WHERE
+                bankrec_bankaccnt_id = i_bankaccnt_id
+            AND
+                bankrec_opendate = _r.gltrans_date
+            AND
+                bankrec_enddate = _r.gltrans_date
+            AND
+                NOT bankrec_posted;
+        
+        IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'Error occur on insert a bankrec';
+        END IF;
+        
+--         RAISE NOTICE 'bankrec id : %, date : %, bankrec_openbal : %, bankrec_closebal : %', v_bankrec_id, _r.gltrans_date, v_openbal, v_closebal;
+        
+        PERFORM
+                setbankreccleared(v_bankrec_id, 'GL', gltrans_id, true)
+        FROM
+                gltrans
+        WHERE
+                gltrans_accnt_id = v_accnt_id
+        AND
+                gltrans_date = _r.gltrans_date
+        AND
+                gltrans_posted = TRUE
+        AND
+                NOT gltrans_deleted ;
+        
+
+        SELECT postBankReconciliation(v_bankrec_id) INTO v_result;
+        
+        IF (v_result < 1) THEN
+            RAISE EXCEPTION 'postBankReconciliation fail, v_bankrec_id = %', v_bankrec_id;
+        END IF;
+
+    END LOOP;
+
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION bankrec_fix_historical(INTEGER, DATE, DATE)
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION bankrec_post_closed_period()
+  RETURNS BOOLEAN AS
+$BODY$
+DECLARE
+    v_start_date DATE;
+    v_end_date DATE;
+    v_bankaccnt INT[];
+    _r RECORD;
+    
+BEGIN
+    
+    SELECT
+            MIN(period_start),
+            MAX(period_end)
+    INTO
+            v_start_date,
+            v_end_date
+    FROM
+            period
+    WHERE
+            period_closed
+        AND
+            period_freeze;
+
+    RAISE NOTICE 'MIN Date : %, MAX Date : %', v_start_date, v_end_date;
+    
+    IF (v_start_date IS NULL OR v_end_date IS NULL) THEN
+        RAISE NOTICE 'Skip - no date found';
+        RETURN TRUE;
+    END IF;
+
+    FOR _r IN SELECT
+            DISTINCT(bankaccnt_id) AS bankaccnt_id
+    FROM
+            gltrans
+    LEFT JOIN
+            bankaccnt
+    ON
+            bankaccnt_accnt_id = gltrans_accnt_id
+            
+    WHERE
+            gltrans_date BETWEEN v_start_date AND v_end_date
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted = TRUE 
+        AND
+            bankaccnt_id IS NOT NULL LOOP
+           
+            PERFORM bankrec_fix_historical(_r.bankaccnt_id, v_start_date, v_end_date);
+
+    END LOOP;
+
+    
+    
+    
+            
+
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION bankrec_post_closed_period()
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-dragon-charass_getvalue.sql b/pgsql/x-dragon-charass_getvalue.sql
new file mode 100644 (file)
index 0000000..1abcfe4
--- /dev/null
@@ -0,0 +1,110 @@
+-- Function: itemcharvalue(integer, text)
+
+-- DROP FUNCTION itemcharvalue(integer, text);
+
+CREATE OR REPLACE FUNCTION charass_getvalue(text, integer, text)
+  RETURNS text AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pType ALIAS FOR $1;
+  pItemid ALIAS FOR $2;
+  pCharName ALIAS FOR $3;
+  _value TEXT;
+
+BEGIN
+
+  SELECT charass_value INTO _value
+  FROM charass, char
+  WHERE ( (charass_char_id=char_id)
+   AND (charass_target_type=pType )
+   AND (charass_target_id=pItemid)
+   AND (char_name=pCharName) );
+  IF (NOT FOUND) THEN
+    _value = '';
+  END IF;
+
+  RETURN _value;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION charass_getvalue(text,integer, text)
+  OWNER TO admin;
+
+
+-- Function: itemcharvalue(integer, text)
+
+-- DROP FUNCTION itemcharvalue(integer, text);
+
+CREATE OR REPLACE FUNCTION charass_setvalue(text, integer, text, text)
+  RETURNS text AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pType ALIAS FOR $1;
+  pItemid ALIAS FOR $2;
+  pCharName ALIAS FOR $3;
+  i_value ALIAS FOR $4;
+  _value TEXT;
+  v_char_id INTEGER;
+  v_charass_id INTEGER;
+  
+BEGIN
+
+  SELECT
+       charass_id
+        INTO
+        v_charass_id
+     FROM charass, char
+        WHERE ( (charass_char_id=char_id)
+         AND (charass_target_type=pType )
+         AND (charass_target_id=pItemid)
+         AND (char_name=pCharName)
+         -- only works for these types...
+        AND pType IN ('C', 'I')
+         );
+         
+    IF (NOT FOUND) THEN
+        -- no type validation here...
+        
+        SELECT char_id INTO v_char_id
+            FROM
+                char
+            WHERE
+                char_name = pCharName
+                AND
+                -- allowed types....
+                pType IN ('C', 'I')
+            LIMIT 1;
+        
+        IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'Invalid char name %', pCharName;
+        END IF;
+
+        INSERT INTO
+            charass (
+                charass_char_id, charass_target_type ,
+                charass_target_id, charass_value
+            )
+            VALUES
+            (
+                v_char_id , pType,
+                pItemid, i_value 
+            );
+        RETURN i_value;
+    END IF;
+
+    UPDATE charass SET charass_value = i_value WHERE charass_id = v_charass_id;
+    RETURN i_value;
+    
+   
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION charass_setvalue(text,integer, text, text)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-cobapply.sql b/pgsql/x-dragon-cobapply.sql
new file mode 100644 (file)
index 0000000..30073d6
--- /dev/null
@@ -0,0 +1,50 @@
+-- Sequence: cobapply_id_seq
+
+-- DROP SEQUENCE cobapply_id_seq;
+
+CREATE SEQUENCE cobapply_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE cobapply_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE cobapply_id_seq TO admin;
+GRANT ALL ON TABLE cobapply_id_seq TO xtrole;
+
+
+-- cob apply - planned credit memo applications for a bill ;
+
+
+CREATE TABLE cobapply
+(
+    cobapply_id integer NOT NULL DEFAULT nextval(('cobapply_id_seq'::text)::regclass),
+    cobapply_cobmisc_id integer,
+    cobapply_aropen_id integer,
+    cobapply_applied boolean,
+  
+    CONSTRAINT cobapply_pkey PRIMARY KEY (cobapply_id ),
+    CONSTRAINT cobapply_cobmisc_id_fkey FOREIGN KEY (cobapply_cobmisc_id)
+        REFERENCES cobmisc (cobmisc_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION,
+    CONSTRAINT cobapply_aropen_id_fkey FOREIGN KEY (cobapply_aropen_id)
+        REFERENCES aropen (aropen_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+
+CREATE INDEX cobapply_cobmisc_id_ix  ON cobapply  USING btree  (cobapply_cobmisc_id);
+CREATE INDEX cobapply_aropen_id_ix  ON cobapply  USING btree  (cobapply_aropen_id);
+CREATE INDEX cobapply_applied_ix  ON cobapply  USING btree  (cobapply_applied); 
+
+ALTER TABLE cobapply
+  OWNER TO admin;
+GRANT ALL ON TABLE cobapply TO admin;
+GRANT ALL ON TABLE cobapply TO xtrole;
+COMMENT ON TABLE cobapply
+  IS 'Planned credit memo applies to bills';
+  
+  
\ No newline at end of file
diff --git a/pgsql/x-dragon-cohead-test-shipping-qty.sql b/pgsql/x-dragon-cohead-test-shipping-qty.sql
new file mode 100644 (file)
index 0000000..06de5b0
--- /dev/null
@@ -0,0 +1,86 @@
+
+       
+CREATE OR REPLACE FUNCTION x_dragon_cohead_test_shipping_qty(integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_id  ALIAS FOR $1;
+   
+    v_ret NUMERIC;
+    v_cohead_number TEXT;
+    
+BEGIN
+
+    SELECT cohead_number INTO v_cohead_number FROM cohead WHERE cohead_id = i_cohead_id;
+
+    SELECT count(invhist_itemsite_id) into v_ret
+      FROM
+     (
+    
+            SELECT 
+                invhist_itemsite_id,
+                join_item.item_number as item_number,
+                
+                    COALESCE ((SELECT SUM(COALESCE(coitem_qtyreturned,0)) FROM coitem WHERE coitem_cohead_id = i_cohead_id and coitem_itemsite_id = invhist_itemsite_id
+                ) ,0)  +
+                
+                (COALESCE ((SELECT SUM(COALESCE(coitem_qtyshipped,0)) FROM coitem WHERE coitem_cohead_id = i_cohead_id and coitem_itemsite_id = invhist_itemsite_id
+                ), 0)  * -1 )  as rec_total,
+                
+                
+                COALESCE(SUM(
+    CASE WHEN invdetail_qty > 0 THEN 0 ELSE invdetail_qty END
+    ),0) as tx_shipped,
+    
+    COALESCE(SUM(
+    CASE WHEN invdetail_qty < 0 THEN 0 ELSE invdetail_qty END
+    ),0) as tx_returned,
+    
+                COALESCE(SUM(invdetail_qty),0) as tx_total 
+                
+                
+                
+                
+                FROM invdetail 
+            
+                LEFT JOIN invhist AS join_invhist ON
+                    invdetail.invdetail_invhist_id = join_invhist.invhist_id
+                LEFT JOIN invfifo AS join_invfifo ON
+                    invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id
+                LEFT JOIN itemsite AS join_itemsite ON
+                    join_invhist.invhist_itemsite_id = join_itemsite.itemsite_id
+                LEFT JOIN item AS join_item ON
+                    join_itemsite.itemsite_item_id = join_item.item_id 
+                WHERE ( 
+                    invhist_ordtype = 'SO'
+                    AND 
+                    (
+                        invhist_ordnumber LIKE v_cohead_number || '-%'
+                        OR
+                        invhist_ordnumber = v_cohead_number
+                    )
+                ) 
+                GROUP BY invhist_itemsite_id, join_item.item_number 
+            
+                ORDER BY join_item.item_number ASC
+                
+     ) x
+     WHERE
+        tx_total != rec_total;
+    
+    return v_ret;
+                           
+        RETURN v_ret;        
+     END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_dragon_cohead_test_shipping_qty(integer)
+  OWNER TO admin;
+  
+  
\ No newline at end of file
diff --git a/pgsql/x-dragon-cohead.sql b/pgsql/x-dragon-cohead.sql
new file mode 100644 (file)
index 0000000..cb2e5c9
--- /dev/null
@@ -0,0 +1,15 @@
+-- add a 'displayed' sales person.
+
+
+alter table cohead add column cohead_display_salesrep_id INTEGER;
+
+ALTER TABLE cohead add column cohead_pretax_discount numeric(16,4) NOT NULL DEFAULT 0;
+
+ALTER TABLE cohead add column cohead_posttax_discount numeric(16,4) NOT NULL DEFAULT 0;
+ALTER TABLE cohead ADD CONSTRAINT cohead_display_salesrep_fkey FOREIGN KEY (cohead_display_salesrep_id)
+        REFERENCES salesrep(salesrep_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;
+
diff --git a/pgsql/x-dragon-cohist-pos.sql b/pgsql/x-dragon-cohist-pos.sql
new file mode 100644 (file)
index 0000000..79e1cfd
--- /dev/null
@@ -0,0 +1,42 @@
+CREATE OR REPLACE FUNCTION cohist_pos(INTEGER,TEXT,INTEGER)
+  RETURNS INTEGER AS
+$BODY$
+DECLARE
+  pCohist_id ALIAS FOR $1;
+  pCohist_ordernumber ALIAS FOR $2;
+  pItemsite_id ALIAS FOR $3;
+  _result INTEGER;
+
+BEGIN
+    
+    SELECT
+        rn INTO _result
+    FROM
+        (
+            SELECT 
+                    row_number() OVER(ORDER BY cohist_id ASC) as rn, cohist_id, cohist_itemsite_id 
+            FROM 
+                    cohist 
+            WHERE 
+                    cohist_itemsite_id = pItemsite_id
+            AND 
+                    cohist_ordernumber =  pCohist_ordernumber
+        ) x
+    WHERE
+        x.cohist_itemsite_id = pItemsite_id
+    AND
+        x.cohist_id = pCohist_id;
+
+    IF (_result IS NULL) THEN
+        RAISE EXCEPTION 'Can not found the result of cohist_pos(%, %, %)', pCohist_id, pCohist_ordernumber, pItemsite_id;
+    END IF;
+    
+    RETURN _result;
+END;
+
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION cohist_pos(INTEGER,TEXT,INTEGER)
+  OWNER TO admin;
+
diff --git a/pgsql/x-dragon-coitem-pos.sql b/pgsql/x-dragon-coitem-pos.sql
new file mode 100644 (file)
index 0000000..48bd0ad
--- /dev/null
@@ -0,0 +1,41 @@
+CREATE OR REPLACE FUNCTION coitem_pos(INTEGER,INTEGER,INTEGER)
+  RETURNS INTEGER AS
+$BODY$
+DECLARE
+  pCohead_id ALIAS FOR $1;
+  pCoitem_id ALIAS FOR $2;
+  pItemsite_id ALIAS FOR $3;
+  _result INTEGER;
+
+BEGIN
+    
+    SELECT
+        rn INTO _result
+    FROM
+        (
+            SELECT 
+                    row_number() OVER(ORDER BY coitem_id DESC) AS rn, coitem_itemsite_id, coitem_id
+            FROM 
+                    coitem
+            WHERE
+                    coitem_itemsite_id =   pItemsite_id
+            AND
+                    coitem_cohead_id = pCohead_id
+        ) x
+    WHERE
+        x.coitem_itemsite_id = pItemsite_id
+    AND
+        x.coitem_id = pCoitem_id;
+
+    IF (_result IS NULL) THEN
+        RAISE EXCEPTION 'Can not found the result of coitem_pos(%, %, %)', pCohead_id, pCoitem_id, pItemsite_id;
+    END IF;
+    
+    RETURN _result;
+END;
+
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION coitem_pos(INTEGER,INTEGER,INTEGER)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-deletesoitemcheck.sql b/pgsql/x-dragon-deletesoitemcheck.sql
new file mode 100644 (file)
index 0000000..4bc3801
--- /dev/null
@@ -0,0 +1,29 @@
+-- Function: deletesoitem(integer)
+
+-- DROP FUNCTION deletesoitem(integer);
+
+CREATE OR REPLACE FUNCTION deletesoitemcheck(integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pSoitemid    ALIAS FOR $1;
+
+  _result       INTEGER;
+
+BEGIN
+-- Get coitem
+    SELECT deletesoitem() as _result;
+    
+    IF (_result > -1) THEN
+        RAISE EXCEPTION 'Can be done';
+    END IF;
+   
+    RETURN _result;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION deletesoitemcheck(integer)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-delivery-note-changes.sql b/pgsql/x-dragon-delivery-note-changes.sql
new file mode 100644 (file)
index 0000000..097a77b
--- /dev/null
@@ -0,0 +1,12 @@
+
+ALTER TABLE shiphead ADD COLUMN shiphead_delivery_note TEXT;        
+
+CREATE INDEX shiphead_delivery_note_ix  ON shiphead   USING btree  (shiphead_delivery_note);
+
+ALTER TABLE recvgrp ADD COLUMN recvgrp_receipt_number TEXT;
+
+CREATE INDEX recvgrp_receipt_number_ix  ON recvgrp  USING btree  (recvgrp_receipt_number);
+
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_delivery_note TEXT;
+
+CREATE INDEX invhist_transfer_delivery_note_ix  ON invhist_transfer  USING btree  (invhist_transfer_delivery_note );
\ No newline at end of file
diff --git a/pgsql/x-dragon-dragon-report.sql b/pgsql/x-dragon-dragon-report.sql
new file mode 100644 (file)
index 0000000..edf6dcf
--- /dev/null
@@ -0,0 +1,38 @@
+--
+-- first go at dragon reports
+
+
+CREATE SEQUENCE dragon_report_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE recvgrp_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE dragon_report_id_seq TO admin;
+GRANT ALL ON TABLE dragon_report_id_seq TO xtrole;
+
+CREATE TABLE dragon_report
+(
+
+    id integer NOT NULL DEFAULT nextval(('dragon_report_id_seq'::text)::regclass),
+    name text NOT NULL,
+    query text,
+  
+
+  CONSTRAINT dragon_report_pkey PRIMARY KEY (id)
+)
+WITH (
+  OIDS=FALSE
+);
+
+
+ALTER TABLE dragon_report
+  OWNER TO admin;
+GRANT ALL ON TABLE dragon_report TO admin;
+GRANT ALL ON TABLE dragon_report TO xtrole;
+COMMENT ON TABLE dragon_report
+  IS 'first go at dragon reports';
+  
+  
\ No newline at end of file
diff --git a/pgsql/x-dragon-expense.sql b/pgsql/x-dragon-expense.sql
new file mode 100644 (file)
index 0000000..559cc56
--- /dev/null
@@ -0,0 +1,131 @@
+
+CREATE SEQUENCE expense_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE expense_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE expense_id_seq TO admin;
+GRANT ALL ON TABLE expense_id_seq TO xtrole;
+
+
+CREATE SEQUENCE expitem_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE expitem_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE expitem_id_seq TO admin;
+GRANT ALL ON TABLE expitem_id_seq TO xtrole;
+
+
+
+CREATE TABLE expense
+(
+    expense_id INTEGER NOT NULL DEFAULT nextval(('expense_id_seq'::text)::regclass),
+    
+    
+    expense_accnt_id INTEGER DEFAULT NULL,
+    expense_emp_id INTEGER NOT NULL,
+    
+    expense_number TEXT NOT NULL,
+    
+    expense_trandate date DEFAULT NULL,
+    expense_created date DEFAULT NULL,
+    expense_modified  date DEFAULT NULL,
+    expense_duedate date DEFAULT NULL,
+    
+    expense_memo  TEXT,
+    expense_comments  TEXT,
+    expense_status TEXT,
+    
+    expense_advance decimal(12,3) DEFAULT '0.000',
+    expense_amount decimal(12,3) DEFAULT '0.000',
+    
+    expense_tax decimal(12,3) DEFAULT '0.000',
+    expense_total decimal(12,3) DEFAULT '0.000',
+    expense_posted boolean default false,
+     
+    CONSTRAINT expense_accnt_id_fkey FOREIGN KEY (expense_accnt_id)
+        REFERENCES accnt (accnt_id)  MATCH SIMPLE,
+    CONSTRAINT expense_emp_id_fkey FOREIGN KEY (expense_emp_id)
+        REFERENCES emp (emp_id),
+    CONSTRAINT expense_id_pkey PRIMARY KEY (expense_id)
+)
+WITH (
+  OIDS=FALSE
+);
+
+ALTER TABLE expense
+  OWNER TO admin;
+  
+GRANT ALL ON TABLE expense TO admin;
+GRANT ALL ON TABLE expense TO xtrole;
+COMMENT ON TABLE expense
+  IS 'Expense Reports';
+ CREATE INDEX expense_number_ix  ON expense USING btree  (expense_number);
+ CREATE INDEX expense_date_ix  ON expense USING btree  (expense_trandate,expense_created, expense_modified, expense_duedate );
+
+
+CREATE TABLE expitem
+(
+  expitem_id INTEGER NOT NULL DEFAULT nextval(('expitem_id_seq'::text)::regclass),
+  
+  expitem_expense_id INTEGER NOT NULL,
+  expitem_curr_id INTEGER NOT NULL,
+  expitem_expcat_id INTEGER NOT NULL,
+
+  
+  expitem_row INTEGER NOT NULL,
+  
+  
+  expitem_amount decimal(12,3) DEFAULT '0.000',
+  expitem_amount_fc decimal(12,3) DEFAULT '0.000',
+  expitem_tax decimal(12,3) DEFAULT '0.000',
+  expitem_total decimal(12,3) DEFAULT '0.000',
+  --grossAmt decimal(12,3) DEFAULT '0.000',
+  -- expense cat?
+  
+  expitem_date date DEFAULT NULL,
+  --exchangeRate decimal(12,5) DEFAULT NULL,
+  
+  
+  expitem_is_billable INTEGER DEFAULT 0,
+  
+  expitem_memo text DEFAULT '',
+  
+  
+  -- tax code ???  
+  --receipt int(4) DEFAULT '0',
+    CONSTRAINT expitem_expense_id_fkey FOREIGN KEY (expitem_expense_id)
+        REFERENCES expense (expense_id),
+    
+    CONSTRAINT expitem_curr_id_fkey FOREIGN KEY (expitem_curr_id)
+        REFERENCES curr_symbol (curr_id),
+    
+    CONSTRAINT expitem_expcat_id_fkey FOREIGN KEY (expitem_expcat_id)
+        REFERENCES expcat (expcat_id),
+    
+    -- unique row / expid....
+        
+    CONSTRAINT expitem_id_pkey PRIMARY KEY (expitem_id)
+)
+WITH (
+  OIDS=FALSE
+);
+
+ALTER TABLE expitem
+  OWNER TO admin;
+  
+GRANT ALL ON TABLE expitem TO admin;
+GRANT ALL ON TABLE expitem TO xtrole;
+COMMENT ON TABLE expitem
+  IS 'Expense Report Items';
+
diff --git a/pgsql/x-dragon-fetchnextchecknumber.sql b/pgsql/x-dragon-fetchnextchecknumber.sql
new file mode 100644 (file)
index 0000000..60ef538
--- /dev/null
@@ -0,0 +1,59 @@
+-- Function: fetchnextchecknumber(integer)
+
+-- DROP FUNCTION fetchnextchecknumber(integer);
+
+CREATE OR REPLACE FUNCTION fetchnextchecknumber(integer)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pBankaccntid ALIAS FOR $1;
+  _nextChkNumber INTEGER;
+  v_existing INTEGER;
+
+BEGIN
+
+  SELECT
+        (to_char(LEAST(accnt_number::integer,999),'FM000')  || to_char(bankaccnt_nextchknum, 'FM000000'))::integer 
+        INTO
+          _nextChkNumber
+        FROM
+            bankaccnt
+        LEFT JOIN
+            accnt
+        ON
+            accnt_id = bankaccnt_accnt_id
+        WHERE
+            (bankaccnt_id=pBankaccntid);
+
+
+    SELECT
+            checkhead_id
+        INTO
+            v_existing
+        FROM
+            checkhead
+        WHERE 
+            checkhead_number = _nextChkNumber;
+            
+    IF FOUND THEN
+        RAISE EXCEPTION 'Check % already exists - please increase the check number', _nextChkNumber;
+    END IF;
+
+
+  UPDATE
+          bankaccnt
+        SET
+            bankaccnt_nextchknum = (bankaccnt_nextchknum + 1)
+        WHERE
+            (bankaccnt_id=pBankaccntid);
+
+  RETURN _nextChkNumber;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION fetchnextchecknumber(integer)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-fix-apopen.sql b/pgsql/x-dragon-fix-apopen.sql
new file mode 100644 (file)
index 0000000..46e7aea
--- /dev/null
@@ -0,0 +1,1148 @@
+
+
+CREATE OR REPLACE FUNCTION fix_apopen_postdate()
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    
+    
+BEGIN
+    
+    PERFORM
+            update_postdate(apapply_id, apopen.apopen_distdate+1)
+    FROM
+            apopen
+    LEFT OUTER JOIN 
+            apapply 
+    ON 
+            (
+                (apopen.apopen_id=apapply_target_apopen_id)
+                OR 
+                (apopen.apopen_id=apapply_source_apopen_id)
+            )
+    LEFT OUTER JOIN 
+            apopen target_ap
+    ON 
+            apapply_target_apopen_id = target_ap.apopen_id
+    
+    WHERE
+            apopen.apopen_distdate > apapply_postdate
+        AND
+            apopen.apopen_curr_id = target_ap.apopen_curr_id;
+
+    
+    PERFORM
+            update_closedate(apopen.apopen_id)
+    FROM
+            apopen
+    LEFT OUTER JOIN 
+            apapply 
+    ON 
+            (
+                (apopen.apopen_id=apapply_target_apopen_id)
+                OR 
+                (apopen.apopen_id=apapply_source_apopen_id)
+            )
+    LEFT OUTER JOIN 
+            apopen target_ap
+    ON 
+            apapply_target_apopen_id = target_ap.apopen_id
+    
+    WHERE
+            apopen.apopen_closedate IS NOT NULL
+        AND
+            apopen.apopen_distdate > apopen.apopen_closedate
+        AND
+            apopen.apopen_curr_id = target_ap.apopen_curr_id;
+
+    PERFORM
+            update_postdate(apapply_id, checkhead_checkdate)
+    FROM
+        checkhead
+    LEFT JOIN
+            apapply
+    ON
+            apapply_journalnumber = checkhead_journalnumber
+            AND
+            checkhead_id = apapply_checkhead_id
+    WHERE
+            apapply_postdate IS NOT NULL
+        AND
+            checkhead_checkdate > apapply_postdate
+        AND
+            checkhead_recip_type = 'V'
+        AND
+            NOT checkhead_void;
+    
+
+     RETURN 1;       
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fix_apopen_postdate()
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION fix_apopen_closedate()
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    
+    
+BEGIN
+    
+    
+    PERFORM
+            update_closedate(apopen_id)
+    FROM
+            apopen
+    LEFT OUTER JOIN 
+            apapply 
+    ON 
+            (
+                (apopen_id=apapply_target_apopen_id)
+                OR 
+                (apopen_id=apapply_source_apopen_id)
+            )
+   
+    WHERE
+            apopen_closedate IS NOT NULL
+        AND
+            apopen_closedate < apapply_postdate;
+
+    
+     RETURN 1;       
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fix_apopen_closedate()
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION update_postdate(i_apply_id INTEGER, i_date DATE)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_postdate DATE;
+    
+BEGIN
+    
+    SELECT
+            apapply_postdate
+    INTO
+            v_postdate
+    FROM
+            apapply
+    WHERE
+            apapply_id = i_apply_id;
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Cound not found the apapply, apapply_id = %', i_apply_id;
+    END IF;
+
+    
+    UPDATE
+            apapply
+    SET
+            apapply_postdate = i_date
+    WHERE
+            apapply_id = i_apply_id;
+        
+    RETURN i_apply_id;    
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION update_postdate(INTEGER, DATE)
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION update_closedate(i_apopen_id INTEGER)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_date DATE;
+    
+BEGIN
+    
+    SELECT
+            MAX(apapply_postdate)
+    INTO
+            v_date
+    FROM
+            apopen
+    LEFT OUTER JOIN 
+            apapply 
+    ON 
+            (
+                (apopen.apopen_id=apapply_target_apopen_id)
+                OR 
+                (apopen.apopen_id=apapply_source_apopen_id)
+            )
+    WHERE
+            apopen_id = i_apopen_id;
+
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Cound not found the max apapply date, apopen_id = %', i_apopen_id;
+    END IF; 
+
+    UPDATE
+            apopen
+    SET
+            apopen_closedate = v_date
+    WHERE
+            apopen_id = i_apopen_id;
+        
+    RETURN i_apopen_id;   
+    
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION update_closedate(INTEGER)
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION fix_apopen_balance_bydate(i_date DATE)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE    
+    v_amount NUMERIC;
+    v_sequence INTEGER;
+    v_ap_accnt_id INTEGER;
+    v_loss_accnt_id INTEGER;
+    v_result INTEGER;
+   
+    
+BEGIN
+    
+    SELECT 
+            apaccnt_ap_accnt_id 
+    INTO
+            v_ap_accnt_id
+    FROM 
+            apaccnt 
+    WHERE 
+            apaccnt_vendtype ='.*';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'AP account not found';
+    END IF;
+
+    SELECT 
+            accnt_id 
+    INTO
+            v_loss_accnt_id
+    FROM 
+            accnt 
+    WHERE 
+            accnt_descrip = 'Currency Gain Loss';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Currency Gain Loss account not found';
+    END IF;
+    
+    SELECT
+            COALESCE(SUM(ROUND(gltrans_amount,3)), 0)
+    INTO
+            v_amount
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_ap_accnt_id
+            AND
+            NOT gltrans_deleted
+            AND
+            gltrans_date <= i_date
+            AND
+            (
+                gltrans_docnumber LIKE 'NS-EOYJEFIX-%'
+                OR
+                gltrans_docnumber = 'CM Application'
+            );
+
+    
+    RAISE NOTICE 'Amount before % is %', i_date, v_amount;
+    
+    IF (v_amount = 0) THEN
+        RETURN -1;
+    END IF;
+
+    SELECT fetchGLSequence() INTO v_sequence;
+    
+    
+    SELECT insertIntoGLSeries( v_sequence,
+                               'G/L',
+                               'JE',
+                             'Balance-apopen-' || i_date,
+                              v_ap_accnt_id,
+                             round(v_amount, 3) * -1.0,
+                              i_date
+                            ) INTO v_result;
+    
+    IF (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    SELECT insertIntoGLSeries(
+                            v_sequence,
+                            'G/L',
+                            'JE',
+                            'Balance-apopen-' || i_date,
+                            v_loss_accnt_id,
+                            round(v_amount, 3),
+                            i_date
+                            ) INTO v_result;
+
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    UPDATE 
+        glseries
+    SET 
+        glseries_notes = 'Balance apopen before ' || i_date
+    WHERE 
+        (glseries_sequence = v_sequence);
+
+    SELECT postGLSeriesNoSumm(v_sequence,COALESCE(NULL,fetchJournalNumber('AP-CK'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed! glsequence = % result = %', v_sequence, v_result;
+    END IF;
+    
+    RETURN 1;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fix_apopen_balance_bydate(DATE)
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION fix_void_voucher_gltrans(i_docnumber TEXT)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_sequence INTEGER;
+    v_ap_accnt_id INTEGER;
+    v_loss_accnt_id INTEGER;
+    v_amount NUMERIC;
+    v_date DATE;
+    v_result INTEGER;
+    
+BEGIN
+    
+    SELECT 
+            apaccnt_ap_accnt_id 
+    INTO
+            v_ap_accnt_id
+    FROM 
+            apaccnt 
+    WHERE 
+            apaccnt_vendtype ='.*';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'AP account not found';
+    END IF;
+
+    SELECT 
+            accnt_id 
+    INTO
+            v_loss_accnt_id
+    FROM 
+            accnt 
+    WHERE 
+            accnt_descrip = 'Currency Gain Loss';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Currency Gain Loss account not found';
+    END IF;
+
+    SELECT
+            MAX(gltrans_date),
+            COALESCE(SUM(ROUND(gltrans_amount,3)),0)
+    INTO
+            v_date,
+            v_amount
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_ap_accnt_id
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_docnumber = i_docnumber;
+
+    RAISE NOTICE 'Amount of % is %', i_docnumber, v_amount;
+
+    IF (v_amount = 0) THEN
+        RETURN -1;
+    END IF;
+
+    SELECT fetchGLSequence() INTO v_sequence;
+    
+    
+    SELECT insertIntoGLSeries( v_sequence,
+                               'A/P',
+                               'VO',
+                             i_docnumber,
+                              v_ap_accnt_id,
+                             round(v_amount, 3) * -1.0,
+                              v_date
+                            ) INTO v_result;
+    
+    IF (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    SELECT insertIntoGLSeries(
+                            v_sequence,
+                            'A/P',
+                            'VO',
+                            i_docnumber,
+                            v_loss_accnt_id,
+                            round(v_amount, 3),
+                            v_date
+                            ) INTO v_result;
+
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    UPDATE 
+        glseries
+    SET 
+        glseries_notes = 'Void apopen ' || i_docnumber
+    WHERE 
+        (glseries_sequence = v_sequence);
+
+    SELECT postGLSeriesNoSumm(v_sequence,COALESCE(NULL,fetchJournalNumber('AP-CK'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed! glsequence = % result = %', v_sequence, v_result;
+    END IF;
+    
+    RETURN 1;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fix_void_voucher_gltrans(TEXT)
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION fix_currrate_issue(i_docnumber TEXT)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_sequence INTEGER;
+    v_ap_accnt_id INTEGER;
+    v_loss_accnt_id INTEGER;
+    v_amount NUMERIC;
+    v_date DATE;
+    v_result INTEGER;
+    
+BEGIN
+    
+    SELECT 
+            apaccnt_ap_accnt_id 
+    INTO
+            v_ap_accnt_id
+    FROM 
+            apaccnt 
+    WHERE 
+            apaccnt_vendtype ='.*';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'AP account not found';
+    END IF;
+
+    SELECT 
+            accnt_id 
+    INTO
+            v_loss_accnt_id
+    FROM 
+            accnt 
+    WHERE 
+            accnt_descrip = 'Currency Gain Loss';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Currency Gain Loss account not found';
+    END IF;
+
+    SELECT
+            MAX(gltrans_date),
+            COALESCE(SUM(ROUND(gltrans_amount,3)),0)
+    INTO
+            v_date,
+            v_amount
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_ap_accnt_id
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_docnumber = i_docnumber;
+
+    RAISE NOTICE 'Gltrans amount of % is %', i_docnumber, v_amount;
+
+    SELECT 
+            ROUND((v_amount - SUM(total_val)),3)
+    INTO
+            v_amount
+    FROM
+    (
+        SELECT 
+                ROUND(((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+                CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END),3) AS total_val
+        FROM
+                apopen
+
+        LEFT OUTER JOIN apapply ON (
+                                        (apopen.apopen_id=apapply_target_apopen_id)
+                                        OR 
+                                        (apopen.apopen_id=apapply_source_apopen_id)
+                                    )
+        LEFT OUTER JOIN apopen target_ap
+                    ON apapply_target_apopen_id = target_ap.apopen_id
+        WHERE
+                apopen.apopen_docnumber = i_docnumber
+
+        GROUP BY apopen.apopen_amount,apopen.apopen_paid,apopen.apopen_curr_rate,apopen.apopen_doctype
+    ) AS x;
+
+    RAISE NOTICE 'Currency rate difference of % is %', i_docnumber, v_amount;
+
+    IF (v_amount = 0) THEN
+        RETURN -1;
+    END IF;
+
+    SELECT fetchGLSequence() INTO v_sequence;
+    
+    
+    SELECT insertIntoGLSeries( v_sequence,
+                               'A/P',
+                               'VO',
+                             i_docnumber,
+                              v_ap_accnt_id,
+                             round(v_amount, 3) * -1.0,
+                              v_date
+                            ) INTO v_result;
+    
+    IF (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    SELECT insertIntoGLSeries(
+                            v_sequence,
+                            'A/P',
+                            'VO',
+                            i_docnumber,
+                            v_loss_accnt_id,
+                            round(v_amount, 3),
+                            v_date
+                            ) INTO v_result;
+
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries Failed';
+    END IF;
+
+    UPDATE 
+        glseries
+    SET 
+        glseries_notes = 'Fix currency rate issue ' || i_docnumber
+    WHERE 
+        (glseries_sequence = v_sequence);
+
+    SELECT postGLSeriesNoSumm(v_sequence,COALESCE(NULL,fetchJournalNumber('AP-CK'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed! glsequence = % result = %', v_sequence, v_result;
+    END IF;
+    
+    RETURN 1;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fix_currrate_issue(TEXT)
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION apopen_amount_cals(i_docnumber TEXT, i_date DATE)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    v_amount NUMERIC;
+    
+BEGIN
+    
+    v_amount := 0;
+    SELECT
+            SUM(total)
+    INTO
+            v_amount
+    FROM
+    (
+        SELECT
+                COALESCE(((apopen.apopen_amount-apopen.apopen_paid+COALESCE(SUM( (apapply_target_paid *  apopen.apopen_curr_rate) /   target_ap.apopen_curr_rate  ),0))/apopen.apopen_curr_rate *
+                CASE WHEN (apopen.apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END),0) AS total
+        FROM 
+                apopen
+        LEFT OUTER JOIN apapply ON (((apopen.apopen_id=apapply_target_apopen_id)
+                                    OR (apopen.apopen_id=apapply_source_apopen_id))
+                                   AND (apapply_postdate >=i_date))
+        LEFT OUTER JOIN apopen target_ap
+            ON apapply_target_apopen_id = target_ap.apopen_id
+
+        WHERE  
+            apopen.apopen_distdate <= i_date
+        AND 
+            (COALESCE(apopen.apopen_closedate,i_date)>=i_date) 
+
+        AND
+            apopen.apopen_docnumber = i_docnumber
+
+        GROUP BY apopen.apopen_doctype,apopen.apopen_paid,
+                 apopen.apopen_amount,apopen.apopen_curr_rate
+    ) AS x;
+
+    RETURN v_amount;
+   
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION apopen_amount_cals(TEXT, DATE)
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION checkhead_amount_cals(i_number TEXT, i_date DATE)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    v_amount NUMERIC;
+    v_checkhead_id INTEGER;
+    
+BEGIN
+    
+    v_amount := 0;
+    
+    IF (FALSE = ((SELECT strpos(i_number, '::')) > 0)) THEN
+        SELECT
+                checkhead_id
+        INTO
+                v_checkhead_id
+        FROM
+                checkhead
+        WHERE
+                checkhead_number = i_number::INTEGER;
+        
+        IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'Could not found check number = %', i_number;
+        END IF;
+
+    ELSE
+
+        SELECT split_part(i_number, '::', 2) INTO v_checkhead_id;
+
+    END IF;
+
+    SELECT 
+            SUM(total)
+    INTO
+            v_amount
+    FROM
+    (
+        
+        SELECT
+                checkhead_number,
+                CASE WHEN checkhead_void THEN
+                    checkhead_amount / checkhead_curr_rate * -1
+                ELSE
+                    apapply_target_paid / apopen_curr_rate * -1
+                END AS total,
+
+        FROM
+                checkhead
+        LEFT JOIN
+                apapply
+        ON
+                apapply_journalnumber = checkhead_journalnumber
+            AND
+                checkhead_id = apapply_checkhead_id
+        LEFT JOIN
+                    apopen
+        ON
+                    apopen_id = apapply_target_apopen_id
+
+        WHERE 
+                checkhead_recip_type = 'V'
+            AND
+                (
+                    (NOT checkhead_void AND apapply_postdate >= i_date)
+                    OR
+                    (checkhead_void AND checkhead_voided > i_date)
+                )  
+
+            AND
+                checkhead_checkdate <= i_date
+
+            AND
+                checkhead_id = v_checkhead_id
+        
+    ) AS x;
+
+    RETURN v_amount;
+   
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION checkhead_amount_cals(TEXT, DATE)
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION gltrans_amount_cals(i_number TEXT, i_accnt_id INTEGER, i_date DATE)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    v_amount NUMERIC;
+    
+BEGIN
+    
+    v_amount := 0;
+    
+    IF (FALSE = ((SELECT strpos(i_number, '::')) > 0)) THEN
+        SELECT
+                SUM(COALESCE(gltrans_amount,0))
+        INTO
+                v_amount
+        FROM
+                gltrans
+        WHERE
+            gltrans_accnt_id = i_accnt_id
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_date <= i_date
+        AND
+            gltrans_docnumber = i_number::TEXT;
+        
+        RETURN v_amount;
+
+    END IF;
+
+    SELECT
+            SUM(COALESCE(gltrans_amount,0))
+    INTO
+            v_amount
+    FROM
+            gltrans
+    WHERE
+        gltrans_accnt_id = i_accnt_id
+    AND
+        NOT gltrans_deleted
+    AND
+        gltrans_date <= i_date
+    AND
+        gltrans_docnumber = (SELECT split_part(i_number, '::', 1))::TEXT
+    AND
+        gltrans_misc_id = (SELECT split_part(i_number, '::', 2))::INTEGER;
+
+    RETURN v_amount;
+
+     
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION gltrans_amount_cals(TEXT, INTEGER, DATE)
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION apopen_compare(i_docnumber TEXT, i_date DATE)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    v_related TEXT[];
+    v_ap_accnt_id INTEGER;
+    v_amount NUMERIC;
+    v_glamount NUMERIC;
+    v_count INTEGER;
+BEGIN
+    
+    
+    v_amount := 0;
+    v_glamount := 0;
+
+    SELECT 
+            apaccnt_ap_accnt_id 
+    INTO
+            v_ap_accnt_id
+    FROM 
+            apaccnt 
+    WHERE 
+            apaccnt_vendtype ='.*';
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'AP account not found';
+    END IF;
+    
+    IF (FALSE = ((SELECT strpos(i_docnumber, '::')) > 0)) THEN
+        SELECT apopen_related(i_docnumber, ARRAY[]::TEXT[]) INTO v_related;
+    ELSE
+        SELECT checkhead_related(i_docnumber, ARRAY[]::TEXT[]) INTO v_related;
+    END IF;
+
+    
+
+--     RAISE NOTICE 'v_related = % array_upper = %', v_related, array_upper(v_related,1);
+
+    FOR i IN 1 .. array_upper(v_related,1) LOOP
+--         RAISE NOTICE 'docnumber = %', v_related[i]; 
+        SELECT
+                COUNT(apopen_id)
+        INTO
+                v_count
+        FROM
+                apopen
+        WHERE
+                apopen_docnumber = v_related[i]::TEXT;
+
+        IF v_count > 0 THEN
+            SELECT v_amount + COALESCE(apopen_amount_cals(v_related[i]::TEXT, i_date),0) - COALESCE(gltrans_amount_cals(v_related[i]::TEXT, v_ap_accnt_id, i_date),0) INTO v_amount;
+            
+                
+        ELSE   
+            SELECT v_amount + COALESCE(checkhead_amount_cals(v_related[i]::TEXT, i_date),0) - COALESCE(gltrans_amount_cals(v_related[i]::TEXT, v_ap_accnt_id, i_date),0) INTO v_amount;
+
+        END IF;
+
+    END LOOP;
+    
+--     RAISE NOTICE 'v_amount = %', v_amount;
+
+
+    RETURN v_amount;
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION apopen_compare(TEXT, DATE)
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION apopen_related(i_docnumber TEXT, i_related TEXT[])
+    RETURNS  TEXT[]
+    
+AS $BODY$
+DECLARE   
+    _r RECORD;
+BEGIN
+    
+    IF (NOT ARRAY[i_docnumber] <@ i_related) THEN
+        SELECT array_append(i_related, i_docnumber) INTO i_related;
+    END IF;
+    
+--     RAISE NOTICE 'i_related = % ', i_related;
+
+    FOR _r IN SELECT
+            apapply_source_docnumber,
+            apapply_target_docnumber,
+            apapply_checkhead_id
+
+    FROM 
+            apopen
+    LEFT OUTER JOIN apapply ON (
+                                    (apopen.apopen_id=apapply_target_apopen_id)
+                                OR 
+                                    (apopen.apopen_id=apapply_source_apopen_id)
+                                )
+                               
+
+    WHERE  
+            apopen_docnumber = i_docnumber LOOP
+        
+        IF (_r.apapply_checkhead_id IS NOT NULL) THEN
+            _r.apapply_source_docnumber = _r.apapply_source_docnumber || '::' || _r.apapply_checkhead_id;
+        END IF;
+
+        IF (_r.apapply_source_docnumber IS NOT NULL AND NOT ARRAY[_r.apapply_source_docnumber] <@ i_related) THEN
+            IF _r.apapply_checkhead_id IS NULL THEN
+                SELECT apopen_related(_r.apapply_source_docnumber, i_related) INTO i_related;
+                
+            ELSE
+                SELECT checkhead_related(_r.apapply_source_docnumber, i_related) INTO i_related;
+            
+            END IF;
+
+        END IF;
+
+        IF (_r.apapply_target_docnumber IS NOT NULL AND NOT ARRAY[_r.apapply_target_docnumber] <@ i_related) THEN
+            
+            SELECT apopen_related(_r.apapply_target_docnumber, i_related) INTO i_related;
+
+        END IF;
+        
+    END LOOP;
+
+    
+    RETURN i_related;
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION apopen_related(TEXT, TEXT[])
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION checkhead_related(i_number TEXT, i_related TEXT[])
+    RETURNS  TEXT[]
+    
+AS $BODY$
+DECLARE   
+    _r RECORD;
+    v_checkhead_id INTEGER;
+BEGIN
+    
+    IF (NOT ARRAY[i_number]::TEXT[] <@ i_related) THEN
+        SELECT array_append(i_related, i_number::TEXT) INTO i_related;
+    END IF;
+
+
+    SELECT split_part(i_number, '::', 2) INTO v_checkhead_id;
+
+    
+
+    FOR _r IN SELECT
+            apapply_target_docnumber
+    FROM
+            checkitem
+    LEFT JOIN
+            checkhead
+    ON
+            checkitem_checkhead_id = checkhead_id
+    LEFT JOIN
+            apapply
+    ON
+            apapply_journalnumber = checkhead_journalnumber
+        AND
+            checkhead_id = apapply_checkhead_id
+
+    WHERE 
+            checkhead_recip_type = 'V'
+        AND
+            NOT checkhead_void
+
+        AND
+            checkitem_apopen_id IS NOT NULL
+        AND
+            checkhead_id = v_checkhead_id LOOP
+            
+            
+        IF (_r.apapply_target_docnumber IS NOT NULL AND NOT ARRAY[_r.apapply_target_docnumber] <@ i_related) THEN
+            SELECT apopen_related(_r.apapply_target_docnumber, i_related) INTO i_related;
+
+        END IF;
+
+
+
+
+    END LOOP;
+       
+    RETURN i_related;
+  
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION checkhead_related(TEXT, TEXT[])
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION fetch_apopen_error(i_date DATE)
+    RETURNS  TEXT[]
+    
+AS $BODY$
+DECLARE        
+    v_related TEXT[];
+    v_result TEXT[];
+    _r RECORD;
+    v_amount NUMERIC;
+    v_number TEXT;
+BEGIN
+    v_related:= ARRAY[]::TEXT[];
+    v_result:= ARRAY[]::TEXT[];
+    v_amount := 0;
+
+    FOR _r IN SELECT
+                        apopen_docnumber,
+                        apopen_doctype,
+                        ap_checkhead_id
+                FROM 
+                (
+                    SELECT
+                            apopen.apopen_docnumber,
+                            apopen.apopen_doctype,
+                            apopen.apopen_id::text AS apopen_id,
+                            -1 AS ap_checkhead_id
+
+                    FROM apopen
+                      LEFT OUTER JOIN apapply ON (((apopen.apopen_id=apapply_target_apopen_id)
+                                                OR (apopen.apopen_id=apapply_source_apopen_id))
+                                               )
+                      LEFT OUTER JOIN apopen target_ap
+                        ON apapply_target_apopen_id = target_ap.apopen_id
+
+                    WHERE ( 
+                    apopen.apopen_docnumber NOT IN (
+                                                SELECT 
+                                                        apopen_docnumber
+                                                FROM
+                                                        apopen
+                                                WHERE
+                                                        apopen_notes LIKE 'Void Voucher%'
+                                                    AND
+                                                        apopen_discount
+                                            )
+
+                    )
+                  
+                    UNION
+
+                    SELECT
+                            checkhead_number::text AS apopen_docnumber,
+                            'CK' AS apopen_doctype,
+                             checkitem_id::text AS apopen_id,
+                             COALESCE(apapply_checkhead_id, -1) AS ap_checkhead_id
+
+                    FROM
+                               checkitem
+                           LEFT JOIN
+                               checkhead
+                           ON
+                               checkitem_checkhead_id = checkhead_id
+                            LEFT JOIN
+                               apapply
+                           ON
+                               apapply_journalnumber = checkhead_journalnumber
+                               AND
+                               checkhead_id = apapply_checkhead_id
+
+                          LEFT JOIN
+                              vendinfo
+                              ON
+                               checkhead_recip_id = vend_id
+
+                          LEFT JOIN
+                               vendtype 
+                          ON
+                              vend_vendtype_id=vendtype_id
+
+                       WHERE 
+                              checkhead_recip_type = 'V'
+                        --   AND NOT checkhead_deleted  
+                           AND
+                              NOT checkhead_void
+
+                           AND
+                              checkitem_apopen_id IS NOT NULL
+
+                ) AS x LOOP
+            
+            v_number = _r.apopen_docnumber;
+            
+            IF (_r.apopen_doctype = 'CK') THEN
+                v_number = _r.apopen_docnumber || '::' || _r.ap_checkhead_id;
+            END IF;
+
+
+            IF (NOT ARRAY[v_number]::TEXT[] <@ v_related) THEN
+
+                IF (FALSE = ((SELECT strpos(v_number, '::')) > 0)) THEN
+                    SELECT apopen_related(v_number, v_related) INTO v_related;
+                ELSE
+                    SELECT checkhead_related(v_number, v_related) INTO v_related;
+                END IF;
+
+                SELECT apopen_compare(v_number, i_date) INTO v_amount;
+                IF (ABS(v_amount) > 1) THEN
+                    RAISE NOTICE 'Error docnumber : %, amount : %', v_number, v_amount;
+                    SELECT array_append(v_result, v_number::TEXT) INTO v_result;
+                    
+                END IF;
+            END IF;
+
+    END LOOP;
+
+    RETURN v_result;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION fetch_apopen_error(DATE)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-dragon-fix-cobmisc-discount.sql b/pgsql/x-dragon-fix-cobmisc-discount.sql
new file mode 100644 (file)
index 0000000..b71f7b7
--- /dev/null
@@ -0,0 +1,146 @@
+-- 
+-- CREATE OR REPLACE FUNCTION fix_cobmisc_discount_all()
+--     RETURNS  INTEGER
+--     
+-- AS $BODY$
+-- DECLARE        
+--     
+--     
+-- BEGIN
+--       
+-- 
+-- 
+-- END;
+-- $BODY$
+--   LANGUAGE plpgsql VOLATILE
+--   COST 100;
+--   
+-- ALTER FUNCTION fix_cobmisc_discount_all()
+--   OWNER TO admin;
+-- 
+-- 
+-- 
+-- 
+-- CREATE OR REPLACE FUNCTION fix_cobmisc_discount(i_cohead_id INTEGER)
+--     RETURNS  TEXT
+--     
+-- AS $BODY$
+-- DECLARE        
+--     v_cohead_number TEXT;
+--     v_cohead_pretax_discount NUMERIC;
+--     v_cohead_posttax_discount NUMERIC;
+--     v_cohead_discount NUMERIC;
+--     v_cobmisc_id INTEGER;
+--     v_cobmisc_misc NUMERIC;
+--     v_invchead_invcnumber INTEGER;
+-- BEGIN
+--         SELECT
+--                 cohead_number,
+--                 COALESCE(cohead_pretax_discount, 0),
+--                 COALESCE(cohead_posttax_discount, 0)
+--         INTO
+--                 v_cohead_number,
+--                 v_cohead_pretax_discount,
+--                 v_cohead_posttax_discount
+--         FROM  
+--                 cohead
+--         WHERE
+--                 cohead_id = i_cohead_id;
+-- 
+--         IF (NOT FOUND) THEN
+--             RAISE EXCEPTION 'Could not found sales order, i_cohead_id = %', i_cohead_id;
+--         END IF;
+-- 
+--         SELECT
+--                 COALESCE(SUM(
+--                             ROUND( coitem_custprice * coitem_qtyord, 2)
+--                             -
+--                             ROUND (coitem_price * coitem_qtyord,2)
+--                         ), 0) * -1
+--         INTO
+--                 v_cohead_discount
+--         FROM
+--                 coitem
+--         WHERE
+--                 coitem_cohead_id = i_cohead_id
+--                 AND
+--                 coitem_custprice > coitem_price
+--                 AND
+--                 coitem_itemsite_id != (
+--                                         SELECT
+--                                                 itemsite_id
+--                                         FROM
+--                                                 itemsite
+--                                         LEFT JOIN
+--                                                 item
+--                                         ON
+--                                                 itemsite_item_id = item_id
+--                                         WHERE
+--                                                 item_number = 'Z-LIST-DISCOUNT'
+--                                       );
+-- 
+--         IF (v_cohead_discount <> v_cohead_pretax_discount) THEN
+--             RAISE NOTICE 'Pretax discount not correct! v_cohead_number = %, v_cohead_pretax_discount = %, v_cohead_discount = %', v_cohead_number, v_cohead_pretax_discount, v_cohead_discount;
+--             UPDATE
+--                     cohead
+--             SET
+--                     cohead_pretax_discount = v_cohead_discount
+--             WHERE
+--                     cohead_id = i_cohead_id;
+--         END IF;
+-- 
+--         SELECT
+--                 cobmisc_id,
+--                 cobmisc_invcnumber,
+--                 cobmisc_misc
+--         INTO
+--                 v_cobmisc_id,
+--                 v_invchead_invcnumber,
+--                 v_cobmisc_misc
+--         FROM
+--                 cobmisc
+--         WHERE
+--                 cobmisc_cohead_id = i_cohead_id
+--                 AND
+--                 cobmisc_posted;
+-- 
+--         IF (v_cobmisc_id IS NULL) THEN
+--             RETURN 'Skip - no cobmisc';
+--         END IF;
+-- 
+--         IF (v_cobmisc_misc = (v_cohead_discount + v_cohead_posttax_discount)) THEN
+--             RETURN 'Skip - discount value correct!';
+--         END IF;
+-- 
+--         UPDATE
+--                 cobmisc
+--         SET
+--                 cobmisc_misc = (v_cohead_discount + v_cohead_posttax_discount)
+--         WHERE
+--                 cobmisc_id = v_cobmisc_id
+--                 AND
+--                 cobmisc_posted;
+-- 
+--        
+--         UPDATE
+--                 invchead
+--         SET
+--                 invchead_misc_amount = (v_cohead_discount + v_cohead_posttax_discount)
+--         WHERE
+--                 invchead_invcnumber = v_invchead_invcnumber
+--             AND 
+--                 invchead_posted
+--             AND
+--                 NOT invchead_void;
+--                 
+--                 
+-- 
+-- 
+-- 
+-- END;
+-- $BODY$
+--   LANGUAGE plpgsql VOLATILE
+--   COST 100;
+--   
+-- ALTER FUNCTION fix_cobmisc_discount(INTEGER)
+--   OWNER TO admin;
diff --git a/pgsql/x-dragon-gl-precision.sql b/pgsql/x-dragon-gl-precision.sql
new file mode 100644 (file)
index 0000000..8768df8
--- /dev/null
@@ -0,0 +1,46 @@
+-- not wide enough?
+
+
+-- this was a mistake!!! - we should never had made gl 3 decimal places - it makes a nightmare everywhere..
+
+alter table glseries alter column glseries_amount  TYPE numeric(12,2);
+ --View: api.journalentry
+
+DROP VIEW api.journalentry;
+   alter table gltrans alter column gltrans_amount  TYPE numeric(12,2);
+
+CREATE OR REPLACE VIEW api.journalentry AS 
+ SELECT curr_symbol.curr_abbr AS currency, c.gltrans_amount AS amount, c.gltrans_date AS dist_date, c.gltrans_docnumber AS doc_number, formatglaccount(da.accnt_id) AS debit, formatglaccount(ca.accnt_id) AS credit, c.gltrans_notes AS notes
+   FROM gltrans d, gltrans c, accnt da, accnt ca, curr_symbol
+  WHERE d.gltrans_sequence = c.gltrans_sequence AND d.gltrans_accnt_id = da.accnt_id AND c.gltrans_accnt_id = ca.accnt_id AND d.gltrans_amount < 0::numeric AND c.gltrans_amount > 0::numeric AND d.gltrans_doctype = 'JE'::text AND c.gltrans_doctype = 'JE'::text AND curr_symbol.curr_id = basecurrid()
+  ORDER BY d.gltrans_date DESC;
+
+ALTER TABLE api.journalentry
+  OWNER TO admin;
+GRANT ALL ON TABLE api.journalentry TO admin;
+GRANT ALL ON TABLE api.journalentry TO xtrole;
+COMMENT ON VIEW api.journalentry
+  IS 'Journal Entry';
+
+
+-- Rule: "_DELETE" ON api.journalentry
+
+-- DROP RULE "_DELETE" ON api.journalentry;
+
+CREATE OR REPLACE RULE "_DELETE" AS
+    ON DELETE TO api.journalentry DO INSTEAD NOTHING;
+
+-- Rule: "_INSERT" ON api.journalentry
+
+-- DROP RULE "_INSERT" ON api.journalentry;
+
+CREATE OR REPLACE RULE "_INSERT" AS
+    ON INSERT TO api.journalentry DO INSTEAD  SELECT insertgltransaction('G/L'::text, 'JE'::text, new.doc_number, new.notes, getglaccntid(new.credit), getglaccntid(new.debit), (-1), currtobase(getcurrid(new.currency::text), new.amount, new.dist_date), new.dist_date) AS insertgltransaction;
+
+-- Rule: "_UPDATE" ON api.journalentry
+
+-- DROP RULE "_UPDATE" ON api.journalentry;
+
+CREATE OR REPLACE RULE "_UPDATE" AS
+    ON UPDATE TO api.journalentry DO INSTEAD NOTHING;
+--
diff --git a/pgsql/x-dragon-invadj.sql b/pgsql/x-dragon-invadj.sql
new file mode 100644 (file)
index 0000000..76e24f8
--- /dev/null
@@ -0,0 +1,347 @@
+-- Sequence: accnt_accnt_id_seq
+
+--DROP table invadj;
+
+CREATE SEQUENCE invadj_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE invadj_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE invadj_id_seq TO admin;
+GRANT ALL ON TABLE invadj_id_seq TO xtrole;
+
+
+CREATE TABLE invadj
+(
+  invadj_id integer NOT NULL DEFAULT nextval(('invadj_id_seq'::text)::regclass),
+  invadj_transdate  date,
+  invadj_location_id integer,
+  invadj_itemsite_id integer,
+  invadj_qty_by integer,
+  invadj_posted boolean,
+  
+    CONSTRAINT invadj_pkey PRIMARY KEY (invadj_id ),
+    CONSTRAINT invadj_location_fkey FOREIGN KEY (invadj_location_id)
+        REFERENCES location (location_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION,
+      
+    CONSTRAINT invadj_itemsite_fkey FOREIGN KEY (invadj_itemsite_id)
+      REFERENCES itemsite (itemsite_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+
+ALTER TABLE invadj ADD COLUMN   invadj_comments text;
+ALTER TABLE invadj ADD COLUMN   invadj_voids_id INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE invadj ADD COLUMN   invadj_invdetail_id INTEGER;
+ALTER TABLE invadj ADD COLUMN   invadj_voided_by_id INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE invadj ADD COLUMN   invadj_invadjgrp_id INTEGER DEFAULT NULL;
+
+CREATE INDEX invadj_location_id_ix  ON invadj  USING btree  (invadj_location_id);
+CREATE INDEX invadj_transdate_ix  ON invadj  USING btree  (invadj_transdate);
+CREATE INDEX invadj_itemsite_ix  ON invadj  USING btree  (invadj_itemsite_id);
+CREATE INDEX invadj_posted_ix  ON invadj USING btree  (invadj_posted);
+
+CREATE INDEX invadj_voided_by_id_ix  ON invadj USING btree  (invadj_voided_by_id);
+CREATE INDEX invadj_invdetail_id_ix  ON invadj USING btree  (invadj_invdetail_id);
+CREATE INDEX invadj_voids_id_ix  ON invadj USING btree  (invadj_voids_id);
+
+CREATE INDEX invadj_invadjgrp_id_ix  ON invadj USING btree  (invadj_invadjgrp_id);
+
+
+ALTER TABLE invadj
+  OWNER TO admin;
+GRANT ALL ON TABLE invadj TO admin;
+GRANT ALL ON TABLE invadj TO xtrole;
+COMMENT ON TABLE invadj
+  IS 'Inventory Adjustment Draft';
+  
+  
+  
+  
+
+
+-- create dummy itemlocs
+
+CREATE OR REPLACE FUNCTION invadj_sync_invdetail(int)
+  RETURNS  int  AS
+$BODY$
+DECLARE
+  
+  i_invdetail_id ALIAS FOR $1;
+
+  r_invfifo RECORD;
+  v_id INTEGER;
+   
+    
+BEGIN
+
+    SELECT
+            *
+        INTO
+            r_invfifo
+        FROM
+            invdetailview
+        WHERE
+            invdetail_id = i_invdetail_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find invdetail record';
+    END IF;
+    
+    IF r_invfifo.invhist_transtype != 'AD' THEN
+        RAISE EXCEPTION 'record is not an adjustment';
+    END IF;
+    
+    SELECT
+            invadj_id
+        INTO
+            v_id
+        FROM
+            invadj
+        WHERE
+            invadj_invdetail_id = r_invfifo.invdetail_id;
+            
+    IF FOUND THEN
+        RETURN v_id;
+    END IF;
+    
+    INSERT INTO
+        invadj
+        (
+            
+            invadj_transdate  , invadj_location_id ,
+            invadj_itemsite_id , invadj_qty_by ,
+            
+            invadj_posted , invadj_comments,
+            invadj_voids_id, invadj_invdetail_id,
+            invadj_voided_by_id
+        )
+            VALUES
+        (
+            r_invfifo.invhist_transdate::date, r_invfifo.invdetail_location_id,
+            r_invfifo.invhist_itemsite_id, r_invfifo.invdetail_qty,
+            
+            true, r_invfifo.invhist_ordnumber || '/' || r_invfifo.invhist_ordnumber  || ' : '|| r_invfifo.invhist_comments,
+            0, r_invfifo.invdetail_id,
+            0
+            
+        );
+        
+    SELECT
+            invadj_id
+        INTO
+            v_id
+        FROM
+            invadj
+        WHERE
+            invadj_invdetail_id = r_invfifo.invdetail_id;
+          
+
+   RETURN v_id;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invadj_sync_invdetail(int)
+  OWNER TO admin;
+
+
+  
+-- create dummy itemlocs
+
+CREATE OR REPLACE FUNCTION invadj_post(int)
+  RETURNS  INTEGER  AS
+$BODY$
+DECLARE
+  
+    i_invadj_id ALIAS FOR $1;
+
+    r_invadj RECORD;
+    r_dist RECORD;
+    
+    v_invdetail_id INTEGER;
+  
+    v_series INTEGER;
+    v_result INTEGER;
+    v_result_bool BOOLEAN;
+BEGIN
+  
+  
+    SELECT
+            *
+        INTO
+            r_invadj
+        FROM
+            invadj
+        WHERE
+            invadj_id = i_invadj_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find invadj record';
+    END IF;
+    
+    IF r_invadj.invadj_posted  THEN
+        RAISE EXCEPTION 'invadj already posted';
+    END IF;
+  
+  
+    IF   r_invadj.invadj_voids_id > 0 THEN 
+        
+        SELECT
+                invadj_voided_by_id
+            INTO
+                v_result
+            FROM
+                invadj
+            WHERE
+                invadj_id = r_invadj.invadj_voids_id;
+                
+                
+                
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'voids id is invalid';
+        END IF;
+        IF v_result > 0 THEN
+            RAISE EXCEPTION 'voids id points to an already voided record';
+        END IF;
+            
+    END IF;
+  
+  
+    SELECT invAdjustment(
+                    r_invadj.invadj_itemsite_id,
+                    r_invadj.invadj_qty_by,
+                    'INVADJ-' || r_invadj.invadj_id,
+                    r_invadj.invadj_comments,
+                    r_invadj.invadj_transdate
+                    -- uses std cost?
+                ) INTO v_series;
+            
+    IF v_series < 1 THEN
+        RAISE EXCEPTION  'invAdjustment post failed';
+    END IF;
+        
+    SELECT
+                itemlocdist_id, itemlocdist_reqlotserial,
+                itemlocdist_distlotserial, itemlocdist_qty,
+                
+                itemsite_loccntrl, itemsite_controlmethod,
+                itemsite_perishable, itemsite_warrpurc,
+                
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+            INTO
+                r_dist
+            FROM
+                itemlocdist, itemsite
+            WHERE
+                (
+                    (itemlocdist_itemsite_id=itemsite_id) AND (itemlocdist_series=v_series )
+                )
+            ORDER BY itemlocdist_id;
+            
+            
+    IF NOT FOUND THEN
+         RAISE EXCEPTION 'invAdjustment failed to create itemlocdist';
+    END IF;
+        
+        
+        
+    INSERT INTO itemlocdist (
+       itemlocdist_itemlocdist_id,  itemlocdist_source_type,
+       itemlocdist_source_id,  itemlocdist_qty,
+       itemlocdist_ls_id, itemlocdist_expiration
+   )
+       SELECT
+       itemlocdist_id,       'L',
+       r_invadj.invadj_location_id,       r_invadj.invadj_qty_by,
+       itemlocdist_ls_id, endOfTime()
+       FROM itemlocdist WHERE (itemlocdist_id=r_dist.itemlocdist_id);
+
+        
+    SELECT distributeToLocations(r_dist.itemlocdist_id) INTO v_result;
+    
+    IF NOT FOUND OR v_result < 0 THEN
+        RAISE EXCEPTION 'distributeToLocations failed  ';
+    END IF;
+          
+    
+    SELECT postItemlocseries(v_series) INTO v_result_bool ;
+    
+    IF NOT v_result_bool  THEN
+        RAISE EXCEPTION 'postItemlocseries failed  ';
+    END IF;
+        
+    -- finally - if the record was a void - make refernce in the voided data..    
+    IF  r_invadj.invadj_voids_id > 0 THEN
+    
+        UPDATE invadj SET
+            invadj_voided_by_id = r_invadj.invadj_id
+            WHERE
+            invadj_id = r_invadj.invadj_voids_id ;
+            
+            
+    END IF;
+  
+    SELECT
+            invdetail_id
+        INTO
+            v_invdetail_id
+        FROM
+            invdetailview
+        WHERE
+            invhist_ordnumber = 'INVADJ-' || r_invadj.invadj_id
+        LIMIT 1;
+    
+  
+    UPDATE invadj SET
+            invadj_posted = true,
+            invadj_invdetail_id = v_invdetail_id
+            WHERE
+            
+            invadj_id = r_invadj.invadj_id;
+  
+    
+    
+    
+    -- we need to update the invhist id..
+    
+    IF  r_invadj.invadj_voids_id > 0 OR  r_invadj.invadj_voided_by_id > 0  THEN
+        -- try running the void flag code.
+        PERFORM invfifo_invadj_void_flag(v_invdetail_id);
+    END IF;
+    
+    
+    
+   RETURN v_result;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invadj_post(int)
+  OWNER TO admin;
+
+
+
+-- sync:
+--DELETE FROM invadj;
+--SELECT invadj_sync_invdetail(invdetail_id) FROM invdetailview where invhist_transtype = 'AD' ORDER BY invhist_transdate ASC;
+
+
+--- FIX the fact i forgot to update invdetail id..
+
+--UPDATE invadj
+--    SET invadj_invdetail_id = (SELECT invdetail_id FROM invdetailview WHERE invhist_ordnumber = 'INVADJ-' || invadj_id LIMIT 1)
+--    WHERE invadj_posted  and invadj_invdetail_id IS NULL;
+--
+--
+
diff --git a/pgsql/x-dragon-invadjgrp.sql b/pgsql/x-dragon-invadjgrp.sql
new file mode 100644 (file)
index 0000000..e680672
--- /dev/null
@@ -0,0 +1,54 @@
+
+CREATE SEQUENCE invadjgrp_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE invadjgrp_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE invadjgrp_id_seq TO admin;
+GRANT ALL ON TABLE invadjgrp_id_seq TO xtrole;
+
+
+
+---- CREATE TABEL invadjgrp -------
+CREATE TABLE invadjgrp
+(
+  invadjgrp_id integer NOT NULL DEFAULT nextval(('invadjgrp_id_seq'::text)::regclass),
+  invadjgrp_name  TEXT,
+  invadjgrp_transdate  date,
+  invadjgrp_location_id integer,
+  invadjgrp_posted boolean,
+  invadjgrp_comments TEXT,
+  
+    CONSTRAINT invadjgrp_pkey PRIMARY KEY (invadjgrp_id ),
+
+    CONSTRAINT invadjgrp_location_fkey FOREIGN KEY (invadjgrp_location_id)
+        REFERENCES location (location_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+
+
+ALTER TABLE invadjgrp
+  OWNER TO admin;
+GRANT ALL ON TABLE invadjgrp TO admin;
+GRANT ALL ON TABLE invadjgrp TO xtrole;
+COMMENT ON TABLE invadjgrp
+  IS 'Inventory Adjustment Group';
+
+
+CREATE INDEX invadjgrp_name_ix  ON invadjgrp  USING btree  (invadjgrp_name);
+CREATE INDEX invadjgrp_location_id_ix  ON invadjgrp  USING btree  (invadjgrp_location_id);
+CREATE INDEX invadjgrp_transdate_ix  ON invadjgrp  USING btree  (invadjgrp_transdate);
+CREATE INDEX invadjgrp_posted_ix  ON invadjgrp USING btree  (invadjgrp_posted);
+CREATE INDEX invadjgrp_comments_ix  ON invadjgrp USING btree  (invadjgrp_comments);
+
+update invadjgrp SET invadjgrp_posted = false where invadjgrp_posted IS NULL;
+ALTER TABLE invadjgrp ALTER COLUMN invadjgrp_posted  SET NOT NULL;
+ALTER TABLE invadjgrp ALTER COLUMN invadjgrp_posted  SET DEFAULT false;
+
+ALTER TABLE invadjgrp ADD COLUMN invadjgrp_void boolean NOT NULL DEFAULT false;
\ No newline at end of file
diff --git a/pgsql/x-dragon-invdetail-bydate.sql b/pgsql/x-dragon-invdetail-bydate.sql
new file mode 100644 (file)
index 0000000..4e84e10
--- /dev/null
@@ -0,0 +1,538 @@
+
+
+-- create an index on location so it's fast..
+
+
+
+-- returns the exact quantity of stock at the invdetail_id time..
+
+
+            
+       
+
+CREATE OR REPLACE FUNCTION invdetail_bydate(i_id int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+  v_return numeric(18,6) ;
+  BEGIN
+    v_return := 0;
+    SELECT invdetail_at_id(i_id) into v_return;
+
+  
+    RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_bydate(int)
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION invdetail_at_id(i_id int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+  v_itemsite_id INTEGER;
+  v_location_id INTEGER;
+  v_transdate timestamp with time zone;
+  v_qty numeric(18,6) ;
+  v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+
+
+
+
+   SELECT
+     invhist_itemsite_id,
+     invdetail_location_id,
+     invhist_transdate,
+     invdetail_qty
+        INTO
+        v_itemsite_id, 
+        v_location_id ,
+        v_transdate,
+        v_qty
+          FROM invdetail LEFT JOIN invhist ON 
+            invdetail_invhist_id = invhist_id
+         WHERE
+            invdetail_id = i_id
+          LIMIT 1;
+   
+
+-- # when transactions are the same day, we only want to include the ones with lower ids..
+
+
+    SELECT
+            COALESCE(SUM( invdetail_qty), 0) + v_qty INTO v_return
+            
+         FROM invdetail LEFT JOIN invhist ON 
+            invdetail_invhist_id = invhist_id
+        WHERE
+            invdetail_location_id = v_location_id
+            AND
+            invhist_itemsite_id = v_itemsite_id
+            AND   ( 
+                invhist_transdate <  v_transdate 
+                OR
+                (invhist_transdate =  v_transdate AND invdetail_id < i_id)
+            )  ;
+
+    IF (v_return IS NULL) THEN 
+        v_return = 0;
+    END IF;
+
+
+    -- UPDATE invdetail SET invdetail_bydate_qty_after = v_return WHERE invdetail_id = i_id;
+
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_byid(int)
+  OWNER TO admin;
+
+
+
+
+
+-- DATE, location_id, itemsite_id
+CREATE OR REPLACE FUNCTION invdetail_atdate(i_transdate timestamp with time zone, i_location_id int, i_itemsite_id int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+   
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT   COALESCE(SUM( invdetail_qty), 0)  
+        INTO
+            v_return 
+        FROM
+            invdetailview
+        WHERE
+             
+                invhist_itemsite_id = i_itemsite_id
+            AND
+                invhist_transdate <  i_transdate
+            AND
+                invfifo_void = 0
+            
+            AND
+               invdetail_location_id = i_location_id;
+        
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_atdate(timestamp with time zone, int, int)
+  OWNER TO admin;
+
+
+
+-- DATE, location_id, itemsite_id
+CREATE OR REPLACE FUNCTION invdetail_cost_atdate(timestamp with time zone, int, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    i_itemsite_id   ALIAS FOR $3;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT
+            COALESCE(SUM( invfifo_landedunitcost * invdetail_qty)  , 0) 
+        INTO
+            v_return 
+        FROM
+            invdetailview
+        WHERE
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invhist_transdate <  i_transdate
+            AND
+            invdetail_location_id = i_location_id
+            AND
+            invfifo_void = 0;
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_cost_atdate(timestamp with time zone, int, int)
+  OWNER TO admin;
+
+
+
+
+
+
+
+
+
+
+
+-- testing vlogic. on 2012-08-31 (124)
+
+-- select invdetail_location_atdate('2012-08-31', 124,1);
+--itemsite 1231 has 93?
+--
+--
+--(SELECT
+--                    invhist_itemsite_id,
+--                    sum(invdetail_qty) as invdetail_total
+--                FROM
+--                    invdetailview
+--                WHERE
+--                    invhist_transdate <  '2012-08-31'
+--                AND
+--                    invdetail_location_id = 124
+--                GROUP BY
+--                    invhist_itemsite_id
+--                HAVING
+--                    SUM(invdetail_qty) > 0
+--            ) dsum;
+--
+
+
+CREATE OR REPLACE FUNCTION invdetail_location_atdate(timestamp with time zone, int, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    v_posneg ALIAS FOR $3;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+     
+     
+  
+    IF v_posneg > 0 THEN
+        
+        SELECT SUM(invdetail_total)
+            INTO v_return
+        FROM 
+            (SELECT
+                    invhist_itemsite_id,
+                    sum(invdetail_qty) as invdetail_total
+                FROM
+                    invdetailview
+                WHERE
+                    invhist_transdate <  i_transdate
+                AND
+                    invdetail_location_id = i_location_id
+                AND
+                    invfifo_void = 0
+                GROUP BY
+                    invhist_itemsite_id
+                HAVING
+                    SUM(invdetail_qty) > 0
+                    
+            ) dsum;
+       
+        
+        RETURN COALESCE(v_return ,0);
+    END IF;
+    
+        
+    SELECT SUM(invdetail_total)
+            INTO v_return
+        FROM 
+            (SELECT
+                    invhist_itemsite_id,
+                    sum(invdetail_qty) as invdetail_total
+                FROM
+                    invdetailview
+                WHERE
+                    invhist_transdate <  i_transdate
+                AND
+                    invdetail_location_id = i_location_id
+                AND
+                    invfifo_void = 0
+                GROUP BY
+                    invhist_itemsite_id
+                HAVING
+                    SUM(invdetail_qty) < 0
+            ) dsum;
+        
+            
+        
+    RETURN COALESCE(v_return ,0);
+    
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_location_atdate(timestamp with time zone, int, int )
+  OWNER TO admin;
+
+
+
+CREATE OR REPLACE FUNCTION invcost_location_atdate(timestamp with time zone, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT
+        COALESCE(SUM( invfifo_landedunitcost * invdetail_qty ), 0)  
+        INTO
+            v_return 
+        FROM
+            invdetailview
+        WHERE
+            invhist_transdate <  i_transdate
+            AND
+            invdetail_location_id = i_location_id
+            AND
+            invfifo_void = 0;
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invcost_location_atdate(timestamp with time zone, int )
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION invdetail_cost_location_atdate(timestamp with time zone, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT
+            COALESCE(SUM( invfifo_totalcost * (invdetail_qty / ABS(invdetail_qty)) ), 0)
+        INTO
+            v_return 
+        FROM
+            invdetailview
+       
+        WHERE
+            invhist_transdate <  i_transdate
+        AND
+            invdetail_location_id = i_location_id
+        AND
+            invfifo_void = 0
+        ;
+         
+        
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_cost_location_atdate(timestamp with time zone, int )
+  OWNER TO admin;
+
+
+
+
+CREATE OR REPLACE FUNCTION invdetail_qty_at_id(int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+  i_id ALIAS FOR $1;
+  v_itemsite_id INTEGER;
+  v_location_id INTEGER;
+  v_transdate timestamp with time zone;
+  v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    SELECT
+     invhist_itemsite_id,
+     invdetail_location_id,
+     invhist_transdate
+        INTO
+        v_itemsite_id,
+        v_location_id ,
+        v_transdate
+          FROM invdetail 
+            LEFT JOIN invhist ON invdetail_invhist_id = invhist_id
+         WHERE
+            invdetail_id = i_id
+          LIMIT 1;
+
+    SELECT   COALESCE(SUM( invdetail_qty), 0) INTO v_return 
+         FROM invdetail 
+            LEFT JOIN invhist ON invdetail_invhist_id = invhist_id
+            LEFT JOIN invfifo ON invdetail_id = invfifo_invdetail_id
+        WHERE
+            invdetail_location_id = v_location_id
+            AND
+            invhist_itemsite_id = v_itemsite_id
+            AND
+            ((invhist_transdate <  v_transdate) OR (invhist_transdate =  v_transdate AND invdetail_id <= i_id))
+            AND
+            (invfifo_void IS NULL OR invfifo_void = 0);
+
+    IF (v_return IS NULL) THEN 
+        v_return = 0;
+    END IF;
+
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_qty_at_id(int)
+  OWNER TO admin;
+
+
+
+-- DATE, location_id, itemsite_id
+CREATE OR REPLACE FUNCTION invdetail_sold_atdate(timestamp with time zone, int, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    i_itemsite_id   ALIAS FOR $3;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT   COALESCE(SUM( invdetail_qty), 0)  
+        INTO
+            v_return 
+        FROM
+            invdetailview
+        WHERE
+             
+                invhist_itemsite_id = i_itemsite_id
+            AND
+                invhist_transdate::date =  i_transdate::date
+            AND
+                invfifo_void = 0
+            
+            AND
+               invdetail_location_id = i_location_id;
+        
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_sold_atdate(timestamp with time zone, int, int)
+  OWNER TO admin;
+
+
+--  location_id, itemsite_id
+CREATE OR REPLACE FUNCTION invdetail_sold_after(timestamp with time zone, int, int)
+  RETURNS  numeric(18,6)  AS
+$BODY$
+DECLARE
+    i_transdate   ALIAS FOR $1;
+    i_location_id   ALIAS FOR $2;
+    i_itemsite_id   ALIAS FOR $3;
+    v_return numeric(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    
+    SELECT   COALESCE(SUM( invdetail_qty), 0)  
+        INTO
+            v_return 
+        FROM
+            invdetailview
+        WHERE
+                invhist_itemsite_id = i_itemsite_id
+            AND
+                invhist_transdate::date >  i_transdate::date
+            AND
+                invfifo_void = 0
+            AND
+                invdetail_qty < 0
+            
+            AND
+               invdetail_location_id = i_location_id;
+        
+    
+    RETURN COALESCE(v_return ,0);
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_sold_after(timestamp with time zone, int, int)
+  OWNER TO admin;
+
+
+
+
+
+CREATE OR REPLACE FUNCTION invdetail_balance_byitem( i_itemsite_id INTEGER, i_location_id INTEGER)
+  RETURNS  NUMERIC(18,6)  AS
+$BODY$
+DECLARE
+    v_return NUMERIC(18,6) ;
+BEGIN
+    v_return := 0;
+    
+    SELECT 
+            COALESCE(SUM(invdetail_qty),0)
+    INTO
+            v_return
+    FROM
+            invdetail
+    LEFT JOIN
+            invhist
+    ON
+            invdetail_invhist_id = invhist_id
+    WHERE
+            invhist_itemsite_id = i_itemsite_id
+        AND
+            invdetail_location_id = i_location_id;
+    
+    RETURN v_return;
+    
+        
+END;
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+ALTER FUNCTION  invdetail_balance_byitem(INTEGER, INTEGER)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-invhist-transfer.sql b/pgsql/x-dragon-invhist-transfer.sql
new file mode 100644 (file)
index 0000000..ba177fc
--- /dev/null
@@ -0,0 +1,505 @@
+-- Sequence: accnt_accnt_id_seq
+
+-- DROP SEQUENCE accnt_accnt_id_seq;
+
+CREATE SEQUENCE invhist_transfer_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE invhist_transfer_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_transfer_id_seq TO admin;
+GRANT ALL ON TABLE invhist_transfer_id_seq TO xtrole;
+
+
+CREATE TABLE invhist_transfer
+(
+  invhist_transfer_id integer NOT NULL DEFAULT nextval(('invhist_transfer_id_seq'::text)::regclass),
+  invhist_transfer_transdate  timestamp with time zone DEFAULT ('now'::text)::timestamp(6) with time zone,
+  invhist_transfer_number text,
+  invhist_transfer_from integer,
+  invhist_transfer_to integer,
+  invhist_transfer_descrip text,
+  
+     CONSTRAINT invhist_transfer_pkey PRIMARY KEY (invhist_transfer_id ),
+    CONSTRAINT invhist_transfer_to_fkey FOREIGN KEY (invhist_transfer_to)
+        REFERENCES location (location_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION,
+    CONSTRAINT invhist_transfer_from_fkey FOREIGN KEY (invhist_transfer_from)
+      REFERENCES location (location_id)  
+      ON UPDATE CASCADE ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+
+CREATE INDEX invhist_transfer_number_ix  ON invhist_transfer  USING btree  (invhist_transfer_number);
+CREATE INDEX invhist_transfer_transdate_ix  ON invhist_transfer  USING btree  (invhist_transfer_transdate );
+CREATE INDEX invhist_transfer_loc_ix  ON invhist_transfer  USING btree  (invhist_transfer_from, invhist_transfer_to );
+
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_posted BOOLEAN DEFAULT false;
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_recvgrp_id INTEGER;
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_price TEXT default '';
+
+ALTER TABLE invhist_transfer DROP CONSTRAINT invhist_salesrep_id_fkey;
+
+ALTER TABLE invhist_transfer DROP COLUMN invhist_salesrep_id;
+
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_salesrep_id  INTEGER;
+
+ALTER TABLE invhist_transfer ADD CONSTRAINT invhist_transfer_salesrep_id_fkey FOREIGN KEY (invhist_transfer_salesrep_id)
+      REFERENCES  salesrep(salesrep_id)  MATCH SIMPLE 
+      ON UPDATE CASCADE ON DELETE NO ACTION;
+
+
+
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_void BOOLEAN DEFAULT false;
+
+ALTER TABLE invhist_transfer ADD CONSTRAINT invhist_transfer_recvgrp_id_fkey FOREIGN KEY (invhist_transfer_recvgrp_id)
+      REFERENCES recvgrp (recvgrp_id)  MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;
+
+ALTER TABLE invhist_transfer ADD COLUMN invhist_transfer_arrivaldate timestamp with time zone DEFAULT ('now'::text)::timestamp(6) with time zone;
+
+
+CREATE INDEX invhist_transfer_posted_ix  ON invhist_transfer  USING btree  (invhist_transfer_posted );
+CREATE INDEX invhist_transfer_void_ix  ON invhist_transfer  USING btree  (invhist_transfer_void );
+
+ALTER TABLE invhist_transfer
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_transfer TO admin;
+GRANT ALL ON TABLE invhist_transfer TO xtrole;
+COMMENT ON TABLE invhist_transfer
+  IS 'Inventory Transfer Group';
+  
+  
+  
+CREATE TRIGGER invhist_transfertrigger
+  BEFORE INSERT OR UPDATE OR DELETE
+  ON invhist_transfer
+  FOR EACH ROW
+  EXECUTE PROCEDURE _invhist_transfertrigger();
+  
+  
+  
+
+CREATE OR REPLACE FUNCTION _invhist_transfertrigger()
+  RETURNS trigger AS
+$BODY$
+DECLARE
+  
+
+BEGIN
+    IF (TG_OP = 'INSERT') THEN
+        IF (NEW.invhist_transfer_posted) THEN 
+            RAISE EXCEPTION 'You can not create a transfer which is already posted';
+        END IF;
+        RETURN NEW;
+    END IF;
+    
+    IF (TG_OP = 'DELETE') THEN
+        IF (OLD.invhist_transfer_posted) THEN 
+            RAISE EXCEPTION 'You can not delete a transfer which is already posted';
+        END IF;
+        RETURN OLD;
+    END IF;
+    
+    -- we are now updating
+    
+    
+    IF (OLD.invhist_transfer_posted) THEN
+        IF (
+            ( OLD.invhist_transfer_transdate != NEW.invhist_transfer_transdate ) OR
+            ( OLD.invhist_transfer_number != NEW.invhist_transfer_number ) OR
+            ( OLD.invhist_transfer_from !=  NEW.invhist_transfer_from) OR
+            ( OLD.invhist_transfer_to != NEW.invhist_transfer_to ) 
+        ) THEN
+            RAISE EXCEPTION 'You can not modify a transfer which is already posted';
+        END IF;
+        RETURN NEW;
+    END IF;
+    
+    -- if it's not posted..
+    RETURN NEW;
+    
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION _invhist_transfertrigger()
+  OWNER TO admin;  
+    
+
+
+
+
+--     ------------------------------- 
+
+    
+
+CREATE SEQUENCE invhist_transfer_item_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE invhist_transfer_item_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_transfer_item_id_seq TO admin;
+GRANT ALL ON TABLE invhist_transfer_item_id_seq TO xtrole;
+
+
+CREATE TABLE invhist_transfer_item
+(
+  invhist_transfer_item_id integer NOT NULL DEFAULT nextval(('invhist_transfer_item_id_seq'::text)::regclass),
+  invhist_transfer_item_invhist_transfer_id integer NOT NULL,
+  invhist_transfer_item_itemsite_id integer NOT NULL,
+  invhist_transfer_item_qty integer,
+  
+   CONSTRAINT invhist_transfer_item_pkey PRIMARY KEY (invhist_transfer_item_id ),
+   CONSTRAINT invhist_transfer_item_itemsite_fkey FOREIGN KEY (invhist_transfer_item_itemsite_id)
+        REFERENCES itemsite (itemsite_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION,
+    CONSTRAINT invhist_transfer_item_invhist_transfer_fkey FOREIGN KEY (invhist_transfer_item_invhist_transfer_id)
+        REFERENCES invhist_transfer ( invhist_transfer_id) 
+      ON UPDATE CASCADE ON DELETE NO ACTION
+)
+WITH (
+  OIDS=FALSE
+);
+
+
+ALTER TABLE invhist_transfer_item ADD COLUMN invhist_transfer_item_line INTEGER;
+ALTER TABLE invhist_transfer_item ADD COLUMN invhist_transfer_invhist_id  INTEGER;
+
+ALTER TABLE invhist_transfer_item ADD COLUMN invhist_transfer_item_unit_price NUMERIC(12,2) DEFAULT NULL;
+ALTER TABLE invhist_transfer_item ADD COLUMN invhist_transfer_item_unit_price_default NUMERIC(12,2) DEFAULT NULL;
+
+CREATE INDEX invhist_transfer_item_line_ix  ON invhist_transfer_item  USING btree  (invhist_transfer_item_line);
+
+CREATE INDEX invhist_transfer_item_unit_price_ix  ON invhist_transfer_item  USING btree  (invhist_transfer_item_unit_price);
+CREATE INDEX invhist_transfer_item_unit_price_default_ix  ON invhist_transfer_item  USING btree  (invhist_transfer_item_unit_price_default);
+
+CREATE UNIQUE INDEX invhist_transfer_item_line_invhist_transfer_id_key 
+    ON invhist_transfer_item 
+USING btree (invhist_transfer_item_invhist_transfer_id , invhist_transfer_item_line);
+
+
+
+ALTER TABLE invhist_transfer_item ADD CONSTRAINT invhist_transfer_invhist_fkey FOREIGN KEY (invhist_transfer_invhist_id)
+        REFERENCES invhist(invhist_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;
+
+
+ALTER TABLE invhist_transfer_item
+  OWNER TO admin;
+GRANT ALL ON TABLE invhist_transfer_item TO admin;
+GRANT ALL ON TABLE invhist_transfer_item TO xtrole;
+COMMENT ON TABLE invhist_transfer_item
+  IS 'Inventory Transfer Group Item';
+  
+  
+  
+  
+CREATE TRIGGER invhist_transfer_itemtrigger
+  BEFORE INSERT OR UPDATE OR DELETE
+  ON invhist_transfer_item
+  FOR EACH ROW
+  EXECUTE PROCEDURE _invhist_transfer_itemtrigger();
+  
+  
+  
+
+CREATE OR REPLACE FUNCTION _invhist_transfer_itemtrigger()
+  RETURNS trigger AS
+$BODY$
+DECLARE
+   _p RECORD;
+
+BEGIN
+     
+    IF (TG_OP = 'UPDATE') THEN
+        IF (OLD.invhist_transfer_item_invhist_transfer_id != NEW.invhist_transfer_item_invhist_transfer_id) THEN
+            RAISE EXCEPTION 'You can not modify then transfer group of transfer item ';
+        END IF;
+    END IF;
+    
+    
+    IF ((TG_OP = 'INSERT') OR (TG_OP = 'UPDATE')) THEN
+        
+        SELECT * FROM invhist_transfer INTO  _p  WHERE
+                invhist_transfer_id = NEW.invhist_transfer_item_invhist_transfer_id
+                LIMIT 1;
+        
+    END IF;
+    IF (TG_OP = 'DELETE') THEN        
+        SELECT * FROM invhist_transfer INTO  _p  WHERE
+                invhist_transfer_id = OLD.invhist_transfer_item_invhist_transfer_id
+                LIMIT 1;
+        
+    END IF;
+    
+    
+    
+    IF (_p.invhist_transfer_posted) THEN 
+        RAISE EXCEPTION 'You can not modify records of a transfer that is already posted';
+    END IF;
+    
+    
+    IF (TG_OP = 'DELETE') THEN
+        RETURN OLD;
+    END IF;
+    
+    RETURN NEW;  
+    
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION _invhist_transfer_itemtrigger()
+  OWNER TO admin;  
+  
+  
+  
+
+-- create dummy itemlocs
+
+CREATE OR REPLACE FUNCTION itemloc_get(int, int)
+  RETURNS  int  AS
+$BODY$
+DECLARE
+  
+  i_itemsite ALIAS FOR $1;
+  i_location ALIAS FOR $2;
+  v_id int;
+   
+BEGIN
+    SELECT itemloc_id INTO v_id FROM itemloc WHERE
+        itemloc_itemsite_id = i_itemsite
+        AND 
+        itemloc_location_id = i_location;
+        
+        
+    IF (NOT FOUND) THEN
+        INSERT INTO itemloc ( 
+            itemloc_itemsite_id , itemloc_location_id ,
+            itemloc_qty, itemloc_expiration  ,
+            itemloc_consolflag
+        ) VALUES (
+            i_itemsite, i_location,
+            0, endoftime(),
+            false
+        );
+        SELECT itemloc_id INTO v_id FROM itemloc WHERE
+            itemloc_itemsite_id = i_itemsite
+            AND 
+            itemloc_location_id = i_location;
+            
+    END IF;
+
+
+   RETURN v_id;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  itemloc_get(int,int)
+  OWNER TO admin;
+
+
+  
+--- post the invhist_Transfer...
+
+
+CREATE OR REPLACE FUNCTION invhist_transfer_post(int)
+  RETURNS  int  AS
+$BODY$
+DECLARE
+  i_id ALIAS FOR $1;
+  v_location_from  INTEGER;
+  v_location_to INTEGER;
+  v_transdate timestamp with time zone;
+  v_number TEXT;
+  v_code TEXT;
+  
+  v_return INTEGER;
+  
+  _r RECORD;
+   
+BEGIN
+    v_return := 0;
+
+    
+
+
+   SELECT
+         
+        invhist_transfer_from ,
+        invhist_transfer_to,
+        invhist_transfer_transdate ,
+        invhist_transfer_number  
+        
+        INTO
+         v_location_from, 
+        v_location_to ,
+        v_transdate,
+        v_number
+         FROM
+            invhist_transfer
+         WHERE
+            invhist_transfer_id = i_id
+            AND
+            invhist_transfer_posted = false
+          LIMIT 1;
+   
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Unposted Stock transfer does not exist';
+        RETURN -1;
+    END IF;
+
+--# when transactions are the same day, we only want to include the ones with lower ids..
+    FOR _r IN  SELECT  relocateInventory(
+                itemloc_get( invhist_transfer_item_itemsite_id, v_location_from),
+                 v_location_to,
+                invhist_transfer_item_itemsite_id,
+                invhist_transfer_item_qty,
+                v_number,
+                v_transdate
+                
+                ) AS result,
+                invhist_transfer_item_itemsite_id
+                FROM
+                    invhist_transfer_item
+                WHERE
+                     invhist_transfer_item_invhist_transfer_id = i_id
+    
+        LOOP       
+            IF _r.result < 1 THEN
+            
+                SELECT
+                        item_number
+                    INTO
+                        v_code
+                    FROM
+                        
+                        item
+                    LEFT JOIN
+                        itemsite
+                    ON
+                        item_id = itemsite_item_id
+                    WHERE
+                        itemsite_id = _r.invhist_transfer_item_itemsite_id
+                LIMIT 1;
+                
+                
+                    
+            
+            
+            
+                RAISE EXCEPTION 'Failed to Post Stock transfer: %', v_code;
+                RETURN -1;
+            END IF;
+            
+    END LOOP;
+
+    UPDATE invhist_transfer SET invhist_transfer_posted = true WHERE 
+        invhist_transfer_id = i_id;
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invhist_transfer_post(int)
+  OWNER TO admin;
+
+
+
+  
+CREATE OR REPLACE FUNCTION invhist_transfer_void(int)
+  RETURNS  int  AS
+$BODY$
+DECLARE
+  i_id ALIAS FOR $1;
+  v_location_from  INTEGER;
+  v_location_to INTEGER;
+  v_transdate timestamp with time zone;
+  v_number TEXT;
+  
+  v_return INTEGER;
+  v_itemloc_id INTEGER;
+  _r RECORD;
+   
+BEGIN
+    v_return := 0;
+
+    
+
+
+   SELECT
+         
+        invhist_transfer_from ,
+        invhist_transfer_to,
+        invhist_transfer_transdate ,
+        invhist_transfer_number  
+        
+        INTO
+         v_location_from, 
+        v_location_to ,
+        v_transdate,
+        v_number
+         FROM
+            invhist_transfer
+         WHERE
+            invhist_transfer_id = i_id
+            AND
+            invhist_transfer_posted = true
+          LIMIT 1;
+   
+
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Posted Stock transfer does not exist';
+        RETURN -1;
+    END IF;
+    
+    
+     
+    
+--# when transactions are the same day, we only want to include the ones with lower ids..
+-- to and from are reversed..
+    FOR _r IN  SELECT  relocateInventory(
+                itemloc_get( invhist_transfer_item_itemsite_id, v_location_to),
+                v_location_from,
+                invhist_transfer_item_itemsite_id,
+                invhist_transfer_item_qty ,
+                v_number || ' REVERSED',
+                v_transdate
+                ) AS result
+                FROM
+                    invhist_transfer_item
+                WHERE
+                     invhist_transfer_item_invhist_transfer_id = i_id
+    
+        LOOP       
+            IF _r.result < 1 THEN
+                RAISE EXCEPTION 'Failed to Post Stock transfer';
+                RETURN -1;
+            END IF;
+            
+    END LOOP;
+
+    UPDATE invhist_transfer SET invhist_transfer_posted = false WHERE 
+        invhist_transfer_id = i_id;
+
+  RETURN v_return;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  invhist_transfer_void(int)
+  OWNER TO admin;
+
diff --git a/pgsql/x-dragon-item-beforetrigger.sql b/pgsql/x-dragon-item-beforetrigger.sql
new file mode 100644 (file)
index 0000000..1b23e0e
--- /dev/null
@@ -0,0 +1,26 @@
+CREATE TRIGGER x_dragon_item_beforetrigger
+  BEFORE  UPDATE
+  ON item
+  FOR EACH ROW
+  EXECUTE PROCEDURE x_dragon_item_trigger_before();
+
+
+
+CREATE OR REPLACE FUNCTION x_dragon_item_trigger_before()
+  RETURNS trigger AS
+$BODY$
+BEGIN
+-- Override values to avoid invalid data combinations
+  IF (NEW.item_number != OLD.item_number) THEN
+    RAISE EXCEPTION 'changing item number is not allowed. from %  to %', OLD.item_number, NEW.item_number;
+  END IF;
+
+  RETURN NEW;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION x_dragon_item_trigger_before()
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-dragon-itemprice_wrp.sql b/pgsql/x-dragon-itemprice_wrp.sql
new file mode 100644 (file)
index 0000000..c03518a
--- /dev/null
@@ -0,0 +1,82 @@
+
+CREATE OR REPLACE FUNCTION itemprice_wrp(integer, integer)
+    RETURNS  numeric(18, 6)
+
+AS $BODY$
+DECLARE        
+           
+    i_itemsite_id  ALIAS FOR $1;
+    i_curr_id  ALIAS FOR $2;
+    v_result numeric(18, 6);
+    
+BEGIN
+     
+    
+
+    SELECT
+            ROUND(MAX(ipsitem_price),3)
+        INTO
+            v_result
+        FROM
+            ipsiteminfo
+        LEFT JOIN
+            ipshead
+        ON
+            ipshead_id = ipsitem_ipshead_id 
+        LEFT JOIN
+            itemsite
+        ON
+            ipsitem_item_id  = itemsite_item_id
+        WHERE
+            ipshead_name like '%WRP%'
+        AND
+            ipshead_curr_id = i_curr_id
+        AND
+            itemsite_id = i_itemsite_id;
+        
+        -- not found?
+    IF FOUND AND v_result IS NOT NULL THEN 
+        RETURN v_result;
+    END IF;
+        
+    
+              
+            
+    -- default...  could not work it out above..      
+    
+        -- use the list price.
+        
+    SELECT   currtocurr(
+                    basecurrid(),
+                    i_curr_id,
+                    item_listprice,
+                    NOW()::date
+                )
+        INTO
+            v_result
+        FROM
+            itemsite
+        LEFT JOIN
+            item
+        ON
+            item_id = itemsite_item_id
+        WHERE
+            itemsite_id = i_itemsite_id
+        LIMIT 1;
+        
+        -- not found?
+        
+    RETURN v_result;
+        
+         END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  itemprice_wrp(integer, integer)
+  OWNER TO admin;
+    
+    
+ -- select itemprice_wrp(itemsite_id, getcurrid('USD')) FROM itemsite;
diff --git a/pgsql/x-dragon-location.sql b/pgsql/x-dragon-location.sql
new file mode 100644 (file)
index 0000000..46dc620
--- /dev/null
@@ -0,0 +1,6 @@
+
+  
+ALTER TABLE location ADD COLUMN location_cust_id INTEGER DEFAULT 0;
+
+CREATE INDEX location_cust_id_ix  ON location USING btree  (location_cust_id);
diff --git a/pgsql/x-dragon-locbal.sql b/pgsql/x-dragon-locbal.sql
new file mode 100644 (file)
index 0000000..a3332c5
--- /dev/null
@@ -0,0 +1,610 @@
+
+-- loc bal is disabled at present - it's slow, and does not help much..
+
+
+CREATE SEQUENCE locbal_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+GRANT ALL ON SEQUENCE locbal_id_seq  TO xtrole;
+
+
+CREATE TABLE locbal (
+    locbal_id INTEGER NOT NULL DEFAULT nextval(('locbal_id_seq'::text)::regclass),
+    locbal_period_id integer,
+    locbal_location_id integer,
+    
+    locbal_itemsite_id integer,
+    
+    locbal_beginning numeric(20,2),
+    locbal_ending numeric(20,2),
+    
+    locbal_credits numeric(20,2),
+    locbal_debits numeric(20,2),
+    
+    CONSTRAINT locbal_itemsite_id_fkey FOREIGN KEY (locbal_itemsite_id)
+        REFERENCES itemsite  (itemsite_id)  MATCH SIMPLE,
+    
+    
+    CONSTRAINT locbal_period_id_fkey FOREIGN KEY (locbal_period_id)
+        REFERENCES period (period_id)  MATCH SIMPLE,
+        
+    CONSTRAINT locbal_location_id_fkey FOREIGN KEY (locbal_location_id)
+        REFERENCES location (location_id),
+    CONSTRAINT locbal_id_pkey PRIMARY KEY (locbal_id)
+);
+
+CREATE UNIQUE INDEX locbal_locsite_idx  ON locbal USING btree  (locbal_period_id, locbal_location_id, locbal_itemsite_id );
+
+
+
+ALTER TABLE public.locbal OWNER TO admin;
+GRANT ALL ON TABLE locbal  TO xtrole;
+COMMENT ON TABLE locbal IS 'Location Balance information';
+
+ CREATE SEQUENCE loccurbal_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+GRANT ALL ON TABLE loccurbal_id_seq TO xtrole;
+
+CREATE TABLE loccurbal (
+    loccurbal_id INTEGER NOT NULL DEFAULT nextval(('loccurbal_id_seq'::text)::regclass),
+    loccurbal_location_id integer,
+    loccurbal_itemsite_id integer,
+    loccurbal_ending numeric(20,2),
+    
+    CONSTRAINT loccurbal_itemsite_id_fkey FOREIGN KEY (loccurbal_itemsite_id)
+        REFERENCES itemsite  (itemsite_id)  MATCH SIMPLE,
+    CONSTRAINT loccurbal_location_id_fkey FOREIGN KEY (loccurbal_location_id)
+        REFERENCES location (location_id),
+    CONSTRAINT loccurbal_id_pkey PRIMARY KEY (loccurbal_id)
+);
+
+ALTER TABLE public.loccurbal OWNER TO admin;
+
+GRANT ALL ON TABLE loccurbal TO xtrole;
+
+COMMENT ON TABLE loccurbal IS 'Location Balance current';
+
+
+CREATE UNIQUE INDEX loccurbal_locsite_idx  ON loccurbal USING btree  (loccurbal_location_id, loccurbal_itemsite_id );
+
+
+
+
+-- update balance.
+
+
+-- TESTING:
+-- SELECT distinct(invhist_itemsite_id), invdetaillocation_id, NOW() FROM invdetailview GROUP BY invhist_itemsite_id LIMIT 100;
+
+-- 
+
+DROP FUNCTION locbal_update_location_itemsite(integer, integer, date );
+CREATE OR REPLACE FUNCTION locbal_update_location_itemsite(integer, integer, date )
+  RETURNS NUMERIC AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  i_location_id ALIAS FOR $1;
+  i_itemsite_id ALIAS FOR $2;
+  i_date ALIAS FOR $3;
+  
+  v_id INTEGER;
+  v_chk INTEGER;
+  v_ret NUMERIC;
+  v_last NUMERIC;
+BEGIN
+
+    --RAISE NOTICE 'update locbal(a) % , %, %',i_location_id, i_itemsite_id,  i_date;
+    SELECT
+            period_id
+        INTO
+            v_id
+        FROM
+            period
+        WHERE
+            period_start <= i_date
+            AND
+            period_end >= i_date;
+        
+    IF NOT FOUND THEN
+        RAISE NOTICE 'no period found';
+        RETURN 0;
+    END IF;
+  
+    -- make sure there are some transactions for that item/location
+    SELECT
+            invdetail_id
+        INTO
+            v_chk
+        FROM
+            invdetailview
+        WHERE
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_location_id = i_location_id
+            AND
+            invhist_posted
+        LIMIT 1;
+        
+    IF NOT FOUND THEN
+        RAISE NOTICE 'no transactions found';
+        RETURN 0;
+    END IF;
+    
+    
+     --RAISE NOTICE 'locbal_update_location_itemsite_period(  % , %, %) ',i_location_id, i_itemsite_id, v_id;
+   
+    -- this handle current and before..
+    SELECT
+            locbal_update_location_itemsite_period(i_location_id, i_itemsite_id, v_id)
+        INTO
+            v_ret;
+    
+    -- we should update after...
+    
+    -- finally update the total..
+    --RAISE NOTICE 'locbal_update_begin_end   %   ',i_date  ;
+   
+    PERFORM
+           locbal_update_begin_end(locbal_id)
+        FROM
+            locbal
+        LEFT JOIN
+            period
+        ON
+            locbal_period_id = period_id
+        WHERE
+            period_start > i_date
+            AND
+            locbal_itemsite_id = i_itemsite_id
+            AND
+            locbal_location_id = i_location_id
+        ORDER BY
+            period_start ASC;
+    
+    
+     --RAISE NOTICE 'loccurbal_update(  % , % ) ',i_location_id, i_itemsite_id ;
+    ---- updates loccurbal find final locbal_id
+    PERFORM loccurbal_update(i_location_id, i_itemsite_id); 
+    RETURN v_ret;
+  
+  
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION locbal_update_location_itemsite(integer, integer, date )
+  OWNER TO admin;
+    
+
+
+
+CREATE OR REPLACE FUNCTION locbal_update_begin_end(integer  )
+  RETURNS NUMERIC AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+    i_id ALIAS FOR $1;
+    v_location_id INTEGER;
+    v_itemsite_id INTEGER;
+   
+    v_period_start DATE;
+    v_balance NUMERIC;
+    
+BEGIN
+
+    --0 get current.
+    SELECT
+            locbal_location_id,
+            locbal_itemsite_id,
+            period_start
+        INTO
+            v_location_id,
+            v_itemsite_id,
+            v_period_start
+        FROM
+            locbal
+        LEFT JOIN
+            period
+        ON
+            locbal_period_id = period_id
+        WHERE
+            locbal_id = i_id ;
+        
+    
+    -- get prev
+    
+    SELECT
+            locbal_ending
+        INTO
+            v_balance
+        FROM
+            locbal
+        LEFT JOIN
+            period
+        ON
+            locbal_period_id = period_id
+        WHERE
+            locbal_id != i_id
+            AND
+            period_start < v_period_start
+            AND
+            locbal_location_id = v_location_id
+            AND 
+            locbal_itemsite_id = v_itemsite_id
+        ORDER BY
+            period_start DESC
+        LIMIT 1;
+    
+    IF NOT FOUND THEN
+        -- RAISE NOTICE 'no more previous periods';
+        v_balance := 0;
+    END IF;
+
+    UPDATE
+        locbal
+        SET
+            locbal_beginning = v_balance,
+            locbal_ending = v_balance + locbal_credits - locbal_debits
+        WHERE
+            locbal_id = i_id;
+    
+    RETURN v_balance;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION locbal_update_begin_end(integer  )
+  OWNER TO admin;
+    
+
+
+
+
+CREATE OR REPLACE FUNCTION loccurbal_update(integer, integer)
+  RETURNS NUMERIC AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+    
+    i_location_id ALIAS FOR $1;
+    i_itemsite_id ALIAS FOR $2;
+   
+    v_id INTEGER;
+    v_balance NUMERIC;
+    
+BEGIN
+
+    --0 get current.
+     
+    -- get last
+    
+    SELECT
+            COALESCE(locbal_ending, 0)
+        INTO
+            v_balance
+        FROM
+            locbal
+        LEFT JOIN
+            period
+        ON
+            locbal_period_id = period_id
+        WHERE
+             
+            locbal_location_id = i_location_id
+            AND 
+            locbal_itemsite_id = i_itemsite_id
+        ORDER BY
+            period_start DESC
+        LIMIT 1;
+    
+    IF NOT FOUND  THEN
+        v_balance := 0;
+    END IF;
+    
+    SELECT
+          loccurbal_id 
+        INTO
+            v_id
+        FROM
+            loccurbal
+        WHERE
+            loccurbal_location_id = i_location_id
+            AND 
+            loccurbal_itemsite_id = i_itemsite_id
+        LIMIT 1;
+    
+    IF NOT FOUND THEN
+        INSERT INTO loccurbal (
+            loccurbal_location_id,
+            loccurbal_itemsite_id,
+            loccurbal_ending 
+        ) VALUES (
+            i_location_id,
+            i_itemsite_id,
+            v_balance
+        );
+        RETURN v_balance;
+    END IF;
+    
+     
+    UPDATE
+        loccurbal
+        SET
+            loccurbal_ending = v_balance 
+        WHERE
+            loccurbal_id = v_id;
+    
+    RETURN v_balance;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION loccurbal_update(integer, integer)
+  OWNER TO admin;
+    
+
+
+    
+    
+CREATE OR REPLACE FUNCTION locbal_update_location_itemsite_period(integer,integer, integer)
+  RETURNS NUMERIC AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  i_location_id ALIAS FOR $1;
+  i_itemsite_id ALIAS FOR $2;
+  i_period_id ALIAS FOR $3;
+  
+  v_id INTEGER;
+  v_prev_period_id INTEGER;
+   
+  v_credit NUMERIC;
+  v_debit NUMERIC;
+  v_balance NUMERIC;
+  
+  v_start DATE;
+  v_end DATE;
+
+BEGIN
+
+    --RAISE NOTICE 'SELECT locbal_update_location_itemsite_period (% , %, %)',i_location_id, i_itemsite_id,  i_period_id;
+    SELECT
+            period_start,
+            period_end
+        INTO
+            v_start,
+            v_end
+        FROM
+            period
+        WHERE
+            period_id = i_period_id;
+
+    -- check to see if we have a value for the previous period.
+
+
+    SELECT
+            period_id
+        INTO
+            v_prev_period_id
+        FROM
+            period
+        WHERE
+            period_start < v_start
+            AND
+            period_id != i_period_id
+        ORDER BY
+            period_start DESC
+        LIMIT 1;
+        
+    IF NOT FOUND THEN
+        -- RAISE NOTICE 'no more previous periods';
+        v_balance := 0;
+    ELSE
+        -- find out if we have a balance for the previous period..
+        
+        SELECT
+                locbal_ending
+            INTO
+                v_balance
+            FROM
+                locbal
+            WHERE
+                locbal_location_id = i_location_id
+            AND
+                locbal_itemsite_id = i_itemsite_id
+            AND
+                locbal_period_id = v_prev_period_id;
+                
+            
+        IF NOT FOUND THEN
+        
+            
+        
+            SELECT
+                locbal_update_location_itemsite_period(i_location_id,i_itemsite_id, v_prev_period_id)
+            INTO
+                v_balance;
+                
+        END IF;
+    
+    
+    END IF;
+
+
+
+    SELECT
+            
+            COALESCE(SUM( CASE WHEN invdetail_qty > 0 THEN invdetail_qty ELSE 0 END) , 0) ,
+            COALESCE(SUM( CASE WHEN invdetail_qty < 0 THEN invdetail_qty * -1 ELSE 0 END) , 0) 
+        INTO
+            v_credit,
+            v_debit
+         
+        FROM
+            invdetailview
+        WHERE
+            invhist_transdate >= v_start
+            AND
+            invhist_transdate < v_end + INTERVAL '1 DAY'
+            AND
+            invhist_itemsite_id = i_itemsite_id 
+            AND
+            invdetail_location_id = i_location_id
+            AND
+            invhist_posted;
+            
+            
+    IF NOT FOUND THEN
+        v_credit := 0;
+        v_debit := 0;
+    END IF;
+    
+    -- do we have a current record...
+      
+    SELECT
+            locbal_id
+        INTO
+            v_id
+        FROM
+            locbal
+        WHERE
+            locbal_location_id = i_location_id
+        AND
+            locbal_itemsite_id = i_itemsite_id
+        AND
+            locbal_period_id = i_period_id;
+    
+    IF NOT FOUND THEN
+        --RAISE NOTICE 'adding locbal';
+    
+        INSERT INTO locbal
+        ( 
+            locbal_period_id  ,
+            locbal_location_id  ,
+            
+            locbal_itemsite_id  ,
+            
+            locbal_beginning  ,
+            locbal_ending  ,
+            
+            locbal_credits  ,
+            locbal_debits
+        ) VALUES (
+            i_period_id,
+            i_location_id,
+            i_itemsite_id,
+            
+            v_balance,
+            v_balance + v_credit - v_debit,
+            
+            v_credit,
+            v_debit
+        
+        );
+    ELSE
+        --RAISE NOTICE 'updating locbal';
+        UPDATE locbal
+            SET 
+                locbal_beginning  = v_balance,
+                locbal_ending = v_balance + v_credit - v_debit ,
+                
+                locbal_credits  = v_credit,
+                locbal_debits = v_debit
+            WHERE
+                locbal_id = v_id;
+    END IF;
+    
+            
+    RETURN v_balance + v_credit - v_debit ;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION locbal_update_location_itemsite_period(integer,integer, integer)
+  OWNER TO admin;
+    
+
+-- TESTING
+--
+--SELECT locbal_update_location_itemsite(a,b,c)
+--    FROM (
+--        SELECT distinct(invhist_itemsite_id) b, invdetail_location_id a, MAX(invhist_transdate)::date c
+--        FROM invdetailview
+--        
+--        GROUP BY invhist_itemsite_id, invdetail_location_id  ) d;
+-- 
+-- 
+-- 
+
+  
+
+CREATE OR REPLACE FUNCTION _invhist_locbaltrigger()
+  RETURNS trigger AS
+$BODY$
+DECLARE
+  v_ret NUMERIC;
+
+BEGIN
+    IF (TG_OP = 'INSERT') THEN
+        SELECT locbal_update_location_itemsite(NEW.invdetail_location_id, invhist_itemsite_id, invhist_transdate::date)
+        INTO v_ret
+            FROM invhist WHERE invhist_id = NEW.invdetail_invhist_id;
+    
+        RETURN NEW;
+    END IF;
+     IF (TG_OP = 'UPDATE') THEN
+        
+        SELECT locbal_update_location_itemsite(NEW.invdetail_location_id, invhist_itemsite_id, invhist_transdate::date)
+        INTO v_ret
+            FROM invhist WHERE invhist_id = NEW.invdetail_invhist_id;
+        
+        SELECT locbal_update_location_itemsite(OLD.invdetail_location_id, invhist_itemsite_id, invhist_transdate::date)
+        INTO v_ret
+            FROM invhist WHERE invhist_id = OLD.invdetail_invhist_id;
+    
+        RETURN NEW;
+    END IF;
+    
+    IF (TG_OP = 'DELETE') THEN
+        SELECT locbal_update_location_itemsite(OLD.invdetail_location_id, invhist_itemsite_id, invhist_transdate::date)
+        INTO v_ret
+            FROM invhist WHERE invhist_id = OLD.invdetail_invhist_id;
+      
+        RETURN OLD;
+    END IF;
+    
+    RETURN NEW;
+    
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION _invhist_locbaltrigger()
+  OWNER TO admin;      
+--    
+--CREATE TRIGGER invhist_locbaltrigger
+--  AFTER INSERT OR UPDATE OR DELETE
+--  ON invdetail
+--  FOR EACH ROW
+--  EXECUTE PROCEDURE _invhist_locbaltrigger();
+
+DROP TRIGGER invhist_locbaltrigger ON invdetail;
\ No newline at end of file
diff --git a/pgsql/x-dragon-optimize.sql b/pgsql/x-dragon-optimize.sql
new file mode 100644 (file)
index 0000000..6febc3f
--- /dev/null
@@ -0,0 +1,95 @@
+
+-- indexes speed our list up..
+
+CREATE INDEX cohead_orderdate  ON cohead  USING btree  (cohead_orderdate);
+  
+CREATE INDEX itemloc_locsite  ON itemloc USING btree  (itemloc_itemsite_id, itemloc_location_id);
+
+-- this does not exist??  - what was it supposed to do?
+--CREATE INDEX itemsite_costcode_id_key   ON itemsite  USING btree  (itemsite_costcode_id );
+
+CREATE INDEX evntlog_stdcost_ix  ON evntlog USING btree  (evntlog_number, evntlog_evnttime, evntlog_evnttype_id);
+
+
+CREATE INDEX location_name_ix  ON location USING btree  (location_name);
+
+CREATE INDEX itemlocdist_series_idx  ON itemlocdist  USING btree  (itemlocdist_series);
+CREATE INDEX itemlocdist_itemlocdist_id_idx  ON itemlocdist  USING btree  (itemlocdist_itemlocdist_id);
+CREATE INDEX itemlocdist_source_type_idx  ON itemlocdist  USING btree  (itemlocdist_source_type);
+CREATE INDEX itemlocdist_itemsite_id_idx  ON itemlocdist  USING btree  (itemlocdist_itemsite_id);
+CREATE INDEX itemlocpost_itemlocseries_idx  ON itemlocpost  USING btree  (itemlocpost_itemlocseries);
+
+
+CREATE INDEX itemloc_ls_idx  ON itemloc   USING btree  (itemloc_ls_id);
+CREATE INDEX itemloc_expiration_idx  ON itemloc   USING btree  (itemloc_expiration);
+CREATE INDEX itemloc_warrpurc_idx  ON itemloc   USING btree  (itemloc_warrpurc);
+                   
+CREATE INDEX itemsite_controlmethod_idx     ON itemsite   USING btree  (itemsite_controlmethod);
+CREATE INDEX item_inv_uom_idx ON item USING btree  (item_inv_uom_id);
+-- post invoice / invoiceitem view speed?
+
+--CREATE INDEX invcitem_coitem_idx  ON invcitem USING btree  (invcitem_coitem_id);
+CREATE INDEX  shipitem_invcitem_idx  ON shipitem USING btree  (shipitem_invcitem_id);
+CREATE INDEX invcitem_coitem_idx  ON invcitem USING btree  (invcitem_coitem_id);
+
+
+-- from 4.0?
+DROP INDEX IF EXISTS invcitemtax_taxhist_parent_id_idx;
+CREATE INDEX invcitemtax_taxhist_parent_id_idx ON invcitemtax (taxhist_parent_id);
+
+
+CREATE INDEX item_type_ix  ON item  USING btree  (item_type);
+
+CREATE INDEX invchead_cust_id_idx  ON invchead  USING btree  (invchead_cust_id);
+
+
+CREATE INDEX shiphead_order_type_idx  ON shiphead USING btree  (shiphead_order_type);
+CREATE INDEX cust_partialship_backorder_idx  ON custinfo USING btree  (cust_partialship, cust_backorder);
+CREATE INDEX coitem_subnumber_warranty_qtyshipped_idx  ON coitem USING btree  (coitem_subnumber, coitem_warranty, coitem_qtyshipped);
+CREATE INDEX item_type_idx  ON item USING btree  (item_type);
+CREATE INDEX itemsite_controlmethod_costmethod_freeze_idx  ON itemsite USING btree  (itemsite_controlmethod, itemsite_costmethod, itemsite_freeze);
+CREATE INDEX salesaccnt_custtype_prodcat_idx  ON salesaccnt USING btree  (salesaccnt_custtype_id, salesaccnt_prodcat, salesaccnt_custtype);
+CREATE INDEX prodcat_code_idx  ON prodcat USING btree  (prodcat_code);
+CREATE INDEX custtype_code_idx  ON custtype USING btree  (custtype_code);
+CREATE INDEX period_start_end_idx  ON period USING btree  (period_start, period_end);
+CREATE INDEX yearperiod_start_end_idx  ON yearperiod USING btree  (yearperiod_start, yearperiod_end);
+CREATE INDEX accnt_type_idx  ON accnt USING btree  (accnt_type);
+CREATE INDEX itemloc_qty_expiration_warrpurc_ls_id_idx  ON itemloc USING btree  (itemloc_qty, itemloc_ls_id, itemloc_expiration, itemloc_warrpurc);
+CREATE INDEX metric_value_idx  ON metric USING btree  (metric_value);
+CREATE INDEX invhist_posted_idx  ON invhist USING btree  (invhist_posted);
+CREATE INDEX invbal_period_id_idx  ON invbal USING btree  (invbal_period_id);
+CREATE INDEX usrgrp_username_idx  ON usrgrp USING btree  (usrgrp_username);
+CREATE INDEX shipitem_invoiced_idx  ON shipitem USING btree  (shipitem_invoiced);
+CREATE INDEX aropenalloc_doctype  ON aropenalloc USING btree  (aropenalloc_doctype);
+CREATE INDEX invchead_posted_idx  ON invchead USING btree  (invchead_posted);
+CREATE INDEX orderseq_name_idx  ON orderseq USING btree  (orderseq_name);
+CREATE INDEX recv_posted  ON recv USING btree  (recv_posted);
+
+
+
+--- used to optimize last purchase price lookup
+
+
+CREATE INDEX  poitem_line_date  on poitem USING btree ( poitem_duedate, poitem_linenumber, poitem_pohead_id, poitem_itemsite_id);
+
+ CREATE INDEX  checkhead_checkdate_ix  on checkhead USING btree ( checkhead_checkdate);
+CREATE INDEX  checkhead_voided_ix on checkhead USING btree ( checkhead_void, checkhead_voided);
+
+CREATE INDEX checkhead_recip_type_ix on checkhead USING btree ( checkhead_recip_type);
+CREATE INDEX checkhead_journalnumber_ix on checkhead USING btree (               checkhead_journalnumber);
+
+CREATE INDEX apapply_journalnumber_ix on apapply USING btree (               apapply_journalnumber);
+CREATE INDEX apapply_checkhead_id_ix on apapply USING btree (               apapply_checkhead_id);
+
+CREATE INDEX apapply_target_apopen_id_ix on apapply USING btree (               apapply_target_apopen_id);
+CREATE INDEX apapply_source_apopen_id_ix on apapply USING btree (               apapply_source_apopen_id);
+
+CREATE INDEX apopen_closedate_ix on apopen USING btree (               apopen_closedate);
+CREATE INDEX apopen_distdate_ix on apopen USING btree (               apopen_distdate);
+
+CREATE INDEX apopen_discount_ix on apopen USING btree (               apopen_discount);
+CREATE INDEX apopen_notes_ix on apopen USING btree (               apopen_notes);
\ No newline at end of file
diff --git a/pgsql/x-dragon-period-temp-close.sql b/pgsql/x-dragon-period-temp-close.sql
new file mode 100644 (file)
index 0000000..5dae81b
--- /dev/null
@@ -0,0 +1,69 @@
+
+
+
+
+
+CREATE OR REPLACE FUNCTION  period_temp_close(i_id INTEGER)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_tmp INTEGER;
+    v_btmp BOOLEAN;
+    v_ret INTEGER;
+    
+    r_period RECORD;
+    r_invlocdist RECORD;
+    r_tmp RECORD;
+    
+    v_period_start DATE;
+    v_period_end DATE;
+    v_period_closed BOOLEAN;
+    v_period_freeze BOOLEAN;
+BEGIN
+
+    SELECT period_start INTO v_period_end  FROM period where period_id = i_id;
+    
+    PERFORM closeAccountingPeriod( period_id ) FROM
+        (SELECT
+                period_id
+            FROM
+                period
+            WHERE
+                NOT period_closed
+                AND
+                period_start <= v_period_end
+            ORDER BY
+                period_start ASC
+        ) x;
+    
+    
+    
+    
+    PERFORM freezeAccountingPeriod(period_id) FROM
+        (SELECT
+                period_id
+            FROM
+                period
+            WHERE
+                NOT period_freeze
+                AND
+                period_start <= v_period_end
+            ORDER BY
+                period_start ASC
+        ) x;
+    
+        --IF v_tmp < 0 THEN
+        --    RAISE EXCEPTION 'open period returned %', v_tmp;
+        --END IF;
+    
+    RETURN 0;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  period_temp_close(  INTEGER)
+  OWNER TO admin;    
+
+
diff --git a/pgsql/x-dragon-period-temp-open.sql b/pgsql/x-dragon-period-temp-open.sql
new file mode 100644 (file)
index 0000000..fec3176
--- /dev/null
@@ -0,0 +1,102 @@
+
+CREATE OR REPLACE FUNCTION  period_temp_open(i_target_dt DATE)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_tmp INTEGER;
+    v_btmp BOOLEAN;
+    v_ret INTEGER;
+    
+    r_period RECORD;
+    r_invlocdist RECORD;
+    r_tmp RECORD;
+    
+    v_period_start DATE;
+    v_period_end DATE;
+    v_period_closed BOOLEAN;
+    v_period_freeze BOOLEAN;
+BEGIN
+
+    
+    SELECT
+            period_start INTO v_period_start
+        FROM
+            period
+        WHERE
+            period_start <= i_target_dt
+            AND
+            period_end >= i_target_dt
+        LIMIT 1;
+    
+    
+    SELECT
+            period_closed,  period_freeze
+            INTO
+            v_period_closed, v_period_freeze
+        FROM
+            period
+        WHERE
+            period_start = v_period_start;
+    
+    
+    
+    --RAISE NOTICE 'period state is % ', v_period_closed;
+    
+    IF NOT v_period_closed AND NOT v_period_freeze THEN
+        RETURN 0;
+    END IF;
+    
+    SELECT
+            period_start INTO v_period_end
+        FROM
+            period
+        WHERE
+            period_closed
+        ORDER BY
+            period_start DESC LIMIT 1;
+
+    --RAISE NOTICE 'opening periods between % and %', v_period_start, v_period_end;
+    
+    PERFORM thawAccountingPeriod(period_id) FROM
+        (SELECT
+                period_id
+            FROM
+                period
+            WHERE
+                period_start >= v_period_start
+                AND
+                period_start <= v_period_end
+            ORDER BY
+                period_start DESC
+        ) x;
+    
+    PERFORM openAccountingPeriod( period_id ) FROM
+        (SELECT
+                period_id
+            FROM
+                period
+            WHERE
+                period_start >= v_period_start
+                AND
+                period_start <= v_period_end
+            ORDER BY
+                period_start DESC
+        ) x;
+    
+        --IF v_tmp < 0 THEN
+        --    RAISE EXCEPTION 'open period returned %', v_tmp;
+        --END IF;
+    
+    SELECT period_id INTO v_ret FROM period where period_start = v_period_end LIMIT 1;
+    RETURN v_ret;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  period_temp_open(  DATE)
+  OWNER TO admin;    
+
+
+
diff --git a/pgsql/x-dragon-pohead.sql b/pgsql/x-dragon-pohead.sql
new file mode 100644 (file)
index 0000000..614d448
--- /dev/null
@@ -0,0 +1,43 @@
+
+
+alter table pohead add column pohead_location_id INTEGER DEFAULT 0;
+
+CREATE INDEX pohead_location_id_ix  ON pohead USING btree  (pohead_location_id);
+
+alter table pohead add column pohead_bg_va TEXT;
+
+alter table pohead add column pohead_bg_arrival_est_day DATE;
+
+alter table pohead add column pohead_bg_available_est_day DATE;
+
+alter table pohead add column pohead_bg_available_latest_day DATE;
+
+alter table pohead add column pohead_last_updated DATE;
+
+alter table pohead add column pohead_notes TEXT;
+
+
+CREATE OR REPLACE FUNCTION pohead_last_updated() RETURNS trigger 
+AS $BODY$
+DECLARE
+     
+BEGIN
+    
+    NEW.pohead_last_updated := NOW()::DATE;
+      
+    RETURN NEW;   
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  pohead_last_updated()
+  OWNER TO admin;
+
+
+CREATE TRIGGER _pohead_last_updated 
+    BEFORE INSERT OR UPDATE ON pohead
+        FOR EACH ROW EXECUTE PROCEDURE pohead_last_updated();
+
+
diff --git a/pgsql/x-dragon-poitem.sql b/pgsql/x-dragon-poitem.sql
new file mode 100644 (file)
index 0000000..2de4f1e
--- /dev/null
@@ -0,0 +1,3 @@
+alter table poitem add column poitem_location_id INTEGER DEFAULT 0;
+
+CREATE INDEX poitem_location_id_ix  ON poitem USING btree  (poitem_location_id);
\ No newline at end of file
diff --git a/pgsql/x-dragon-postinvtransfixed.sql b/pgsql/x-dragon-postinvtransfixed.sql
new file mode 100644 (file)
index 0000000..91d1586
--- /dev/null
@@ -0,0 +1,237 @@
+-- this is a slight modification of postinvtrans
+-- it forces the cost to be based on the pCostOvrld.
+
+
+-- Function: postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer)
+
+-- DROP FUNCTION postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer);
+
+CREATE OR REPLACE FUNCTION dragon_postinvtransfixed(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer)
+  RETURNS integer AS
+$BODY$
+DECLARE
+  pItemsiteid       ALIAS FOR $1;
+  pTransType        ALIAS FOR $2;
+  pQty              ALIAS FOR $3;
+  pModule           ALIAS FOR $4;
+  pOrderType        ALIAS FOR $5;
+  pOrderNumber      ALIAS FOR $6;
+  pDocNumber        ALIAS FOR $7;
+  pComments         ALIAS FOR $8;
+  pDebitid          ALIAS FOR $9;
+  pCreditid         ALIAS FOR $10;
+  pItemlocSeries     ALIAS FOR $11;
+  pTimestamp         TIMESTAMP WITH TIME ZONE := $12;
+  pCostOvrld         ALIAS FOR $13;
+  pInvhistid         ALIAS FOR $14;  -- original transaction to be returned, reversed, etc.
+
+  _creditid         INTEGER;
+  _debitid          INTEGER;
+  _glreturn         INTEGER;
+  _invhistid        INTEGER;
+  _itemlocdistid     INTEGER;
+  _r                RECORD;
+  _sense            INTEGER;  -- direction in which to adjust inventory QOH
+  _t                RECORD;
+  _xferwhsid        INTEGER;
+
+BEGIN
+
+  --  Cache item and itemsite info  
+  SELECT  COALESCE(abs(pCostOvrld / pQty),  stdCost(itemsite_item_id)) AS cost,
+         itemsite_costmethod,
+         itemsite_qtyonhand,
+        itemsite_warehous_id,
+         ( (item_type = 'R') OR (itemsite_controlmethod = 'N') ) AS nocontrol,
+         (itemsite_controlmethod IN ('L', 'S')) AS lotserial,
+         (itemsite_loccntrl) AS loccntrl,
+         itemsite_freeze AS frozen INTO _r
+  FROM itemsite JOIN item ON (item_id=itemsite_item_id)
+  WHERE (itemsite_id=pItemsiteid);
+
+  --  Post the Inventory Transactions
+  IF (NOT _r.nocontrol) THEN
+
+    IF (COALESCE(pItemlocSeries,0) = 0) THEN
+      RAISE EXCEPTION 'Transaction series must be provided';
+    END IF;
+
+    SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
+
+    IF ((pTimestamp IS NULL) OR (CAST(pTimestamp AS date)=CURRENT_DATE)) THEN
+      pTimestamp := CURRENT_TIMESTAMP;
+    END IF;
+
+    IF (pTransType = 'TS' OR pTransType = 'TR') THEN
+      SELECT * INTO _t FROM tohead WHERE (tohead_number=pDocNumber);
+      IF (pTransType = 'TS') THEN
+       _xferwhsid := CASE
+           WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+           WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_src_warehous_id
+           WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_dest_warehous_id
+           WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+           ELSE NULL
+           END;
+      ELSIF (pTransType = 'TR') THEN
+       _xferwhsid := CASE
+           WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+           WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_dest_warehous_id
+           WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_src_warehous_id
+           WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
+           ELSE NULL
+           END;
+      END IF;
+    END IF;
+
+
+    -- increase inventory: AD RM RT RP RR RS RX RB TR
+    -- decrease inventory: IM IB IT SH SI EX RI
+    -- TS and TR are special: shipShipment and recallShipment should not change
+    -- QOH at the Transfer Order src whs (as this was done by issueToShipping)
+    -- but postReceipt should change QOH at the transit whs
+    IF (pTransType='TS') THEN
+      _sense := CASE WHEN (SELECT tohead_trns_warehous_id=_r.itemsite_warehous_id
+                          FROM tohead
+                          WHERE (tohead_number=pDocNumber)) THEN -1
+                          ELSE 0
+                          END;
+    ELSIF (pTransType='TR') THEN
+      _sense := CASE WHEN (SELECT tohead_src_warehous_id=_r.itemsite_warehous_id
+                          FROM tohead
+                          WHERE (tohead_number=pDocNumber)) THEN 0
+                          ELSE 1
+                          END;
+    ELSIF (pTransType IN ('IM', 'IB', 'IT', 'SH', 'SI', 'EX', 'RI')) THEN
+      _sense := -1;
+
+    ELSE
+      _sense := 1;
+    END IF;
+
+    IF((_r.itemsite_costmethod='A') AND (_r.itemsite_qtyonhand + (_sense * pQty)) < 0) THEN
+      -- Can not let average costed itemsites go negative
+      RAISE EXCEPTION 'This transaction will cause an Average Costed item to go negative which is not allowed.';
+      RETURN -2;
+    END IF;
+
+    INSERT INTO invhist
+    ( invhist_id, invhist_itemsite_id, invhist_transtype, invhist_transdate,
+      invhist_invqty, invhist_qoh_before,
+      invhist_qoh_after,
+      invhist_costmethod, invhist_value_before, invhist_value_after,
+      invhist_ordtype, invhist_ordnumber, invhist_docnumber, invhist_comments,
+      invhist_invuom, invhist_unitcost, invhist_xfer_warehous_id, invhist_posted,
+      invhist_series )
+    SELECT
+      _invhistid, itemsite_id, pTransType, pTimestamp,
+      pQty, itemsite_qtyonhand,
+      (itemsite_qtyonhand + (_sense * pQty)),
+      itemsite_costmethod, itemsite_value, itemsite_value + pCostOvrld,
+      pOrderType, pOrderNumber, pDocNumber, pComments,
+      uom_name, _r.cost, _xferwhsid, FALSE, pItemlocSeries
+    FROM itemsite, item, uom
+    WHERE ( (itemsite_item_id=item_id)
+     AND (item_inv_uom_id=uom_id)
+     AND (itemsite_id=pItemsiteid) );
+
+    IF (pCreditid IN (SELECT accnt_id FROM accnt)) THEN
+      _creditid = pCreditid;
+    ELSE
+      SELECT warehous_default_accnt_id INTO _creditid
+      FROM itemsite, warehous
+      WHERE ( (itemsite_warehous_id=warehous_id)
+        AND  (itemsite_id=pItemsiteid) );
+    END IF;
+
+    IF (pDebitid IN (SELECT accnt_id FROM accnt)) THEN
+      _debitid = pDebitid;
+    ELSE
+      SELECT warehous_default_accnt_id INTO _debitid
+      FROM itemsite, warehous
+      WHERE ( (itemsite_warehous_id=warehous_id)
+        AND  (itemsite_id=pItemsiteid) );
+    END IF;
+
+
+--  Post the G/L Transaction
+    IF (_creditid <> _debitid) THEN
+      SELECT insertGLTransaction(pModule, pOrderType, pOrderNumber, pComments,
+                                _creditid, _debitid, _invhistid,
+                                abs(pCostOvrld), pTimestamp::DATE, FALSE) INTO _glreturn;
+    END IF;
+
+    --  Distribute this if this itemsite is controlled
+    IF ( _r.lotserial OR _r.loccntrl ) THEN
+
+      _itemlocdistid := nextval('itemlocdist_itemlocdist_id_seq');
+      INSERT INTO itemlocdist
+      ( itemlocdist_id,
+        itemlocdist_itemsite_id,
+        itemlocdist_source_type,
+        itemlocdist_reqlotserial,
+        itemlocdist_distlotserial,
+        itemlocdist_expiration,
+        itemlocdist_qty,
+        itemlocdist_series,
+        itemlocdist_invhist_id,
+        itemlocdist_order_type,
+        itemlocdist_order_id )
+      SELECT _itemlocdistid,
+             pItemsiteid,
+             'O',
+             (((pQty * _sense) > 0)  AND _r.lotserial),
+            ((pQty * _sense) < 0),
+             endOfTime(),
+             (_sense * pQty),
+             pItemlocSeries,
+             _invhistid,
+             pOrderType, 
+             CASE WHEN pOrderType='SO' THEN getSalesLineItemId(pOrderNumber)
+                  ELSE NULL
+             END;
+
+      -- populate distributions if invhist_id parameter passed to undo
+      IF (pInvhistid IS NOT NULL) THEN
+        INSERT INTO itemlocdist
+          ( itemlocdist_itemlocdist_id, itemlocdist_source_type, itemlocdist_source_id,
+            itemlocdist_itemsite_id, itemlocdist_ls_id, itemlocdist_expiration,
+            itemlocdist_qty, itemlocdist_series, itemlocdist_invhist_id ) 
+        SELECT _itemlocdistid, 'L', COALESCE(invdetail_location_id, -1),
+               invhist_itemsite_id, invdetail_ls_id,  COALESCE(invdetail_expiration, endoftime()),
+               (invdetail_qty * -1.0), pItemlocSeries, _invhistid
+        FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
+        WHERE (invhist_id=pInvhistid);
+
+        IF ( _r.lotserial)  THEN          
+          INSERT INTO lsdetail 
+            ( lsdetail_itemsite_id, lsdetail_ls_id, lsdetail_created,
+              lsdetail_source_type, lsdetail_source_id, lsdetail_source_number ) 
+          SELECT invhist_itemsite_id, invdetail_ls_id, CURRENT_TIMESTAMP,
+                 'I', _itemlocdistid, ''
+          FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
+          WHERE (invhist_id=pInvhistid);
+        END IF;
+
+        PERFORM distributeitemlocseries(pItemlocSeries);
+        
+      END IF;
+
+    END IF;   -- end of distributions
+
+  -- These records will be used for posting G/L transactions to trial balance after records committed.
+  -- If we try to do it now concurrency locking prevents any transacitons while
+  -- user enters item distribution information.  Cant have that.
+    INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
+    VALUES ( _glreturn, pItemlocSeries );
+
+    RETURN _invhistid;
+  ELSE
+    RETURN -1;
+  END IF;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION postinvtrans(integer, text, numeric, text, text, text, text, text, integer, integer, integer, timestamp with time zone, numeric, integer)
+  OWNER TO admin;
diff --git a/pgsql/x-dragon-recvgrp.sql b/pgsql/x-dragon-recvgrp.sql
new file mode 100644 (file)
index 0000000..d95301f
--- /dev/null
@@ -0,0 +1,93 @@
+--
+-- Table to group recv's into
+
+
+
+CREATE SEQUENCE recvgrp_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE recvgrp_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE recvgrp_id_seq TO admin;
+GRANT ALL ON TABLE recvgrp_id_seq TO xtrole;
+
+
+
+CREATE TABLE recvgrp
+(
+
+    recvgrp_id integer NOT NULL DEFAULT nextval(('recvgrp_id_seq'::text)::regclass),
+    recvgrp_number text NOT NULL,
+  
+    recvgrp_landed_cost numeric(12,4) DEFAULT 0.0,
+    recvgrp_landed_method TEXT DEFAULT 'Q',
+  
+    recvgrp_date date,
+    recvgrp_pohead_id INTEGER,
+    recvgrp_landed_curr_id INTEGER,
+    recvgrp_location_id INTEGER,
+  
+  
+  
+
+  CONSTRAINT recvgrp_pkey PRIMARY KEY (recvgrp_id )
+)
+WITH (
+  OIDS=FALSE
+);
+ALTER TABLE recvgrp
+  OWNER TO admin;
+GRANT ALL ON TABLE recvgrp TO admin;
+GRANT ALL ON TABLE recvgrp TO xtrole;
+COMMENT ON TABLE recvgrp
+  IS 'Information about Groups of Received Order Items.';
+  
+  
+ALTER TABLE recvgrp ADD COLUMN recvgrp_date date;
+ALTER TABLE recvgrp ADD COLUMN recvgrp_pohead_id INTEGER;
+ALTER TABLE recvgrp ADD COLUMN recvgrp_landed_curr_id INTEGER;
+ALTER TABLE recvgrp ADD COLUMN recvgrp_location_id INTEGER;
+ALTER TABLE recvgrp ADD COLUMN recvgrp_void INTEGER;
+
+
+ALTER TABLE recvgrp ADD CONSTRAINT recvgrp_location_id_fkey FOREIGN KEY (recvgrp_location_id)
+        REFERENCES location(location_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;  
+
+ALTER TABLE recvgrp ADD CONSTRAINT recvgrp_pohead_id_fkey FOREIGN KEY (recvgrp_pohead_id)
+        REFERENCES pohead(pohead_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;  
+
+ALTER TABLE recvgrp ADD CONSTRAINT  revgrp_landed_curr_symbol  FOREIGN KEY (recvgrp_landed_curr_id)
+        REFERENCES curr_symbol(curr_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;  
+
+
+
+CREATE UNIQUE INDEX recvgrp_number_idx
+  ON recvgrp 
+  USING btree
+  (recvgrp_number COLLATE pg_catalog."default" );
+
+
+  
+ALTER TABLE recv ADD COLUMN recv_recvgrp_id INTEGER;
+
+
+
+--UPDATE recvgrp SET recvgrp_pohead_id =
+--    (SELECT max(poitem_pohead_id) FROM poitem where poitem_id IN ( SELECT recv_orderitem_id FROM recv WHERE recv_recvgrp_id = recvgrp_id) )
+--    WHERE recvgrp_pohead_id IS NULL;
+
+
+
+CREATE INDEX recv_recvgrp_id_ix  ON recv  USING btree  (recv_recvgrp_id);
+
+ALTER TABLE recv ADD CONSTRAINT recv_recvgrp_id_fkey FOREIGN KEY (recv_recvgrp_id)
+        REFERENCES recvgrp(recvgrp_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;
diff --git a/pgsql/x-dragon-recvgrpland.sql b/pgsql/x-dragon-recvgrpland.sql
new file mode 100644 (file)
index 0000000..d8e02c3
--- /dev/null
@@ -0,0 +1,53 @@
+--
+-- Table to group recv's into
+
+
+
+CREATE SEQUENCE recvgrpland_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE recvgrpland_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE recvgrpland_id_seq TO admin;
+GRANT ALL ON TABLE recvgrpland_id_seq TO xtrole;
+
+
+
+CREATE TABLE recvgrpland
+(
+
+    recvgrpland_id integer NOT NULL DEFAULT nextval(('recvgrpland_id_seq'::text)::regclass),
+    recvgrpland_vohead_id INTEGER,
+      recvgrpland_recvgrp_id INTEGER,
+    recvgrpland_curr_id INTEGER,
+    recvgrpland_cost numeric(12,4) DEFAULT 0.0,
+    recvgrpland_method TEXT DEFAULT 'Q',
+    recvgrpland_glseries INTEGER DEFAULT 0,
+  
+  CONSTRAINT recvgrpland_pkey PRIMARY KEY (recvgrpland_id )
+)
+WITH (
+  OIDS=FALSE
+);
+ALTER TABLE recvgrpland
+  OWNER TO admin;
+GRANT ALL ON TABLE recvgrpland TO admin;
+GRANT ALL ON TABLE recvgrpland TO xtrole;
+COMMENT ON TABLE recvgrpland
+  IS 'Map of landed costs to received group';
+  
+  
+
+ALTER TABLE recvgrpland ADD CONSTRAINT recvgrpland_vohead_id_fkey FOREIGN KEY (recvgrpland_vohead_id)
+        REFERENCES vohead(vohead_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;  
+
+ALTER TABLE recvgrpland ADD CONSTRAINT recvgrpland_recvgrp_id_fkey FOREIGN KEY (recvgrpland_recvgrp_id)
+        REFERENCES recvgrp(recvgrp_id) MATCH SIMPLE
+      ON UPDATE CASCADE ON DELETE NO ACTION;  
+--CREATE INDEX recv_recvgrp_id_ix  ON recv  USING btree  (recv_recvgrp_id);
diff --git a/pgsql/x-dragon-salesforecast.sql b/pgsql/x-dragon-salesforecast.sql
new file mode 100644 (file)
index 0000000..690fe65
--- /dev/null
@@ -0,0 +1,42 @@
+
+CREATE SEQUENCE salesforecast_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+CREATE TABLE salesforecast (
+    salesforecast_id INTEGER NOT NULL DEFAULT nextval(('salesforecast_id_seq'::text)::regclass),
+    salesforecast_itemsite_id integer,
+    salesforecast_period_id integer,
+    
+    salesforecast_qty integer,
+    
+    salesforecast_updated_by integer,
+    
+    CONSTRAINT salesforecast_itemsite_id_fkey FOREIGN KEY (salesforecast_itemsite_id)
+        REFERENCES itemsite  (itemsite_id)  MATCH SIMPLE,
+    
+    
+    CONSTRAINT salesforecast_period_id_fkey FOREIGN KEY (salesforecast_period_id)
+        REFERENCES period (period_id)  MATCH SIMPLE,
+        
+    CONSTRAINT salesforecast_updated_by_fkey FOREIGN KEY (salesforecast_updated_by)
+        REFERENCES person (id),
+    CONSTRAINT salesforecast_id_pkey PRIMARY KEY (salesforecast_id)
+);
+
+ALTER TABLE salesforecast ADD COLUMN salesforecast_cust_id integer;
+ALTER TABLE salesforecast ADD COLUMN salesforecast_is_all_buyers BOOLEAN;
+ALTER TABLE salesforecast ADD COLUMN salesforecast_sum integer;
+ALTER TABLE salesforecast ADD COLUMN salesforecast_requests integer;
+
+ALTER TABLE salesforecast DROP CONSTRAINT salesforecast_cust_id_fkey;
+-- ALTER TABLE salesforecast ADD CONSTRAINT salesforecast_cust_id_fkey FOREIGN KEY (salesforecast_cust_id)
+--         REFERENCES custinfo  (cust_id)  MATCH SIMPLE;
+DROP INDEX salesforecast_locsite_idx;
+CREATE UNIQUE INDEX salesforecast_locsite_idx  ON salesforecast USING btree  (salesforecast_itemsite_id, salesforecast_period_id,salesforecast_cust_id,salesforecast_is_all_buyers);
+
+ALTER TABLE public.salesforecast OWNER TO admin;
+COMMENT ON TABLE salesforecast IS 'Sale Forecast';
\ No newline at end of file
diff --git a/pgsql/x-dragon-salesorder-planning.sql b/pgsql/x-dragon-salesorder-planning.sql
new file mode 100644 (file)
index 0000000..c9a7d4b
--- /dev/null
@@ -0,0 +1,82 @@
+
+-- we use target date as a proxy for ship date in planning stuff.  
+ALTER TABLE cohead ADD COLUMN cohead_targetdate DATE;
+CREATE INDEX cohead_targetdate  ON cohead   USING btree  (cohead_targetdate);  
+
+
+-- store intended source in coitem and default in cohead - can be null..
+ALTER TABLE coitem ADD COLUMN coitem_location_src INTEGER DEFAULT NULL;
+ALTER TABLE coitem ADD CONSTRAINT coitem_location_src
+        FOREIGN KEY ( coitem_location_src ) REFERENCES location (location_id)
+        MATCH SIMPLE;
+        
+
+-- store intended destination on (defaults to matching cohead..)
+ALTER TABLE coitem ADD COLUMN coitem_shipto_id INTEGER DEFAULT NULL;
+ALTER TABLE coitem ADD CONSTRAINT coitem_shipto_id
+        FOREIGN KEY ( coitem_shipto_id )  REFERENCES shiptoinfo(shipto_id)
+        MATCH SIMPLE;
+        
+        
+        
+ALTER TABLE cohead ADD COLUMN cohead_location_src INTEGER;
+ALTER TABLE cohead ADD CONSTRAINT cohead_location_src
+        FOREIGN KEY ( cohead_location_src ) REFERENCES location (location_id)
+        MATCH SIMPLE;
+
+
+-- changes to ship head so they ship per locations..
+
+
+ALTER TABLE shiphead ADD COLUMN shiphead_location_id INT;
+ALTER TABLE shiphead ADD CONSTRAINT shiphead_location_id
+        FOREIGN KEY ( shiphead_location_id ) REFERENCES location (location_id)
+        MATCH SIMPLE;
+        
+        
+ALTER TABLE shiphead ADD COLUMN shiphead_shipto_id INT;
+ALTER TABLE shiphead ADD CONSTRAINT shiphead_shipto_id
+        FOREIGN KEY ( shiphead_shipto_id )  REFERENCES shiptoinfo(shipto_id)
+        MATCH SIMPLE;
+
+
+CREATE INDEX shiphead_shipto_id_ix  ON shiphead   USING btree  (shiphead_shipto_id);
+CREATE INDEX shiphead_location_id_ix  ON shiphead   USING btree  (shiphead_location_id);  
+
+ALTER TABLE cmhead ADD COLUMN cmhead_billto_cntct_id integer;
+ALTER TABLE cmhead ADD COLUMN cmhead_billto_addr_id integer;
+ALTER TABLE cmhead ADD COLUMN cmhead_location_id integer;
+
+
+
+
+
+ALTER TABLE cmhead
+  ADD CONSTRAINT cmhead_cmhead_billto_cntct_id_fkey FOREIGN KEY (cmhead_billto_cntct_id)
+      REFERENCES cntct (cntct_id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
+
+ALTER TABLE cmhead
+  ADD CONSTRAINT cmhead_cmhead_salesrep_id_fkey FOREIGN KEY (cmhead_salesrep_id)
+      REFERENCES salesrep (salesrep_id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
+
+ALTER TABLE cmhead
+  ADD CONSTRAINT cmhead_cmhead_taxzone_id_fkey FOREIGN KEY (cmhead_taxzone_id)
+      REFERENCES taxzone (taxzone_id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
+
+ALTER TABLE cmhead
+  ADD CONSTRAINT cmhead_cmhead_location_id FOREIGN KEY (cmhead_location_id)
+      REFERENCES location (location_id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
+
+ALTER TABLE cmitem 
+  ADD CONSTRAINT cmitem_itemsite_id FOREIGN KEY (cmitem_itemsite_id)
+      REFERENCES itemsite (itemsite_id) MATCH SIMPLE
+      ON UPDATE NO ACTION ON DELETE NO ACTION;
+
+-- bills - add a revision number..
+
+ALTER TABLE cobmisc ADD COLUMN cobmisc_rev INT DEFAULT 0;
+ALTER TABLE shiphead ADD COLUMN shiphead_rev INT DEFAULT 0;
diff --git a/pgsql/x-dragon-salesordercalcs.sql b/pgsql/x-dragon-salesordercalcs.sql
new file mode 100644 (file)
index 0000000..bb08633
--- /dev/null
@@ -0,0 +1,353 @@
+---  Calc value tax on an order..
+
+      
+  
+CREATE OR REPLACE FUNCTION calcsalesordertax(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _tax NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(tax), 0) INTO _tax
+  FROM ( SELECT ROUND(SUM(taxdetail_tax), 2) AS tax
+         FROM tax JOIN calculateTaxDetailSummary('S', pCoheadid, 'T') ON (taxdetail_tax_id=tax_id)
+         GROUP BY tax_id ) AS data;
+
+  
+  RETURN _tax;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesordertax(integer)
+  OWNER TO admin;
+  
+    
+    
+    
+    
+--  Calc value of order items
+
+    
+    
+    
+CREATE OR REPLACE FUNCTION calcsalesordersubtotal(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio) *
+                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
+  FROM coitem
+  WHERE (coitem_cohead_id=pCoheadid);
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesordersubtotal(integer)
+  OWNER TO admin;
+
+
+
+  
+  
+ -- calcs the discount based on the value of the Z-LIST-DISCOUNT item(s)   
+CREATE OR REPLACE FUNCTION calcsalesorderlistdiscount(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio) *
+                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
+  FROM coitem
+  WHERE
+    (coitem_cohead_id=pCoheadid)
+    AND
+    coitem_itemsite_id IN (
+            SELECT itemsite_id FROM itemsite LEFT JOIN item ON itemsite_item_id = item_id WHERE item_number ='Z-LIST-DISCOUNT'
+    );
+    
+  
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderlistdiscount(integer)
+  OWNER TO admin;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-- qty..
+
+CREATE OR REPLACE FUNCTION calcsalesorderqty(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio)  , 2)), 0) INTO _subtotal
+  FROM coitem
+  WHERE (coitem_cohead_id=pCoheadid);
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderqty(integer)
+ OWNER TO admin;
+
+
+  ---  Calc how much has been shipped..
+   
+     
+CREATE OR REPLACE FUNCTION calcsalesordershipped(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(ROUND((shipitem_qty * coitem_qty_invuomratio) *
+                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
+        FROM shipitem
+            LEFT JOIN shiphead ON shipitem_shiphead_id = shiphead_id
+            LEFT JOIN coitem ON shipitem_orderitem_id = coitem_id
+            
+  WHERE (coitem_cohead_id=pCoheadid) AND (shiphead_shipped = true);
+  
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesordershipped(integer)
+  OWNER TO admin;
+
+--qty  
+CREATE OR REPLACE FUNCTION calcsalesordershippedqty(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+  
+  SELECT COALESCE(SUM(ROUND((shipitem_qty * coitem_qty_invuomratio)  , 2)), 0) INTO _subtotal
+  FROM shipitem LEFT JOIN coitem ON shipitem_orderitem_id = coitem_id
+  LEFT JOIN shiphead ON shipitem_shiphead_id = shiphead_id
+  WHERE (coitem_cohead_id=pCoheadid) AND (shiphead_shipped = true);
+  
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesordershippedqty(integer)
+  OWNER TO admin;
+   
+  
+--  Calc how much has can not be shipped. (currenly only checks 'R' item_type)
+     
+CREATE OR REPLACE FUNCTION calcsalesorderunshipable(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+  
+   
+  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio) *
+                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
+  FROM coitem
+  LEFT JOIN
+    itemsite
+    ON
+    itemsite_id = coitem_itemsite_id
+  LEFT JOIN
+    item
+    ON
+    item_id = itemsite_item_id
+    
+  WHERE (coitem_cohead_id=pCoheadid)
+  AND
+    item_type != 'P' 
+  ;
+  RETURN _subtotal;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderunshipable(integer)
+  OWNER TO admin;
+  
+
+
+
+CREATE OR REPLACE FUNCTION calcsalesorderunshipableqty(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+  
+   
+  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio)  , 2)), 0) INTO _subtotal
+  FROM coitem
+  LEFT JOIN
+    itemsite
+    ON
+    itemsite_id = coitem_itemsite_id
+  LEFT JOIN
+    item
+    ON
+    item_id = itemsite_item_id
+    
+  WHERE (coitem_cohead_id=pCoheadid)
+  AND
+    item_type != 'P' 
+  ;
+  RETURN _subtotal;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderunshipableqty(integer)
+  OWNER TO admin;
+  
+
+
+
+  
+  CREATE OR REPLACE FUNCTION calcsalesorderinvoiced(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+-- This would actually get the real invoice totals..
+-- using aropen...
+--  SELECT COALESCE(SUM(ROUND( invoiceTotal(invchead)) as _subtotal
+--    FROM
+--        invchead ON invcitem_invchead_id = invchead_id
+--          LEFT JOIN coitem ON invcitem_coitem_id = coitem_id 
+--    WHERE (coitem_cohead_id=pCoheadid) AND  invchead_void = false;
+  
+  
+  SELECT COALESCE(SUM(ROUND((invcitem_billed * coitem_qty_invuomratio) *
+                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
+  FROM invcitem
+     LEFT JOIN invchead ON invcitem_invchead_id = invchead_id
+     LEFT JOIN coitem ON invcitem_coitem_id = coitem_id 
+  WHERE (coitem_cohead_id=pCoheadid) AND  invchead_void = false;
+  
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderinvoiced(integer)
+  OWNER TO admin;
+  
+  
+   
+   
+  
+  CREATE OR REPLACE FUNCTION calcsalesorderinvoicedqty(integer)
+  RETURNS numeric AS
+$BODY$
+DECLARE
+  pCoheadid ALIAS FOR $1;
+  _subtotal NUMERIC := 0;
+  
+BEGIN
+
+-- This would actually get the real invoice totals..
+-- using aropen...
+--  SELECT COALESCE(SUM(ROUND( invoiceTotal(invchead)) as _subtotal
+--    FROM
+--        invchead ON invcitem_invchead_id = invchead_id
+--          LEFT JOIN coitem ON invcitem_coitem_id = coitem_id 
+--    WHERE (coitem_cohead_id=pCoheadid) AND  invchead_void = false;
+  
+  
+  SELECT COALESCE(SUM(ROUND((invcitem_billed * coitem_qty_invuomratio)  , 2)), 0) INTO _subtotal
+  FROM invcitem
+     LEFT JOIN invchead ON invcitem_invchead_id = invchead_id
+     LEFT JOIN coitem ON invcitem_coitem_id = coitem_id 
+  WHERE (coitem_cohead_id=pCoheadid) AND  invchead_void = false;
+  
+  RETURN _subtotal;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION calcsalesorderinvoicedqty(integer)
+  OWNER TO admin;
+  
+  
+   
+  
+
diff --git a/pgsql/x-dragon-setbankreccleared.sql b/pgsql/x-dragon-setbankreccleared.sql
new file mode 100644 (file)
index 0000000..6d2445d
--- /dev/null
@@ -0,0 +1,108 @@
+---quick way to set clearance..
+
+-- call setbankreccleared()
+
+CREATE OR REPLACE FUNCTION setbankreccleared(integer, text, integer, boolean)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  pBankrecid ALIAS FOR $1;
+  pSource    ALIAS FOR $2;
+  pSourceid  ALIAS FOR $3;
+  _cleared  ALIAS FOR $4;
+  v_rate    NUMERIC;
+  v_curr_id    INTEGER;
+  v_basecurr_id    INTEGER;
+  v_date  DATE;
+  v_amount  NUMERIC;
+  _r RECORD;
+
+BEGIN
+
+  SELECT bankrecitem_id, bankrecitem_cleared INTO _r
+    FROM bankrecitem
+   WHERE ( (bankrecitem_bankrec_id=pBankrecid)
+     AND   (bankrecitem_source=pSource)
+     AND   (bankrecitem_source_id=pSourceid) );
+     
+     
+     
+  IF ( NOT FOUND ) THEN
+    
+    
+    SELECT
+        bankaccnt_curr_id,
+        basecurrid(),
+        gltrans_date,
+        gltrans_amount
+        INTO
+        v_curr_id,
+        v_basecurr_id,
+        v_date,
+        v_amount
+        FROM 
+    
+          gltrans
+              
+              LEFT JOIN
+                  bankaccnt
+              ON
+                  bankaccnt_accnt_id = gltrans_accnt_id
+              WHERE
+                  gltrans_id = pSourceid;
+
+    v_rate := 1.0;
+     --RAISE NOTICE   'gltransid = %, bank cur =%, base_curr= % curr_rate = %', pSourceid,  v_curr_id, v_basecurr_id, v_rate;       
+    IF v_curr_id != v_basecurr_id THEN
+        SELECT currrate(v_curr_id, v_date) INTO v_rate;
+    END IF;
+    --RAISE EXCEPTION 'gltransid = %, bank cur =%, base_curr= % curr_rate = %', pSourceid,  v_curr_id, v_basecurr_id, v_rate;       
+      
+    INSERT INTO bankrecitem
+      (bankrecitem_bankrec_id, bankrecitem_source,
+       bankrecitem_source_id, bankrecitem_cleared  ,
+       
+      bankrecitem_curr_rate,
+       
+        bankrecitem_amount
+       ) VALUES (
+          pBankrecid, pSource,
+           pSourceid, _cleared ,
+       
+      v_rate, abs(v_amount) * v_rate
+  );
+  ELSE
+    
+    UPDATE bankrecitem
+       SET bankrecitem_cleared=_cleared
+     WHERE (bankrecitem_id=_r.bankrecitem_id);
+  END IF;
+
+  RETURN _cleared;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION setbankreccleared(integer, text, integer,boolean)
+  OWNER TO admin;
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+   
+  
+  
+  
+  
+  
+  
+  
+  
+  
\ No newline at end of file
diff --git a/pgsql/x-dragon-trialbal-fix.sql b/pgsql/x-dragon-trialbal-fix.sql
new file mode 100644 (file)
index 0000000..cf81617
--- /dev/null
@@ -0,0 +1,717 @@
+--rebuild trialbal... -- after an oops in AU..
+
+
+
+
+-- fill in any missing trailbalances...
+
+
+
+CREATE OR REPLACE FUNCTION trialbal_check_account(i_accnt_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+    v_start date;
+    v_end date;
+
+BEGIN
+    select
+            min(period_start),
+            max(period_start)
+        INTO
+            v_start,
+            v_end
+        FROM
+            trialbal
+        LEFT JOIN
+            period
+        ON
+            trialbal_period_id = period_id
+        WHERE
+            trialbal_accnt_id = i_accnt_id;
+    
+    
+    --RAISE NOTICE 'trying range % to %', v_start, v_end;
+    
+    PERFORM
+            trialbal_check_exists(i_accnt_id, period_id)
+        
+        FROM
+            (
+                SELECT
+                        period_id
+                    FROM 
+                        period
+                    WHERE
+                        period_start >= v_start
+                        AND
+                        period_end <= v_end
+                        
+                    ORDER BY
+                        period_start ASC
+            ) x;
+                        
+    
+    RETURN true;
+
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  trialbal_check_account(i_accnt_id integer)
+  OWNER TO admin;
+
+
+
+  
+CREATE OR REPLACE FUNCTION trialbal_check_exists(i_accnt_id integer, i_period_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+    _r RECORD;
+
+BEGIN 
+    
+    SELECT
+            *
+        INTO
+            _r
+        FROM
+            trialbal
+        
+        LEFT JOIN
+            period
+        ON
+            trialbal_period_id = period_id   
+            
+        WHERE
+            trialbal_accnt_id = i_accnt_id
+            AND
+            trialbal_period_id = i_period_id;
+    
+    IF FOUND THEN
+        
+        RETURN true;
+    END IF;
+    
+    SELECT
+            *
+        INTO
+            _r
+        FROM
+            period
+        WHERE
+            period_id = i_period_id;
+    
+    RAISE NOTICE '% Missing trialbal for account %', _r.period_start, i_accnt_id;
+    RETURN false;
+        
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION trialbal_check_exists(i_accnt_id integer, i_period_id integer)
+  OWNER TO admin;
+  
+  
+
+
+CREATE OR REPLACE FUNCTION trialbal_check(i_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  
+    v_start DATE;
+    v_end DATE;
+    v_accnt_id INTEGER;
+    v_pre_credits NUMERIC;
+    v_pre_debits NUMERIC;
+    v_pre_beginning NUMERIC;
+    v_pre_ending NUMERIC;
+    v_beginning NUMERIC;
+    v_credits NUMERIC;
+    v_debits NUMERIC;
+    v_accnt_descrip TEXT;
+     v_accnt_type TEXT;
+    v_yearperiod_start DATE;
+BEGIN
+    
+   
+   SELECT
+       period_start,
+       period_end,
+       trialbal_accnt_id,
+       trialbal_credits,
+       trialbal_debits,
+       trialbal_beginning,
+       trialbal_ending,
+       accnt_descrip,
+       accnt_type,
+       yearperiod_start
+   INTO
+       v_start,
+       v_end,
+       v_accnt_id,
+       v_pre_credits,
+       v_pre_debits,
+       v_pre_beginning,
+       v_pre_ending,
+       v_accnt_descrip,
+       v_accnt_type,
+       v_yearperiod_start
+   FROM
+       trialbal
+   LEFT JOIN
+       period
+   ON
+       period_id = trialbal_period_id
+    LEFT JOIN
+        yearperiod
+    ON
+        yearperiod_id = period_yearperiod_id
+       
+    LEFT JOIN
+        accnt
+    ON
+        accnt_id = trialbal_accnt_id
+   WHERE
+       trialbal_id = i_id;
+       
+    IF strpos(v_accnt_descrip, 'Retained Earn') > 0     THEN
+        return false;
+    END IF;
+    --IF v_accnt_id =  134 THEN -- opening balance has unrecorded transactions!??
+    --    return false;
+    --END IF;
+    --IF i_id =  22395 OR i_id = 17371 or i_id = 17372  OR i_id = 17373 OR i_id = 22396 THEN -- $0.01
+    --    return false;
+    --END IF;
+   
+   -- this beginning amount differs depending
+   -- on if it's carried forward each year or not..
+   
+   -- expense : $0 at beginning of financial year..
+    
+    -- assets start for ever..
+    
+    if v_accnt_type = 'A' OR v_accnt_type = 'L'  OR v_accnt_type = 'Q'  THEN
+         v_yearperiod_start = '1970-01-01'::date; 
+    END IF;
+   
+   
+   
+   SELECT
+       COALESCE(sum(
+             ROUND(gltrans_amount,2)
+       ),0)
+       INTO
+           v_beginning
+       FROM
+           gltrans 
+       where
+           gltrans_date < v_start
+        AND
+            gltrans_date >=  v_yearperiod_start
+       AND 
+           gltrans_accnt_id = v_accnt_id
+       AND
+           gltrans_posted
+        AND
+            NOT gltrans_deleted;
+   
+   SELECT
+       
+       COALESCE(sum(
+           CASE WHEN  gltrans_amount > 0 THEN ROUND(gltrans_amount,2) ELSE 0 END 
+       ),0) ,
+       COALESCE(sum(
+           CASE WHEN  gltrans_amount < 0 THEN ROUND(gltrans_amount,2) ELSE 0 END 
+       ),0)  
+       INTO
+           v_credits,
+           v_debits
+       FROM
+           gltrans 
+       where
+           gltrans_date >= v_start
+        AND 
+           gltrans_date <= v_end
+       AND 
+           gltrans_accnt_id = v_accnt_id
+       AND
+           (gltrans_posted)
+        AND
+            NOT gltrans_deleted;
+   
+   --- let's do a sanity check...
+        IF  ABS(v_pre_beginning - v_beginning ) > 1 THEN
+             RAISE NOTICE 'BEGIN (DIFF=%) did not match TID=% %..% %:%  NewB=% / OldB=%  ',
+                ABS(v_pre_beginning - v_beginning ) ,
+                   i_id, v_yearperiod_start, v_start, v_accnt_id, v_accnt_descrip,
+                   
+                   v_beginning, v_pre_beginning;
+        END IF;
+        
+        IF   ABS( ABS(v_credits) -  v_pre_credits ) > 1 THEN
+            RAISE NOTICE 'CREDIT (DIFF=%) did not match TID=% @%  %:% NC=% / C=%  ',
+                    ABS( ABS(v_credits) -  v_pre_credits ) ,
+                   i_id, v_start, v_accnt_id, v_accnt_descrip,
+                   v_credits, v_pre_credits;
+        
+        END IF;
+        
+        IF  ABS(  ABS(v_debits) -   v_pre_debits ) > 1 THEN
+            RAISE NOTICE 'DEBIT (DIFF=%) did not match TID=% @% %:% ND=% / D=%  ',
+            ABS(  ABS(v_debits) -   v_pre_debits ) ,
+                   i_id, v_start, v_accnt_id, v_accnt_descrip,
+                    v_debits, v_pre_debits;
+        END IF;
+        
+        IF    ABS( v_pre_ending - (v_beginning + v_credits + v_debits )) > 1 THEN
+            RAISE NOTICE 'END (DIFF=%) did not match TID=% @% %:% NC=% / C=%   ND=% / D=%  NB=% / B=%   NE=% / E=% ',
+                    ABS( v_pre_ending - (v_beginning + v_credits + v_debits )),
+                   i_id, v_start, v_accnt_id, v_accnt_descrip,
+                   v_credits, v_pre_credits,
+                   v_debits, v_pre_debits,
+                   v_beginning, v_pre_beginning,
+                   v_beginning + v_credits + v_debits, v_pre_ending;
+        END IF;
+
+        IF v_pre_beginning = v_beginning AND ABS(v_credits) =  v_pre_credits  AND ABS(v_debits) =  v_pre_debits AND 
+                   v_pre_ending = v_beginning + v_credits + v_debits
+                   THEN
+                   return false;
+        END IF;
+      -- RAISE NOTICE 'Fix % % % ', i_id, v_start, v_accnt_descrip;
+    
+   
+  RETURN true;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  trialbal_check(i_id integer)
+  OWNER TO admin;        
+
+
+
+
+CREATE OR REPLACE FUNCTION trialbal_fix_account(i_accnt_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+    v_start date;
+    v_end date;
+
+BEGIN
+    select
+            min(period_start),
+            max(period_start)
+        INTO
+            v_start,
+            v_end
+        FROM
+            trialbal
+        LEFT JOIN
+            period
+        ON
+            trialbal_period_id = period_id
+        WHERE
+            trialbal_accnt_id = i_accnt_id;
+    
+    
+    --RAISE NOTICE 'trying range % to %', v_start, v_end;
+    
+    PERFORM
+            trialbal_fix_exists(i_accnt_id, period_id)
+        
+        FROM
+            (
+                SELECT
+                        period_id
+                    FROM 
+                        period
+                    WHERE
+                        period_start >= v_start
+                        AND
+                        period_end <= v_end
+                        
+                    ORDER BY
+                        period_start ASC
+            ) x;
+                        
+    
+    RETURN true;
+
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  trialbal_fix_account(i_accnt_id integer)
+  OWNER TO admin;
+  
+  
+  
+CREATE OR REPLACE FUNCTION trialbal_fix_exists(i_accnt_id integer, i_period_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+    _r RECORD;
+
+BEGIN 
+    
+    SELECT
+            *
+        INTO
+            _r
+        FROM
+            trialbal
+        
+        LEFT JOIN
+            period
+        ON
+            trialbal_period_id = period_id   
+            
+        WHERE
+            trialbal_accnt_id = i_accnt_id
+            AND
+            trialbal_period_id = i_period_id;
+    
+    IF FOUND THEN
+        PERFORM trialbal_fix(_r.trialbal_id);
+        RETURN true;
+    END IF;
+    --RAISE NOTICE 'try and create? %', i_period_id;
+    --RETURN false;
+        
+    -- not found.. create it...
+    
+    INSERT INTO trialbal
+        (  trialbal_accnt_id, trialbal_period_id,
+          trialbal_beginning, trialbal_dirty,
+          trialbal_ending,
+          trialbal_credits,
+          trialbal_debits )
+        VALUES
+        (   i_accnt_id, i_period_id,
+          0, TRUE,
+          0,
+          0,
+          0
+        );
+      
+    SELECT
+            *
+        INTO
+            _r
+        FROM
+            trialbal
+          
+        LEFT JOIN
+            period
+        ON
+            trialbal_period_id = period_id   
+            
+        WHERE
+            trialbal_accnt_id = i_accnt_id
+            AND
+            trialbal_period_id = i_period_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not create trialbal?!?';
+        RETURN false;
+    END IF;
+    PERFORM trialbal_fix(_r.trialbal_id);
+    return true;
+
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION trialbal_fix_exists(i_accnt_id integer, i_period_id integer)
+  OWNER TO admin;
+  
+  
+           
+CREATE OR REPLACE FUNCTION trialbal_fix(i_id integer)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  
+    v_start DATE;
+    v_end DATE;
+    v_accnt_id INTEGER;
+    v_pre_credits NUMERIC;
+    v_pre_debits NUMERIC;
+    v_pre_beginning NUMERIC;
+    v_pre_ending NUMERIC;
+    v_beginning NUMERIC;
+    v_credits NUMERIC;
+    v_debits NUMERIC;
+    v_accnt_descrip TEXT;
+     v_accnt_type TEXT;
+    v_yearperiod_start DATE;
+BEGIN
+    
+   
+   SELECT
+       period_start,
+       period_end,
+       trialbal_accnt_id,
+       trialbal_credits,
+       trialbal_debits,
+       trialbal_beginning,
+       trialbal_ending,
+       accnt_descrip,
+       accnt_type,
+       yearperiod_start
+   INTO
+       v_start,
+       v_end,
+       v_accnt_id,
+       v_pre_credits,
+       v_pre_debits,
+       v_pre_beginning,
+       v_pre_ending,
+       v_accnt_descrip,
+       v_accnt_type,
+       v_yearperiod_start
+   FROM
+       trialbal
+   LEFT JOIN
+       period
+   ON
+       period_id = trialbal_period_id
+    LEFT JOIN
+        yearperiod
+    ON
+        yearperiod_id = period_yearperiod_id
+       
+    LEFT JOIN
+        accnt
+    ON
+        accnt_id = trialbal_accnt_id
+   WHERE
+       trialbal_id = i_id;
+       
+    IF strpos(v_accnt_descrip, 'Retained Earn') > 0     THEN
+        return false;
+    END IF;
+    --IF v_accnt_id =  134 THEN -- opening balance has unrecorded transactions!??
+    --    return false;
+    --END IF;
+    --IF i_id =  22395 OR i_id = 17371 or i_id = 17372  OR i_id = 17373 OR i_id = 22396 THEN -- $0.01
+    --    return false;
+    --END IF;
+   
+   -- this beginning amount differs depending
+   -- on if it's carried forward each year or not..
+   
+   -- expense : $0 at beginning of financial year..
+    
+    -- assets start for ever..
+    
+    if v_accnt_type = 'A' OR v_accnt_type = 'L'  OR v_accnt_type = 'Q'  THEN
+         v_yearperiod_start = '1970-01-01'::date; 
+    END IF;
+   
+   
+   
+   SELECT
+       COALESCE(sum(
+             ROUND(gltrans_amount,2)
+       ),0)
+       INTO
+           v_beginning
+       FROM
+           gltrans 
+       where
+           gltrans_date < v_start
+        AND
+            gltrans_date >=  v_yearperiod_start
+       AND 
+           gltrans_accnt_id = v_accnt_id
+       AND
+           gltrans_posted
+        AND
+            NOT gltrans_deleted;
+   
+   
+   SELECT
+       
+       COALESCE(sum(
+           CASE WHEN  gltrans_amount > 0 THEN ROUND(gltrans_amount,2) ELSE 0 END 
+       ),0) ,
+       COALESCE(sum(
+           CASE WHEN  gltrans_amount < 0 THEN ROUND(gltrans_amount,2) ELSE 0 END 
+       ),0)  
+       INTO
+           v_credits,
+           v_debits
+       FROM
+           gltrans 
+       where
+           gltrans_date >= v_start
+        AND 
+           gltrans_date <= v_end
+       AND 
+           gltrans_accnt_id = v_accnt_id
+       AND
+           (gltrans_posted)
+        AND
+            NOT gltrans_deleted;
+    
+    
+     --RAISE NOTICE '%: %..%  v_credits = %, v_debits = %, total = %', i_id , v_start, v_end, v_credits, v_debits, v_credits+v_debits;
+   --- let's do a sanity check...
+        --IF  v_pre_beginning != v_beginning  THEN
+        --     RAISE EXCEPTION 'BEGIN did not match TID=% %..% %:%  NewB=% / OldB=%  ',
+        --           i_id, v_yearperiod_start, v_start, v_accnt_id, v_accnt_descrip,
+        --           
+        --           v_beginning, v_pre_beginning;
+        --END IF;
+        --
+        --IF    ABS(v_credits) !=  v_pre_credits  THEN
+        --    RAISE EXCEPTION 'CREDIT did not match TID=% @%  %:% NC=% / C=%  ',
+        --           i_id, v_start, v_accnt_id, v_accnt_descrip,
+        --           v_credits, v_pre_credits;
+        --
+        --END IF;
+        --
+        --IF    ABS(v_debits) !=  v_pre_debits  THEN
+        --    RAISE EXCEPTION 'DEBIT did not match TID=% @% %:% ND=% / D=%  ',
+        --           i_id, v_start, v_accnt_id, v_accnt_descrip,
+        --            v_debits, v_pre_debits;
+        --END IF;
+        --
+        --IF    v_pre_ending != v_beginning + v_credits + v_debits  THEN
+        --    RAISE EXCEPTION 'END did not match TID=% @% %:% NC=% / C=%   ND=% / D=%  NB=% / B=%   NE=% / E=% ',
+        --           i_id, v_start, v_accnt_id, v_accnt_descrip,
+        --           v_credits, v_pre_credits,
+        --           v_debits, v_pre_debits,
+        --           v_beginning, v_pre_beginning,
+        --           v_beginning + v_credits + v_debits, v_pre_ending;
+        --END IF;
+
+       IF v_pre_beginning = v_beginning AND ABS(v_credits) =  v_pre_credits  AND ABS(v_debits) =  v_pre_debits AND 
+                   v_pre_ending = v_beginning + v_credits + v_debits
+                   THEN
+                   return false;
+        END IF;
+       RAISE NOTICE 'Fix % % % ', i_id, v_start, v_accnt_descrip;
+   
+   UPDATE trialbal
+       SET
+           trialbal_beginning = v_beginning,
+           trialbal_ending = v_beginning + v_credits + v_debits,
+           trialbal_credits = ABS(v_credits),
+           trialbal_debits = ABS(v_debits)
+       WHERE
+           trialbal_id = i_id;
+           
+           
+   
+  RETURN true;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  trialbal_fix(i_id integer)
+  OWNER TO admin;     
+
+
+
+
+------ fetch the trial balance by period-----
+
+CREATE OR REPLACE FUNCTION trialbal_byperiod(i_accnt_id INTEGER, i_date DATE)
+  RETURNS NUMERIC AS
+$BODY$
+DECLARE
+    v_balance NUMERIC;
+BEGIN
+
+    SELECT 
+            COALESCE(SUM( 
+                CASE WHEN accnt_type IN ( 'A') THEN  
+                        (trialbal_ending -  trialbal_beginning)   * -1
+                 ELSE 
+                        trialbal_ending -  trialbal_beginning 
+                 END
+             ), 0.0)
+    INTO
+            v_balance
+    FROM 
+            trialbal
+    
+    LEFT JOIN 
+            accnt
+    ON
+            accnt_id = trialbal_accnt_id
+    LEFT JOIN 
+            period
+    ON
+            period_id = trialbal_period_id
+    
+    WHERE
+            period_start <= i_date
+        AND
+            trialbal_accnt_id = i_accnt_id;
+
+    RETURN v_balance;
+    
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION  trialbal_byperiod(INTEGER, DATE)
+  OWNER TO admin;     
+
+
+
+------ fetch the trial balance by period END-----
+
+   
+           
+-- SELECT trialbal_check(trialbal_id) FROM ( SELECT trialbal_id FROM trialbal  LEFT JOIN
+--        period
+--    ON
+--        period_id = trialbal_period_id
+--         WHERE
+--             period_start > '2012-05-01'
+--             AND
+--             trialbal_accnt_id = 149
+--        ORDER BY period_start ASC
+--       
+--        ) x;        
+        
+-- 
+--       
+-- SELECT trialbal_fix(trialbal_id) FROM ( SELECT trialbal_id FROM trialbal  LEFT JOIN
+--        period
+--    ON
+--        period_id = trialbal_period_id
+--         WHERE period_start = '2013-05-01'
+--         AND
+--             trialbal_accnt_id = 149
+--        ORDER BY period_start ASC
+--       
+--        ) x;        
+--         
+--         
\ No newline at end of file
diff --git a/pgsql/x-dragon-undeleteglseries.sql b/pgsql/x-dragon-undeleteglseries.sql
new file mode 100644 (file)
index 0000000..80d5122
--- /dev/null
@@ -0,0 +1,125 @@
+-- Function: deleteglseries(integer, text)
+
+-- DROP FUNCTION deleteglseries(integer, text);
+
+CREATE OR REPLACE FUNCTION undeleteglseries(integer, text)
+  RETURNS boolean AS
+$BODY$
+DECLARE
+  pSequence ALIAS FOR $1;
+  pNotes ALIAS FOR $2;
+  _trialbalid INTEGER;
+  _count INTEGER;
+  v_tmp INTEGER;  
+  _r RECORD;
+
+BEGIN
+
+--  March through all of the G/L Transactions for the passed sequence
+  FOR _r IN SELECT
+            gltrans_id, gltrans_date,
+            gltrans_accnt_id, gltrans_amount,
+            gltrans_posted, gltrans_rec,
+            accnt_closedpost, accnt_forwardupdate,
+            period_id, period_closed,
+            period_freeze
+        FROM
+            accnt, gltrans
+            LEFT OUTER JOIN period ON (gltrans_date BETWEEN period_start AND period_end)
+        WHERE
+            (
+                (gltrans_accnt_id=accnt_id)
+             AND
+                (gltrans_deleted)
+             AND
+                (gltrans_sequence=pSequence)
+            ) LOOP
+
+
+--  If we can post into a Trial Balance, do so
+    IF ( (NOT _r.period_freeze) AND 
+       ( (NOT _r.period_closed) OR (_r.accnt_closedpost) ) AND
+       (  NOT _r.gltrans_rec) AND
+       ( NOT _r.gltrans_posted ) ) THEN
+
+--  Try to find an existing trialbal
+      SELECT trialbal_id INTO _trialbalid
+      FROM trialbal
+      WHERE ( (trialbal_period_id=_r.period_id)
+       AND (trialbal_accnt_id=_r.gltrans_accnt_id) );
+
+      GET DIAGNOSTICS _count = ROW_COUNT;
+      IF (_count > 0) THEN
+
+--  We found a trialbal, update it with the G/L Transaction
+--  Note - two stage update to avoid any funny value caching logic
+        IF (_r.gltrans_amount > 0) THEN
+          UPDATE trialbal
+          SET trialbal_credits = (trialbal_credits + _r.gltrans_amount)
+          WHERE (trialbal_id=_trialbalid);
+        ELSE
+          UPDATE trialbal
+          SET trialbal_debits = (trialbal_debits + (_r.gltrans_amount * -1))
+          WHERE (trialbal_id=_trialbalid);
+        END IF;
+
+        UPDATE trialbal
+        SET trialbal_ending = (trialbal_beginning - trialbal_debits + trialbal_credits),
+            trialbal_dirty=TRUE
+        WHERE (trialbal_id=_trialbalid);
+
+      ELSE
+        RAISE EXCEPTION 'Can not delete G/L Series.  Trial balance record not found.';
+      END IF;
+
+--  Forward update if we should
+      IF (_r.accnt_forwardupdate AND fetchmetricbool('ManualForwardUpdate')) THEN
+        PERFORM forwardUpdateTrialBalance(_trialbalid);
+      END IF;
+
+--  Delete any bank reconciliation records if this was marked cleared but non reconciled
+
+    SELECT bankrecitem_id INTO v_tmp FROM 
+        bankrecitem
+        WHERE ((bankrecitem_source='GL')
+        AND (bankrecitem_source_id=_r.gltrans_id)) LIMIT 1;
+    
+    IF FOUND THEN
+        RAISE EXCEPTION 'GL Series has ban reconcillation?? - this should not be possible for deleted ones!?';
+    END IF;
+
+
+    
+--  Unflag any journals as posted as a result of this series
+    UPDATE sltrans SET
+      sltrans_posted=true,
+      sltrans_gltrans_journalnumber=null
+    FROM gltrans
+    WHERE ((gltrans_sequence=pSequence)
+    AND (sltrans_gltrans_journalnumber=gltrans_journalnumber));
+    
+--  Mark the G/L Transaction as deleted
+      UPDATE gltrans SET
+        gltrans_posted=true,
+        gltrans_deleted=false,
+        gltrans_notes=gltrans_notes || E'\n' || pNotes
+      WHERE (gltrans_id=_r.gltrans_id);
+
+    ELSIF (_r.period_freeze) THEN
+        RAISE EXCEPTION 'Can not delete a G/L Transaction in a frozen period';
+    ELSIF ((_r.period_closed) OR (NOT _r.accnt_closedpost)) THEN
+        RAISE EXCEPTION 'Can not delete a G/L Transaction on account % in a closed period', formatGlAccount(gltrans_accnt_id);
+    ELSIF (_r.gltrans_rec) THEN
+        RAISE EXCEPTION 'Can not delete a G/L Transaction that has been reconciled';
+    END IF;
+
+  END LOOP;
+
+  RETURN true;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION undeleteglseries(integer, text)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-dragon-voidunpostedinvoice.sql b/pgsql/x-dragon-voidunpostedinvoice.sql
new file mode 100644 (file)
index 0000000..9ccf53a
--- /dev/null
@@ -0,0 +1,55 @@
+CREATE OR REPLACE FUNCTION voidunpostedinvoice(integer)
+  RETURNS integer AS
+$BODY$
+-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
+-- See www.xtuple.com/CPAL for the full text of the software license.
+DECLARE
+  pInvcheadid ALIAS FOR $1;
+
+BEGIN
+  UPDATE shipitem SET shipitem_invoiced=FALSE, shipitem_invcitem_id=NULL
+  FROM invcitem
+  WHERE ((shipitem_invoiced)
+    AND  (shipitem_invcitem_id=invcitem_id)
+    AND  (invcitem_invchead_id=pInvcheadid));
+
+  UPDATE coitem SET coitem_status = 'O'
+  WHERE ((coitem_status = 'C')
+    AND  (coitem_id IN (SELECT cobill_coitem_id
+                       FROM cobill, invcitem
+                       WHERE ((cobill_invcitem_id=invcitem_id)
+                         AND  (invcitem_invchead_id=pInvcheadid)))));
+
+  UPDATE cobill SET cobill_invcnum=NULL, cobill_invcitem_id=NULL
+  FROM invcitem
+  WHERE ((cobill_invcitem_id=invcitem_id)
+    AND  (invcitem_invchead_id=pInvcheadid));
+
+  UPDATE invdetail SET invdetail_invcitem_id=NULL
+  FROM invcitem
+  WHERE ((invdetail_invcitem_id=invcitem_id)
+    AND  (invcitem_invchead_id=pInvcheadid));
+
+  UPDATE cobmisc SET cobmisc_invcnumber=NULL, cobmisc_invchead_id=NULL,
+                    cobmisc_posted=FALSE
+  WHERE (cobmisc_invchead_id=pInvcheadid);
+
+  DELETE FROM aropenalloc
+  WHERE (aropenalloc_doctype='I')
+    AND (aropenalloc_doc_id=pInvcheadid);
+
+  DELETE FROM invcitem
+    WHERE (invcitem_invchead_id=pInvcheadid);
+
+  UPDATE FROM invchead
+    SET invchead_void = true
+  WHERE (invchead_id=pInvcheadid);
+
+  RETURN pInvcheadid;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+ALTER FUNCTION voidunpostedinvoice(integer)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-fifo-extra-indexes.sql b/pgsql/x-fifo-extra-indexes.sql
new file mode 100644 (file)
index 0000000..00b5f16
--- /dev/null
@@ -0,0 +1,28 @@
+
+-- indexs' that improve the performance of the code.
+
+CREATE INDEX invhist_ordtype_idx  ON  invhist USING btree  (invhist_ordtype);
+CREATE INDEX  invhist_invhist_ordnumber_text_pattern_ops_idx ON  invhist (invhist_ordnumber text_pattern_ops);
+--?? does it need a standard index?
+CREATE INDEX  invhist_invhist_docnumber_text_pattern_ops_idx ON  invhist (invhist_docnumber text_pattern_ops);
+
+CREATE INDEX  invdetail_qty_idx  ON invdetail  USING btree  (invdetail_qty);
+  
+ CREATE INDEX invdetail_location_id_idx  ON invdetail  USING btree  (invdetail_location_id );
+         
+CREATE INDEX itemsite_stocked_idx  ON  itemsite USING btree  (itemsite_stocked);
+          
+CREATE INDEX gltrans_deleted_idx  ON  gltrans USING btree  (gltrans_deleted);
+CREATE INDEX gltrans_doctype_idx  ON  gltrans USING btree  (gltrans_doctype);
+CREATE INDEX  gltrans_source_idx ON  gltrans USING btree  (gltrans_source);
+CREATE INDEX  gltrans_posted_idx ON  gltrans USING btree  (gltrans_posted);
+CREATE INDEX  gltrans_misc_id_idx ON  gltrans USING btree  (gltrans_misc_id);
+
+
+-- presume this helps direct matches
+CREATE INDEX gltrans_docnumber_idx  ON  gltrans USING btree  (gltrans_docnumber);
+-- textops -- wow much faster..
+CREATE INDEX gltrans_docnumber_text_pattern_ops_idx ON gltrans (gltrans_docnumber text_pattern_ops);
+
+
+CREATE INDEX pohead_orderdate_idx  ON  pohead USING btree  (pohead_orderdate);
diff --git a/pgsql/x-fifo-fix-cohead-id.sql b/pgsql/x-fifo-fix-cohead-id.sql
new file mode 100644 (file)
index 0000000..c765483
--- /dev/null
@@ -0,0 +1,34 @@
+CREATE OR REPLACE FUNCTION invfifo_fix_cohead_id(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+v_cohead_id INTEGER;
+v_cohead_number TEXT;
+BEGIN
+    SELECT split_part(invhist_ordnumber, '-', 1) INTO v_cohead_number FROM invdetailview WHERE invdetail_id = i_invdetail_id;
+    SELECT cohead_id INTO v_cohead_id from cohead where cohead_number = v_cohead_number;
+    
+    UPDATE invfifo
+        SET
+            invfifo_cohead_id = v_cohead_id
+        WHERE
+            invfifo_invdetail_id = i_invdetail_id;
+            
+    RETURN true;
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+  
+  --
+  --SELECT
+  --  invfifo_fix_cohead_id(invdetail_id) from invdetailview
+  --   WHERE
+  --              invhist_ordtype  ='SO'
+  --              AND
+  --              invfifo_cohead_id = 0
+  --  
+  --                
diff --git a/pgsql/x-fifo-invdetailview.sql b/pgsql/x-fifo-invdetailview.sql
new file mode 100644 (file)
index 0000000..bde0006
--- /dev/null
@@ -0,0 +1,29 @@
+
+-- as we are always looking up this join...
+
+DROP VIEW invdetailview;
+
+-- buy is a mix of RP and +ve adjustments.
+CREATE OR REPLACE VIEW invdetailview AS
+
+    SELECT
+        *
+        FROM
+            invdetail
+        LEFT JOIN
+            invhist
+        ON 
+            invhist_id = invdetail_invhist_id
+        
+        LEFT JOIN
+            invfifo
+        ON
+            invfifo_invdetail_id = invdetail_id
+        ;
+            
+
+ALTER TABLE invdetailview
+  OWNER TO admin;
+GRANT ALL ON TABLE invdetailview TO admin;
+GRANT ALL ON TABLE invdetailview TO xtrole;
+
diff --git a/pgsql/x-fifo-invfifo-apply-gl-adjust.sql b/pgsql/x-fifo-invfifo-apply-gl-adjust.sql
new file mode 100644 (file)
index 0000000..2ea2747
--- /dev/null
@@ -0,0 +1,791 @@
+
+
+
+--- apply  stock ajdustment value
+-- for HK
+--  SELECT  setmetric('invfifo_start_date', '2012-05-01');
+
+-- for SG
+--  SELECT  setmetric('invfifo_start_date', '2011-10-01');
+
+--basically inventory ajustments(HK HQ) <-> inventory asset
+--
+--
+--== this should handle voids..
+--
+--== needs to void out our old adjustments.
+--
+--
+--costcat_adjustment_accnt_id    | 228
+
+
+-- test...
+     
+--SELECT invfifo_apply_gl_adjust(period_start) FROM (
+--    SELECT period_start  FROM period WHERE NOT period_closed AND NOT period_freeze ORDER BY period_start ASC LIMIT 1) x;
+--    
+-- 
+----   
+--SELECT invfifo_apply_gl_adjust(transdate)  FROM (
+--    select
+--            distinct(invhist_transdate::date) as transdate
+--        FROM
+--            invdetailview
+--        WHERE
+--            invhist_transdate > (
+--                SELECT period_start  FROM period
+--                WHERE NOT period_closed AND NOT period_freeze ORDER BY period_start ASC LIMIT 1
+--            ) 
+--       
+--        GROUP BY
+--            invhist_transdate::date
+--         ORDER BY
+--            invhist_transdate::date ASC
+--        ) y;
+--
+--      
+
+
+
+--- this is a bit more complicated, as the AD's have been adjusted into different accounts.
+
+-- for a single transaction:
+-- we can use the gltrans_misc_id -> invhist_id
+
+
+--> for an account = eg. 228
+--> gltrans misc_id points to the invhist_id
+--> if the accnt is +ve then
+
+--what we need is a call to find out what the real fifo value for a tx was
+--
+--eg.
+   --invfifo_apply_gl_adjust_from_trans( gltrans_amount, gltrans_misc )
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_adjust_from_trans(NUMERIC, INTEGER)
+  RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE     
+   
+    i_amount ALIAS FOR $1;
+    i_misc_id ALIAS FOR $2;
+    
+    v_total NUMERIC;
+BEGIN
+   SELECT
+            COALESCE(CASE WHEN invfifo_void = 0 THEN ROUND(ABS(invdetail_qty) * invfifo_landedunitcost,2) ELSE 0.0 END,0.0)
+        INTO
+            v_total
+        FROM 
+            invdetailview
+        WHERE
+            invhist_id = i_misc_id; -- check transtype???
+    
+    IF NOT FOUND THEN
+        v_total =  0.0; -- should not happen..
+    END IF;
+    
+    IF i_amount < 0 THEN
+        v_total = v_total * -1;
+    END IF;
+    
+    RETURN v_total;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_apply_gl_adjust_from_trans(NUMERIC, INTEGER)
+  OWNER TO admin;    
+        
+--
+--SELECT sum(gltrans_amount), sum(invfifo_apply_gl_adjust_from_trans(gltrans_amount, gltrans_misc_id)) FROM 
+--   gltrans where gltrans_accnt_id = 228 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01'  ;
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_adjust_all()
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE        
+    v_period_close_at_end INTEGER;
+    v_start_date DATE;
+    
+BEGIN
+
+        SELECT
+            period_temp_open(period_start)
+        INTO
+            v_period_close_at_end
+        FROM
+            period
+        LEFT JOIN
+            yearperiod
+        ON
+            period_yearperiod_id = yearperiod_id
+        WHERE
+            NOT yearperiod_closed
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+
+        SELECT fetchMetricText('invfifo_start_date') INTO v_start_date;
+
+        IF v_start_date IS NULL OR LENGTH(v_start_date::text) < 1 THEN
+            RAISE EXCEPTION 'PERFORM setmetric(''invfifo_start_date'',  ''YOUR START DATE'');  -- do this! %', v_start_date;
+        END IF;
+
+        PERFORM 
+                invfifo_apply_gl_adjust(transdate) 
+        FROM (
+                SELECT
+                        DISTINCT(invhist_transdate::date) AS transdate
+                FROM
+                        invdetailview
+                WHERE
+                        invhist_transtype = 'AD'
+                    AND
+                        invhist_transdate::date >= v_start_date
+            )  x;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+
+        RETURN 'OK';
+
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_adjust_all()
+  OWNER TO admin;    
+        
+
+
+
+
+DROP FUNCTION IF EXISTS invfifo_apply_gl_adjust(DATE);
+-- done on a per day basis?
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_adjust(DATE)
+  RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_date  ALIAS FOR $1;
+    v_date DATE;
+    v_first_open DATE;
+    
+    
+    v_adj_accnt_id  INTEGER;
+    v_asset_accnt_id  INTEGER;
+    
+      v_gl_adjust_by NUMERIC;
+    v_diff NUMERIC;
+    v_day_total  NUMERIC;
+    v_day_stdcost_total  NUMERIC;
+    v_gl_day_total NUMERIC;
+    
+    v_old_value NUMERIC;
+    v_rounding   NUMERIC;
+    v_result INTEGER;
+    v_resultbool BOOLEAN;
+    
+    v_glsequence INTEGER;
+    v_start_date TEXT;
+    v_period_close_at_end INTEGER;
+    v_is_old BOOLEAN;
+BEGIN
+     
+    
+    
+    -- if date is in the closed account area..
+    -- we need to adjust the date to the last value, and do eveything before..
+    
+    -- whats the first open date..
+    v_date := i_date;
+    
+    
+    SELECT fetchMetricText('invfifo_start_date') INTO v_start_date;
+    IF v_start_date IS NULL OR LENGTH(v_start_date) < 1 THEN
+        RAISE EXCEPTION 'PERFORM setmetric(''invfifo_start_date'',  ''YOUR START DATE'');  -- do this! %', v_start_date;
+    END IF;
+    
+    IF v_date < v_start_date::date THEN
+        RAISE NOTICE 'ignoring transaction before start date';
+        RETURN 0;
+    END IF;
+    
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+    
+    
+    SELECT
+        costcat_adjustment_accnt_id,
+        costcat_asset_accnt_id
+    INTO
+        v_adj_accnt_id,
+        v_asset_accnt_id
+    FROM
+        costcat
+    LIMIT 1;
+    
+                 
+    IF v_first_open >= i_date THEN
+        v_date = v_first_open ;
+        
+         
+        v_is_old = true;
+    ELSE
+    
+     
+        v_is_old = false;      
+    END IF;
+      
+       
+     SELECT  COALESCE(SUM( ABS(adjust) ),0.0) + COALESCE(SUM( adjust ),0.0)  INTO v_gl_adjust_by 
+                 
+                FROM (
+                    SELECT
+                                gltrans_accnt_id as accnt_id,
+                                ROUND(COALESCE(SUM(
+                                    invfifo_apply_gl_adjust_from_trans(gltrans_amount, gltrans_misc_id) - gltrans_amount
+                                    ),0.0), 2) as adjust
+                            FROM 
+                                gltrans
+                            WHERE
+                            
+                            gltrans_doctype = 'AD'
+                            AND
+                            (
+                                (
+                                    v_is_old
+                                    AND
+                                    gltrans_date <= v_date
+                                )
+                                OR
+                                (
+                                    NOT v_is_old
+                                    AND
+                                    gltrans_date = v_date
+                                
+                                )
+                            )
+                            GROUP BY
+                                gltrans_accnt_id
+                    ) x;
+            
+    -- this needs to know the rounding error..
+    
+    
+    -- we may have an existing adjustment!!????
+--     if (v_gl_adjust_by = 0.0) THEN
+--         RAISE NOTICE ' diff = % skipping',   v_gl_adjust_by ;
+--         return 0;
+--     END IF;
+   
+    -- do we have an existing adjustment?
+     
+    SELECT
+            COALESCE(ROUND(SUM(ABS(gltrans_amount)),2),0.0)
+        INTO
+            v_old_value
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber =  'FIFO-INVADJ-' || v_date
+            AND
+            gltrans_deleted = false;
+        
+    
+    IF v_old_value = v_gl_adjust_by THEN
+        RAISE NOTICE 'No change, diff = %',   v_gl_adjust_by ;
+        return 0;
+    END IF;
+        
+    
+     
+    RAISE NOTICE '%: old adjust=%  new adjust= %',
+        v_date, v_old_value, v_gl_adjust_by;
+
+    -- values do not match - delete old attempt..
+     
+    SELECT
+            gltrans_sequence
+    INTO
+            v_result
+    FROM
+            gltrans
+    WHERE
+            gltrans_docnumber =  'FIFO-INVADJ-' || v_date
+        AND
+            gltrans_deleted = false
+    LIMIT 1 ;
+        
+    IF FOUND THEN
+            RAISE NOTICE 'Reversing old attempt';
+
+            PERFORM invfifo_apply_gl_adjust_revert_fifo(v_date);
+    
+    END IF;
+    
+    IF v_gl_adjust_by = 0 THEN
+        RAISE NOTICE 'No Adjustment';
+        RETURN v_gl_adjust_by;
+    END IF;
+
+    RAISE NOTICE 'Inv adjustment is %', v_gl_adjust_by;
+    
+    SELECT period_temp_open(v_date) INTO v_period_close_at_end; 
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+
+    SELECT SUM(CASE WHEN res < 1 THEN res - 1 ELSE 0 END) INTO v_result FROM
+        (
+
+            SELECT insertIntoGLSeries(
+                                    v_glsequence,
+                                    'G/L',
+                                    'JE',
+                                    'FIFO-INVADJ-' || v_date, 
+                                    accnt_id, -- adjustment account
+                                    adjust,
+                                   v_date ) as res
+                FROM (
+                    SELECT
+                                gltrans_accnt_id as accnt_id,
+                                ROUND(COALESCE(SUM(
+                                    invfifo_apply_gl_adjust_from_trans(gltrans_amount, gltrans_misc_id) - gltrans_amount
+                                    ),0.0), 2) as adjust
+                            FROM 
+                                gltrans
+                            WHERE
+                            
+                            gltrans_doctype = 'AD'
+                            AND
+                            (
+                                (
+                                    v_is_old
+                                    AND
+                                    gltrans_date <= v_date
+                                )
+                                OR
+                                (
+                                    NOT v_is_old
+                                    AND
+                                    gltrans_date = v_date
+                                
+                                )
+                            )
+                            GROUP BY
+                                gltrans_accnt_id
+                    ) x
+            
+            ) y;
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+
+    
+    if (v_result < 0) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+    END IF;
+    
+    --- is there any remainder....
+    RAISE NOTICE 'ref is FIFO-INVADJ-%', v_date;
+    SELECT
+            COALESCE(ROUND(SUM(ABS(glseries_amount)),2),0.0)
+        INTO
+            v_rounding
+        FROM
+            glseries
+        WHERE
+            glseries_docnumber =  'FIFO-INVADJ-' || v_date;
+
+    RAISE NOTICE 'adjust total is %', v_rounding;
+      
+    SELECT
+            COALESCE(ROUND(SUM(glseries_amount),2),0.0)
+        INTO
+            v_rounding
+        FROM
+            glseries
+        WHERE
+            glseries_docnumber =  'FIFO-INVADJ-' || v_date;
+
+    RAISE NOTICE 'Rounding is %', v_rounding;
+
+    IF v_rounding != 0.0 THEN
+    
+            SELECT insertIntoGLSeries(
+                                    v_glsequence,
+                                    'G/L',
+                                    'JE',
+                                    'FIFO-INVADJ-' || v_date, 
+                                    fetchMetricValue('CurrencyGainLossAccount')::integer, 
+                                    v_rounding * -1.0,
+                                   v_date ) into v_result;
+         if (v_result < 0) THEN
+            RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+        END IF;
+
+    END IF;
+    
+
+    UPDATE glseries
+                SET glseries_notes='Fifo Day inventory adjustment for ' || v_date
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+    --RAISE NOTICE 'postGLSeriesNoSumm(%,COALESCE(NULL,fetchJournalNumber(''G/L''))) ', v_glsequence;
+    
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed %', v_result;
+    END IF;
+
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+    
+  RETURN v_gl_adjust_by;
+    
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_adjust(DATE)
+  OWNER TO admin;    
+        
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_adjust_revert_fifo(i_date DATE)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE  
+    v_first_open DATE;
+    v_min_date DATE;
+    v_max_date DATE;
+
+    v_glsequence INTEGER;
+    _r RECORD;
+    v_result INTEGER;
+    
+    v_post BOOLEAN;
+    v_period_close_at_end INTEGER;
+    
+    
+    
+BEGIN
+    
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+    
+    SELECT 
+            MIN(gltrans_date),
+            MAX(gltrans_date)
+    INTO
+            v_min_date,
+            v_max_date
+    FROM
+            gltrans
+    WHERE   
+            gltrans_docnumber = 'FIFO-INVADJ-' || i_date
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+    
+    
+    IF (v_max_date >= v_first_open) THEN
+        PERFORM invfifo_apply_gl_adjust_delete_je(i_date);
+    END IF;
+    
+    IF (v_min_date < v_first_open) THEN
+        
+        SELECT period_temp_open(v_first_open)  INTO v_period_close_at_end;
+
+        SELECT fetchGLSequence() INTO v_glsequence;
+
+        v_post := false;
+
+        FOR _r IN SELECT 
+                    COALESCE(SUM(gltrans_amount * -1), 0) AS v_amount,
+                    gltrans_accnt_id
+            FROM
+                    gltrans
+            WHERE
+                    gltrans_docnumber = 'FIFO-INVADJ-' || i_date
+                AND
+                    gltrans_source = 'G/L'
+                AND
+                   gltrans_doctype = 'JE'
+                AND
+                    NOT gltrans_deleted
+                AND
+                    gltrans_posted 
+                AND
+                    gltrans_date < v_first_open
+
+            GROUP BY gltrans_accnt_id LOOP
+
+            IF (_r.v_amount <> 0) THEN
+
+                v_post := true;
+
+                SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                            'FIFO-INVADJ-' || v_first_open, 
+                            _r.gltrans_accnt_id,
+                            _r.v_amount,
+                           v_first_open ) INTO v_result;
+
+                IF (v_result < 1) THEN
+                    RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+                END IF;
+            END IF;
+        END LOOP;
+
+        IF (NOT v_post) THEN
+            RETURN -1;
+        END IF;
+
+        UPDATE glseries
+                SET glseries_notes='Fifo Day inventory adjustment for ' || v_date
+                WHERE (glseries_sequence=v_glsequence);
+
+
+
+        SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+
+        if (v_result < 1) THEN
+            RAISE EXCEPTION 'post GL seriese failed.';
+        END IF;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+    END IF;
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_adjust_revert_fifo(DATE )
+  OWNER TO admin;    
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_adjust_delete_je(i_date DATE)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_first_open DATE;
+    v_period_close_at_end INTEGER;
+    v_ret INTEGER;
+    
+BEGIN  
+
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+
+    SELECT period_temp_open(v_first_open) INTO v_period_close_at_end; 
+    PERFORM
+        deleteGlSeries(gltrans_sequence, 'Journal edited by FIFO on ' || to_char(NOW(), 'Day Mon DD YYY') ) 
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-INVADJ-' || i_date
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        AND
+            gltrans_date >= v_first_open;
+        
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+           
+    RETURN 1;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_adjust_delete_je(DATE )
+  OWNER TO admin;  
+
+
+ -- different account!?!?
+ -- opening balance..
+-- 
+-- invdetail_id             | 7537
+--invdetail_transtype      | 
+--invdetail_invhist_id     | 9070
+--invdetail_location_id    | 160
+--invdetail_qty            | 2.000000
+--invdetail_comments       | 
+--invdetail_qty_before     | 0.000000
+--invdetail_qty_after      | 2.000000
+--invdetail_invcitem_id    | 
+--invdetail_expiration     | 2100-01-01
+--invdetail_warrpurc       | 
+--invdetail_ls_id          | 
+--invhist_id               | 9070
+--invhist_itemsite_id      | 1249
+--invhist_transdate        | 2009-05-01 00:00:00+08
+--invhist_transtype        | AD
+--invhist_invqty           | 2.000000
+--invhist_invuom           | EA
+--invhist_ordnumber        | NS-IA-1-IA-1200899
+--invhist_docnumber        | 
+--invhist_qoh_before       | 879.000000
+--invhist_qoh_after        | 881.000000
+--invhist_unitcost         | 77.253000
+--invhist_acct_id          | 
+--invhist_xfer_warehous_id | 
+--invhist_comments         | Miscellaneous Adjustment for item BA549213
+--                         | Imported from Netsuite - InventoryAdjustment
+--invhist_posted           | t
+--invhist_imported         | 
+--invhist_hasdetail        | t
+--invhist_ordtype          | AD
+--invhist_analyze          | t
+--invhist_user             | admin
+--invhist_created          | 2012-09-02 05:24:35.26078+08
+--invhist_costmethod       | S
+--invhist_value_before     | 67905.39
+--invhist_value_after      | 68059.90
+--invhist_series           | 7233
+--invfifo_invdetail_id     | 7537
+--invfifo_unitcost         | 77.253000
+--invfifo_totalcost        | 154.506000
+--invfifo_qty_before       | 0.000000
+--invfifo_qty_after        | 2.000000
+--invfifo_cost_before      | 0.000000
+--invfifo_cost_after       | 154.506000
+--invfifo_is_estimate      | f
+--
+-- 
+-- 
+--
+---- transactions can affect customer deposits, customer credits 121
+--
+-- 
+-- 
+-- 
+-- 
+-- 
+-- 
+----
+------ gltrans misc ids == invhist ids...
+---- selecT gltrans_misc_id from gltrans where gltrans_accnt_id = 228 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01' order by gltrans_date asc ;
+----
+----
+--SELECT COALESCE(ROUND(SUM(ROUND(invdetail_qty * invhist_unitcost,2)),2),0.0) from invdetailview where invhist_id IN (
+--    selecT gltrans_misc_id from gltrans where gltrans_accnt_id = 228 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01' order by gltrans_date asc) ;
+--
+----selecT sum(gltrans_amount) from gltrans where gltrans_accnt_id = 228 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01'  ;
+----
+----
+--SELECT COALESCE(ROUND(SUM(ROUND(invdetail_qty * invhist_unitcost,2)),2),0.0)
+--    from invdetailview where invhist_transdate::date  <= '2011-05-01'        AND  invhist_transtype = 'AD';  
+----
+--
+--
+--SELECT * from invdetailview where  invhist_transdate::date  <= '2011-05-01'        AND  invhist_transtype = 'AD' AND  invhist_id NOT IN (
+--    selecT gltrans_misc_id from gltrans where gltrans_accnt_id = 121 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01' order by gltrans_date asc) ;
+--
+--
+--SELECT distinct(gltrans_accnt_id) FROM gltrans where gltrans_misc_id IN (
+--    selecT gltrans_misc_id from gltrans where gltrans_accnt_id = 228 AND gltrans_doctype='AD' AND gltrans_date <= '2011-05-01' order by gltrans_date asc) ;
+
+ --SELECT
+ --       gltrans_accnt_id as accnt_id,
+ --       ROUND(COALESCE(SUM( invfifo_apply_gl_adjust_from_trans(gltrans_amount, gltrans_misc_id) - gltrans_amount),0.0), 2) as adjust
+ --   FROM 
+ --       gltrans
+ --   WHERE
+ --   
+ --   gltrans_doctype = 'AD'
+ --   AND
+ --   
+ --     gltrans_date <= '2011-05-01' 
+ --        
+ --   
+ --   GROUP BY
+ --       gltrans_accnt_id;
+ --       
+        
+        
+
+
+-- SELECT invfifo_apply_gl_adjust(transdate) 
+--  FROM (
+--    select
+--            distinct(invhist_transdate::date) as transdate
+--        FROM
+--            invdetailview
+--            
+--         WHERE
+--             invhist_transtype = 'AD')  x
diff --git a/pgsql/x-fifo-invfifo-apply-gl-cmhead-fix-stock.sql b/pgsql/x-fifo-invfifo-apply-gl-cmhead-fix-stock.sql
new file mode 100644 (file)
index 0000000..a7cdd94
--- /dev/null
@@ -0,0 +1,66 @@
+
+    
+--------------- Fix blank location id in stock 
+  
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_fix_stock()
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    v_location_id INTEGER;
+    v_count INTEGER;
+    _r RECORD;
+    
+BEGIN
+    
+    v_count := 0;
+    
+    FOR _r IN SELECT
+                        cmhead_id,
+                        cmhead_number
+              FROM
+                        cmhead
+              WHERE
+                        cmhead_location_id IS NULL LOOP
+
+        SELECT
+                invdetail_location_id
+        INTO
+                v_location_id
+        FROM
+                invdetail
+        LEFT JOIN
+                invhist
+        ON
+                invhist_id = invdetail_invhist_id
+        WHERE
+                invhist_ordnumber = _r.cmhead_number
+        LIMIT 1;
+
+        IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'invhist not found. cmhead_number = %', _r.cmhead_number;
+        END IF;
+
+        UPDATE 
+                cmhead 
+        SET 
+                cmhead_location_id = v_location_id
+        WHERE 
+                cmhead_id = _r.cmhead_id;
+
+        v_count = v_count + 1;           
+
+    END LOOP;
+
+    RETURN 'FIXED: ' || v_count;
+            
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_fix_stock()
+  OWNER TO admin; 
+
+
diff --git a/pgsql/x-fifo-invfifo-apply-gl-cmhead.sql b/pgsql/x-fifo-invfifo-apply-gl-cmhead.sql
new file mode 100644 (file)
index 0000000..df4c172
--- /dev/null
@@ -0,0 +1,965 @@
+-- apply the fifo values to the general ledger for a credit memos.
+
+
+-- cm's are invhist_ordtype = 'CM'
+
+--Process:
+-- for a specific cohead
+-- fetch the total value of system created transactions
+-- eg. Ship/return issue etc...
+
+-- find the value we have created as an adjustment (if any.)
+
+-- calculate the correct values
+-- update or create a JE for this.
+
+-- test:
+-- SELECT invfifo_apply_gl_cmhead(cmhead_id) FROM cmhead ORDER BY cmhead_id ASC  ;
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_all()
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE        
+    v_period_close_at_end INTEGER;
+    
+BEGIN
+
+        SELECT
+            period_temp_open(period_start)
+        INTO
+            v_period_close_at_end
+        FROM
+            period
+        LEFT JOIN
+            yearperiod
+        ON
+            period_yearperiod_id = yearperiod_id
+        WHERE
+            NOT yearperiod_closed
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+
+
+        PERFORM 
+                invfifo_apply_gl_cmhead(cmhead_id) 
+        FROM 
+                cmhead
+        ORDER BY
+                cmhead_id ASC;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+
+        RETURN 'OK';
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_all()
+  OWNER TO admin; 
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead(integer)
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE        
+    i_cmhead_id  ALIAS FOR $1;
+    v_tmp INTEGER;
+    v_item_cnt NUMERIC;
+    
+    v_asset_accnt_id  INTEGER;
+    v_cogs_accnt_id INTEGER;
+    
+    v_cogs_adj_total NUMERIC;
+    v_ship_adj_total  NUMERIC;
+    v_asset_adj_total NUMERIC;
+    
+    
+    v_fifo_value NUMERIC;
+    
+    
+    v_posted_cogs NUMERIC;
+    v_posted_asset NUMERIC;
+    
+    v_assetdiff NUMERIC;
+    v_cogsdiff NUMERIC;
+    
+    v_adj_cogs  NUMERIC;
+    
+    v_adj_asset  NUMERIC;
+    
+    v_cmhead_number TEXT;
+    
+    v_glsequence INTEGER;
+    v_result INTEGER;
+    v_num_ships INTEGER;
+    v_num_no_purchase INTEGER;
+    v_resultbool BOOLEAN;
+    
+    v_period_close_at_end INTEGER;
+    v_first_open DATE;
+    v_date DATE;
+    v_start_date TEXT;
+    
+    
+BEGIN
+    --RAISE NOTICE 'START % ', clock_timestamp();
+    -- need to determine what accounts are affected,
+    -- generate a line item for all of them.
+    -- then commit the gl entry for them..
+    
+    -- let's start with basics
+    -- from cost categories
+    -- 
+    -- shipping asset, (number=1260) id = 96 -->  costcat_shipasset_accnt_id =96
+    -- inventory asset (number = 1210 or 120?)  costcat_asset_accnt_id =194
+    -- cogs (number = 121 or 5000) <<< from sales assigments COGS accnt.
+    RAISE NOTICE 'cmhead_id = %', i_cmhead_id;
+    
+    SELECT
+            cmhead_id
+        INTO
+            v_item_cnt
+        FROM
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id
+            AND
+            cmhead_posted;
+            
+     if NOT FOUND THEN
+        RETURN 'skipped = not posted';
+    END IF;
+    
+    SELECT
+            count(cmitem_id)
+        INTO
+            v_item_cnt
+        FROM
+            cmitem
+        LEFT JOIN
+            itemsite
+        ON
+            itemsite_id = cmitem_itemsite_id
+        WHERE
+            cmitem_cmhead_id = i_cmhead_id
+        AND
+            itemsite_stocked;
+            
+    if v_item_cnt < 1 THEN
+        RETURN 'skipped = not an item based order';
+    END IF;
+      
+     
+    SELECT count(distinct salesaccnt_cos_accnt_id) INTO v_tmp FROM salesaccnt;
+    IF v_tmp > 1 THEN
+        RAISE EXCEPTION 'multiple cogs accounts not supported';
+    END IF;
+    
+    SELECT DISTINCT(salesaccnt_cos_accnt_id) INTO v_cogs_accnt_id FROM salesaccnt;
+    
+    
+    SELECT count(distinct costcat_id) INTO v_tmp FROM costcat;
+    IF v_tmp > 1 THEN
+        RAISE EXCEPTION 'multiple cost categories accounts not supported';
+    END IF;
+    
+    SELECT
+            costcat_asset_accnt_id 
+        INTO
+            v_asset_accnt_id
+        FROM
+            costcat
+        LIMIT 1;
+    
+    
+    SELECT
+            cmhead_number
+        INTO
+            v_cmhead_number
+        FROM
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id;
+        
+    
+    --RAISE NOTICE 'cmhead_id = %', i_cmhead_id;
+    /*
+     gltrans_accnt_id |        accnt_descrip        
+------------------+-----------------------------
+              121 | Customer Credits
+              123 | G/L Discrepancy
+              135 | Sales
+              148 | Inventory Asset  << relivant
+              149 | Cost of Goods Sold << relivant
+              159 | Accounts Receivable (HK HQ)
+
+    */
+    --RAISE NOTICE 'BEFORE TOTALS START % ', clock_timestamp();
+    
+    
+    -- 0.632 ms without..
+    SELECT
+        ROUND(invfifo_apply_gl_cmhead_fifo_total(i_cmhead_id),2),
+        
+        ROUND(invfifo_apply_gl_cmhead_accnt_total(v_cmhead_number, v_cogs_accnt_id) ,2), -- together = 300ms
+        ROUND(invfifo_apply_gl_cmhead_accnt_total(v_cmhead_number, v_asset_accnt_id),2),  
+        
+        ROUND(invfifo_apply_gl_cmhead_fetch_je_amount(v_cmhead_number,v_cogs_accnt_id) ,2), -- together = 300ms
+        ROUND(invfifo_apply_gl_cmhead_fetch_je_amount(v_cmhead_number, v_asset_accnt_id),2) -- 0.166
+
+
+         INTO
+         v_fifo_value,
+          
+         v_posted_cogs,
+         v_posted_asset,
+         
+         v_adj_cogs,
+         v_adj_asset
+         ;
+    
+    -- 600 ms iwth all of this..
+    -- probably need to verify that cogs/inventory match..!?!?
+    
+    --RAISE NOTICE 'AFTER TOTALS START % ', clock_timestamp();
+    v_cogsdiff = v_fifo_value - v_posted_cogs;
+    v_assetdiff = (-1 * v_fifo_value) - v_posted_asset;
+  
+    RAISE NOTICE ' values: total  total issued=%    posted:  cogs(%)=%,  asset(%)=%   adjbefore cogs=%, asset=%',
+         v_fifo_value,
+       
+         v_cogs_accnt_id,
+         v_posted_cogs,
+         v_asset_accnt_id,
+         v_posted_asset,
+         
+         v_adj_cogs,
+         v_adj_asset
+         
+         ;
+    
+    
+    SELECT invfifo_apply_gl_cmhead_fetch_je_sequence(v_cmhead_number) INTO v_glsequence;
+    
+    
+    IF (
+        v_cogsdiff  = 0.0
+        
+        AND
+        v_assetdiff = 0.0
+    ) THEN
+        -- delete old difference...
+        
+        IF v_glsequence > 0 THEN
+
+            PERFORM invfifo_apply_gl_cmhead_revert_fifo(v_cmhead_number);
+        
+        END IF;
+    
+        RETURN 'NO FIFO DIFFERNECE';
+    END IF;
+    
+    
+    IF (v_adj_cogs = v_cogsdiff AND v_assetdiff = v_adj_asset ) THEN
+        RETURN 'adjustment already exists';
+    END IF;
+    
+    IF v_glsequence > 0 THEN
+
+         PERFORM invfifo_apply_gl_cmhead_revert_fifo(v_cmhead_number);
+     
+     END IF;
+    
+    
+    if ((v_cogsdiff  + v_assetdiff) != 0.0) THEN
+        RAISE EXCEPTION 'adjustment does not balance';
+    END IF;
+    
+    
+    -- what date to post..
+    
+    -- what is the last shipment?
+    SELECT
+            MAX(cmhead_gldistdate)
+        INTO
+            v_date
+        FROM
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id;
+            
+
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find a cmhead? for order %' , i_cmhead_id;
+    END IF;
+    
+    RAISE NOTICE 'shipdate : %', v_date;
+    
+   SELECT fetchMetricText('invfifo_start_date') INTO v_start_date;
+    IF v_start_date IS NULL OR LENGTH(v_start_date) < 1 THEN
+        RAISE EXCEPTION 'PERFORM setmetric(''invfifo_start_date'',  ''YOUR START DATE'');  -- do this!';
+    END IF;
+    
+    IF v_date <= v_start_date::date THEN
+        RAISE NOTICE 'ignoring transaction before start date';
+        RETURN 0;
+    END IF;
+    
+    
+    -- find the first open period..
+   SELECT
+            yearperiod_start
+    INTO
+            v_first_open
+    FROM
+            yearperiod
+    WHERE
+            NOT yearperiod_closed
+        
+    ORDER BY
+            yearperiod_start ASC
+    LIMIT 1;
+    
+        
+    IF v_first_open >= v_date THEN
+        v_date = v_first_open ;
+    END IF;
+    
+    
+    RAISE NOTICE 'shipdate after checking period: %', v_date;
+    -- create new..
+    
+    
+     SELECT period_temp_open(v_date) INTO v_period_close_at_end; 
+    
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                       'FIFO-CMHEAD-' || v_cmhead_number, 
+                        v_asset_accnt_id,  -- cogs
+                         v_assetdiff  ,
+                       v_date ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+    END IF;
+    
+
+    -- fix the value
+    
+    
+    SELECT insertIntoGLSeries(
+                        v_glsequence,
+                        'G/L',
+                        'JE',
+                       'FIFO-CMHEAD-' || v_cmhead_number, 
+                        v_cogs_accnt_id,  -- cogs
+                        v_cogsdiff  ,
+                       v_date ) INTO v_result;
+
+    if (v_result < 1) THEN
+        
+    
+        RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+    END IF;
+    
+    UPDATE glseries
+                SET glseries_notes='Fifo adjustment for ' || v_cmhead_number
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed';
+    END IF;
+    
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+    
+    
+    RETURN 'CHANGE: cogs=' || v_cogsdiff  || ' asset=' ||  v_assetdiff;
+    
+    
+    
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead(integer)
+  OWNER TO admin;    
+        
+    
+-------------------- FIFO ADJ ---------------------------        
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_fetch_je_amount(text, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cmhead_number ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    
+    v_ret NUMERIC;
+    
+BEGIN  
+    v_ret = 0;
+    SELECT
+            SUM(COALESCE(gltrans_amount,0))
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+        AND
+            gltrans_accnt_id = i_accnt_id
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_fetch_je_amount(text, integer)
+  OWNER TO admin;    
+        
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_fetch_je_sequence(text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    i_cmhead_number ALIAS FOR $1;
+     
+    v_ret INTEGER;
+    
+BEGIN  
+    
+    SELECT
+            COALESCE(gltrans_sequence,0)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        LIMIT 1;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_fetch_je_sequence(text )
+  OWNER TO admin;    
+        
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_fetch_je_date(i_cmhead_number text)
+    RETURNS  DATE
+    
+AS $BODY$
+DECLARE        
+      
+    v_ret DATE;
+    
+BEGIN  
+    
+    SELECT
+            MIN(gltrans_date)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        LIMIT 1;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_fetch_je_date(text )
+  OWNER TO admin;    
+     
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_revert_fifo(i_cmhead_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE  
+    v_first_open DATE;
+    v_min_date DATE;
+    v_max_date DATE;
+
+    v_glsequence INTEGER;
+    _r RECORD;
+    v_result INTEGER;
+    
+    v_post BOOLEAN;
+    v_period_close_at_end INTEGER;
+    
+    
+    
+BEGIN
+    
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+    
+    SELECT 
+            MIN(gltrans_date),
+            MAX(gltrans_date)
+    INTO
+            v_min_date,
+            v_max_date
+    FROM
+            gltrans
+    WHERE   
+            gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+    
+    
+    IF (v_max_date >= v_first_open) THEN
+        PERFORM invfifo_apply_gl_cmhead_delete_je(i_cmhead_number);
+    END IF;
+    
+    IF (v_min_date < v_first_open) THEN
+        
+        SELECT period_temp_open(v_first_open)  INTO v_period_close_at_end;
+
+        SELECT fetchGLSequence() INTO v_glsequence;
+
+        v_post := false;
+
+        FOR _r IN SELECT 
+                        COALESCE(SUM(gltrans_amount * -1), 0) AS v_amount,
+                        gltrans_accnt_id
+                FROM
+                        gltrans
+                WHERE
+                        gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+                    AND
+                        gltrans_source = 'G/L'
+                    AND
+                       gltrans_doctype = 'JE'
+                    AND
+                        NOT gltrans_deleted
+                    AND
+                        gltrans_posted 
+                    AND
+                        gltrans_date < v_first_open
+
+                GROUP BY gltrans_accnt_id LOOP
+
+                IF (_r.v_amount <> 0) THEN
+
+                    v_post := true;
+
+
+                    SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'FIFO-CMHEAD-' || i_cmhead_number, 
+                                _r.gltrans_accnt_id,
+                                _r.v_amount,
+                               v_first_open ) INTO v_result;
+
+                    IF (v_result < 1) THEN
+                        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+                    END IF;
+                END IF;
+        END LOOP;
+
+        IF (NOT v_post) THEN
+            RETURN -1;
+        END IF;
+
+        UPDATE glseries
+                    SET glseries_notes='Fifo adjustment for ' || i_cmhead_number
+                    WHERE (glseries_sequence=v_glsequence);
+
+
+
+        SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+
+        if (v_result < 1) THEN
+            RAISE EXCEPTION 'post GL seriese failed.';
+        END IF;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+    END IF;
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_revert_fifo(text )
+  OWNER TO admin;    
+
+   
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_delete_je(i_cmhead_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_first_open DATE;
+    v_period_close_at_end INTEGER;
+    v_ret INTEGER;
+    
+BEGIN  
+
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+
+    SELECT period_temp_open(v_first_open) INTO v_period_close_at_end; 
+    PERFORM
+        deleteGlSeries(gltrans_sequence, 'Journal edited by FIFO on ' || to_char(NOW(), 'Day Mon DD YYY') ) 
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-CMHEAD-' || i_cmhead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        AND
+            gltrans_date >= v_first_open;
+        
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+           
+    RETURN 1;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_delete_je(text )
+  OWNER TO admin;    
+        
+
+-------------------- FIFO VALUES ---------------------------        
+          
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_fifo_total(integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cmhead_id  ALIAS FOR $1;
+    v_number TEXT;
+    v_total NUMERIC;
+    v_fifo_qty NUMERIC;
+    v_fifo_total NUMERIC;
+    v_tmp INTEGER;
+    v_ret NUMERIC;
+    
+BEGIN
+    SELECT
+        
+        cmhead_number
+    INTO
+        v_number
+    
+    FROM
+         
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id;
+    
+    
+    -- we can only really tell if there is a problem, if cust_id was not set..
+    
+    select
+            count(invdetail_id)
+        INTO
+            v_tmp
+        FROM
+            invdetailview
+         WHERE
+           
+            invhist_ordnumber = v_number 
+        AND
+            invfifo_cust_id = 0
+        AND
+            -- cm's are not voided.!?!?
+             invfifo_void = 0
+        AND
+           invhist_ordtype = 'CM';
+        
+    
+    IF FOUND AND v_tmp > 0 THEN
+        RAISE EXCEPTION 'FIFO values not calculated  : SELECT invhist_itemsite_id, invfifo_landedunitcost FROM invdetailview where invhist_ordnumber = ''%'' AND invfifo_landedunitcost = 0.0 AND    invhist_ordtype = ''CM'';', v_number;
+    END IF;
+    
+    
+    
+    
+    -- cmitem qty..
+    
+    SELECT
+        -- factor in reserved for non-shpped?
+        SUM(cmitem_qtyreturned)
+    INTO
+        v_total 
+    FROM
+        cmitem
+         
+    LEFT JOIN
+        itemsite
+    ON
+        itemsite_id = cmitem_itemsite_id
+    LEFT JOIN 
+        cmhead
+    ON
+        cmhead_id = cmitem_cmhead_id
+    WHERE
+        cmitem_cmhead_id = i_cmhead_id
+    AND
+        NOT cmhead_void
+    AND
+        itemsite_stocked;
+    
+    -- fifo qty..
+    
+    SELECT
+        COALESCE(SUM(invdetail_qty ),0) ,
+        COALESCE(SUM(invdetail_qty   * invfifo_landedunitcost),0)
+        INTO
+            v_fifo_qty,
+            v_fifo_total
+        FROM
+            invdetailview
+        WHERE
+           
+            invhist_ordnumber = v_number 
+             
+        AND
+            -- cm's are not voided.!?!?
+             invfifo_void = 0
+        AND
+           invhist_ordtype = 'CM';
+    
+    
+      IF v_fifo_qty != v_total THEN
+        RAISE EXCEPTION 'docnum=%, fifo qty for cmhead_id = %  does not match fifo = %, shipped = %',
+                v_number , i_cmhead_id, v_fifo_qty, v_total;
+    END IF;
+    
+    return v_fifo_total;
+     
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_fifo_total(integer)
+  OWNER TO admin;    
+    
+    
+--------------- GL account totals. ----------------------
+  
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cmhead_accnt_total(text, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+          
+    
+    i_cmhead_number  ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    v_ret NUMERIC;
+    
+BEGIN
+       
+        
+       
+      SELECT 
+            COALESCE(SUM( gltrans_amount ),0)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+                gltrans_accnt_id = i_accnt_id
+            AND
+                gltrans_docnumber = i_cmhead_number
+            
+            AND
+                NOT gltrans_deleted
+            AND
+                gltrans_posted
+            AND
+                gltrans_doctype='CM';
+            
+    RETURN v_ret;    
+            
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cmhead_accnt_total(text, integer)
+  OWNER TO admin;  
+
+
+
+
+    
+--------------- void CM Application WHERE IS THIS USED>>>----------------------
+  
+--
+--CREATE OR REPLACE FUNCTION voidCMApplication(i_docnumber TEXT)
+--    RETURNS  INTEGER
+--    
+--AS $BODY$
+--DECLARE
+--    v_sequence INTEGER;
+--    v_resultbool BOOLEAN;
+--
+--BEGIN
+--    SELECT 
+--            gltrans_sequence
+--    INTO
+--            v_sequence
+--    FROM
+--            gltrans
+--    WHERE
+--            gltrans_docnumber = i_docnumber
+--        AND
+--            gltrans_notes = 'CM Application'
+--        AND
+--            NOT gltrans_deleted;
+--
+--
+--    IF (NOT FOUND) THEN
+--        RAISE EXCEPTION 'CM Application not found : %', i_docnumber;
+--    END IF;
+--
+--    SELECT deleteGlSeries(v_sequence ,  'Void CM Application on ' || to_char(NOW(), 'Day Mon DD YYY') ) INTO v_resultbool;
+--
+--    RETURN v_sequence;
+--            
+--END;
+--$BODY$
+--  LANGUAGE plpgsql VOLATILE
+--  COST 100;
+--  
+--ALTER FUNCTION  voidCMApplication(TEXT)
+--  OWNER TO admin; 
+
+
+
+
+-- time testing
+
+-- SELECT invfifo_apply_gl_cmhead(cmhead_id) FROM cmhead;
+        
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-apply-gl-cohead.sql b/pgsql/x-fifo-invfifo-apply-gl-cohead.sql
new file mode 100644 (file)
index 0000000..77b8af8
--- /dev/null
@@ -0,0 +1,1667 @@
+
+--- apply the fifo values to the general ledger for a cohead.
+
+
+--Process:
+-- for a specific cohead
+-- fetch the total value of system created transactions
+-- eg. Ship/return issue etc...
+
+-- find the value we have created as an adjustment (if any.)
+
+-- calculate the correct values
+-- update or create a JE for this.
+
+-- SELECT invfifo_apply_gl_cohead(cohead_id) FROM (SELECT cohead_id FROM cohead  ORDER BY cohead_id ASC ) x 
+
+
+
+
+
+ALTER TABLE cohead ADD column cohead_fifo_has_error boolean DEFAULT false;
+
+
+
+
+
+DROP FUNCTION IF EXISTS invfifo_apply_gl_cohead_all( );
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_all( )
+  RETURNS  TEXT
+  
+AS $BODY$  
+        -- select the start of the open year - open the accounts for a while
+DECLARE
+  v_period_close_at_end INTEGER;
+        
+BEGIN        
+    SELECT
+            period_temp_open(period_start)
+        INTO
+            v_period_close_at_end
+        FROM
+            period
+        LEFT JOIN
+            yearperiod
+        ON
+            period_yearperiod_id = yearperiod_id
+        WHERE
+            NOT yearperiod_closed
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+    
+   
+        -- then close at the end.
+    
+
+    PERFORM invfifo_apply_gl_cohead(cohead_id, false) FROM (SELECT cohead_id FROM cohead  ORDER BY cohead_id ASC ) x;
+
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+
+    RETURN 'OK';
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_all()
+  OWNER TO admin;
+
+
+
+
+
+
+DROP FUNCTION IF EXISTS invfifo_apply_gl_cohead(integer, boolean);
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead(i_cohead_id  integer, i_throw boolean)
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    v_cohead_fifo_has_error BOOLEAN;
+    v_ship_accnt_id  INTEGER;
+    v_cohead_number TEXT;
+    v_result TEXT;
+    v_num_ships INTEGER;
+    v_glamount NUMERIC;
+    _r RECORD;
+
+BEGIN 
+
+    SELECT
+            cohead_number,
+            cohead_fifo_has_error
+        INTO
+            v_cohead_number,
+            v_cohead_fifo_has_error
+        FROM
+            cohead
+        WHERE
+            cohead_id = i_cohead_id;
+        
+    
+    RAISE NOTICE 'cohead_id = %, cohead_number = %', i_cohead_id, v_cohead_number;
+    
+    -- preflag it as OK...
+    IF v_cohead_fifo_has_error THEN
+        UPDATE cohead set cohead_fifo_has_error  = false WHERE cohead_id = i_cohead_id;
+    END IF;
+    
+    SELECT
+        costcat_shipasset_accnt_id
+    INTO
+        v_ship_accnt_id
+    FROM
+        costcat
+    LIMIT 1;
+
+    SELECT
+        COALESCE(count(shiphead_id),0) INTO v_num_ships FROM shiphead
+         WHERE
+            shiphead_order_id = i_cohead_id
+            --AND
+            --shiphead_shipdate is not null
+            AND shiphead_shipped;
+
+    -- the downside here is that we will not void out the return ship mess.
+    
+    IF v_num_ships  < 1 THEN
+        -- check if we have a existing gltrans... if yes, delete OR revert it...
+        
+        PERFORM invfifo_apply_gl_cohead_revert_fifo(v_cohead_number);
+
+        IF i_throw THEN 
+            RETURN 'SKIP - no shipments';
+        ELSE 
+            BEGIN
+                SELECT 
+                    ABS(SUM(gltrans_amount)) INTO v_glamount
+                FROM 
+                    gltrans 
+                LEFT JOIN 
+                    invhist 
+                ON 
+                    invhist_id = gltrans_misc_id
+                WHERE 
+                    (gltrans_docnumber LIKE 'FIFO-COHEAD-' || v_cohead_number || '%'
+                    OR
+                    gltrans_docnumber LIKE v_cohead_number || '%')
+                    AND gltrans_accnt_id = v_ship_accnt_id
+                    AND NOT gltrans_deleted
+                    AND gltrans_posted
+                    AND invhist_id IS NOT NULL;
+                
+                IF (v_glamount > 0.5) THEN
+                    UPDATE cohead set cohead_fifo_has_error  = true WHERE cohead_id = i_cohead_id;
+                    RETURN 'EXCEPTION from cohead - no shipments';
+                END IF;
+                
+                RETURN 'SKIP - no shipments';
+            END;
+        END IF;
+    END IF;
+    
+    
+    SELECT
+            COALESCE(count(coitem_id),0) INTO v_num_ships FROM coitem
+        LEFT JOIN
+            itemsite
+        ON
+            coitem_itemsite_id = itemsite_id
+         WHERE
+            coitem_cohead_id = i_cohead_id
+        AND
+            coitem_status != 'X' -- void
+        AND
+            itemsite_stocked = true;
+            
+    IF v_num_ships  < 1 THEN
+        IF i_throw THEN 
+            -- RETURN 'SKIP - no items';
+        ELSE 
+            BEGIN
+                SELECT
+                        COALESCE(COUNT(shipitem_id),0) 
+                INTO 
+                        v_num_ships 
+                FROM 
+                        shipitem
+                LEFT JOIN 
+                        shiphead
+                ON
+                        shiphead_id = shipitem_shiphead_id
+                WHERE
+                        shiphead_order_id = i_cohead_id
+                    AND 
+                        shiphead_shipped;
+                
+                IF (v_num_ships = 0) THEN
+                    RETURN 'SKIP - no items';
+                END IF;
+                
+            END;
+
+        END IF;
+    END IF;
+    
+    IF i_throw THEN 
+        SELECT invfifo_apply_gl_cohead_bydate(i_cohead_id, i_throw) INTO v_result;
+    ELSE 
+        BEGIN
+            SELECT invfifo_apply_gl_cohead_bydate(i_cohead_id, i_throw) INTO v_result;
+        EXCEPTION WHEN OTHERS THEN
+            --RAISE NOTICE 'GOT EXCEPTION';
+            UPDATE cohead set cohead_fifo_has_error  = true WHERE cohead_id = i_cohead_id;
+            RETURN 'EXCEPITON OF invfifo_apply_gl_cohead_bydate';
+        END;
+
+    END IF;
+
+    RETURN v_result;
+    
+    
+    
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead(integer, boolean)
+  OWNER TO admin;    
+        
+  
+------------ BC = standard behaviour just flags errors...  
+  
+  
+DROP FUNCTION IF EXISTS invfifo_apply_gl_cohead(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead(i_cohead_id  integer)
+  RETURNS  TEXT
+AS $BODY$
+DECLARE            
+    v_ret TEXT;
+
+BEGIN
+--     PERFORM invfifo_apply_gl_cohead_reverse_year_end_fifo_je();
+    SELECT invfifo_apply_gl_cohead(i_cohead_id, false) INTO v_ret;
+    RETURN v_ret;
+    
+    END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead(integer)
+  OWNER TO admin;
+
+
+
+
+
+DROP FUNCTION IF EXISTS invfifo_apply_gl_cohead_bydate(integer,boolean);
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_bydate(i_cohead_id integer,i_throw boolean)
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE    
+    v_tmp INTEGER;
+    
+    v_ship_accnt_id  INTEGER;
+    v_asset_accnt_id  INTEGER;
+    v_cogs_accnt_id INTEGER;
+    
+    v_cogs_adj_total NUMERIC;
+    v_ship_adj_total  NUMERIC;
+    v_asset_adj_total NUMERIC;
+    
+    
+    v_shipped_value NUMERIC;
+    v_issued_value NUMERIC;
+    v_posted_cogs NUMERIC;
+    v_posted_ship NUMERIC;
+    v_posted_asset NUMERIC;
+    
+    v_shipdiff NUMERIC;
+    v_assetdiff NUMERIC;
+    v_cogsdiff NUMERIC;
+    
+    v_adj_cogs  NUMERIC;
+    v_adj_ship  NUMERIC;
+    v_adj_asset  NUMERIC;
+    
+    v_cohead_number TEXT;
+    
+    v_glsequence INTEGER;
+    v_result INTEGER;
+    
+    v_first_open DATE;
+    v_date DATE;
+    v_orig_date DATE;
+    v_start_date TEXT;
+    _r RECORD;
+    v_balcheck NUMERIC;
+    v_order_date DATE;
+    
+     v_period_close_at_end INTEGER;
+BEGIN
+   
+    SELECT
+        cohead_number,
+        cohead_orderdate
+    INTO
+        v_cohead_number,
+        v_order_date
+    FROM
+        cohead
+    WHERE
+        cohead_id = i_cohead_id;
+
+
+    SELECT
+            MAX(shiphead_shipdate)
+    INTO
+            v_date
+    FROM
+            shiphead
+    WHERE
+            shiphead_order_id = i_cohead_id
+        AND
+            shiphead_shipped;
+    
+    IF (v_date IS NULL) THEN
+        v_date = v_order_date;
+    END IF;
+
+    v_orig_date = v_date;
+
+    SELECT count(distinct salesaccnt_cos_accnt_id) INTO v_tmp FROM salesaccnt;
+    IF v_tmp > 1 THEN
+        RAISE EXCEPTION 'multiple cogs accounts not supported';
+    END IF;
+    
+    SELECT DISTINCT(salesaccnt_cos_accnt_id) INTO v_cogs_accnt_id FROM salesaccnt;
+    
+    
+    SELECT count(distinct costcat_id) INTO v_tmp FROM costcat;
+    IF v_tmp > 1 THEN
+        RAISE EXCEPTION 'multiple cost categories accounts not supported';
+    END IF;
+
+    SELECT
+        costcat_shipasset_accnt_id ,
+        costcat_asset_accnt_id 
+    INTO
+        v_ship_accnt_id,
+        v_asset_accnt_id
+    FROM
+        costcat
+    LIMIT 1;
+
+    SELECT fetchMetricText('invfifo_start_date') INTO v_start_date;
+    IF v_start_date IS NULL OR LENGTH(v_start_date) < 1 THEN
+        RAISE EXCEPTION 'PERFORM setmetric(''invfifo_start_date'',  ''YOUR START DATE'');  -- do this!';
+    END IF;
+    
+    IF v_date <= v_start_date::date THEN
+        RAISE NOTICE 'SKIP - ignoring transaction before start date';
+        RETURN 0;
+    END IF;
+
+
+    SELECT invfifo_apply_gl_cohead_check_qty(i_cohead_id, v_cohead_number) INTO v_balcheck;
+
+    IF v_balcheck < 0 THEN
+        IF i_throw THEN
+            RAISE EXCEPTION 'Shipped quanties and inventory transactions do not match on order %', v_cohead_number;
+        END IF;
+        UPDATE cohead set cohead_fifo_has_error  = true WHERE cohead_id = i_cohead_id;
+                
+        RETURN 'EXCEPTION - Shipped quanties and inventory transactions do not match on order ';
+    END IF;
+
+    
+    
+    IF i_throw THEN 
+       SELECT
+        -- 16ms
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fifo_total(i_cohead_id, v_cogs_accnt_id,'SHIPPED'),2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fifo_total(i_cohead_id, v_cogs_accnt_id,'ISSUED'),2),0),
+                
+                -- this bit is slow..
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_cogs_accnt_id) ,2),0),
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_ship_accnt_id) ,2),0),
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_asset_accnt_id),2),0),
+            
+            -- this bit is fast...
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number,v_cogs_accnt_id) ,2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number, v_ship_accnt_id) ,2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number, v_asset_accnt_id),2),0)
+            
+            
+                 INTO
+                 v_shipped_value,
+                 v_issued_value,
+                 v_posted_cogs,
+                 v_posted_ship,
+                 v_posted_asset,
+                 v_adj_cogs,
+                 v_adj_ship,
+                 v_adj_asset
+                 ;
+    ELSE 
+        BEGIN
+            SELECT
+            -- 16ms
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fifo_total(i_cohead_id, v_cogs_accnt_id,'SHIPPED'),2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fifo_total(i_cohead_id, v_cogs_accnt_id,'ISSUED'),2),0),
+                
+                -- this bit is slow..
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_cogs_accnt_id) ,2),0),
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_ship_accnt_id) ,2),0),
+                 COALESCE(ROUND(invfifo_apply_gl_cohead_accnt_total(i_cohead_id, v_asset_accnt_id),2),0),
+            
+            -- this bit is fast...
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number,v_cogs_accnt_id) ,2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number, v_ship_accnt_id) ,2),0),
+                COALESCE(ROUND(invfifo_apply_gl_cohead_fetch_je_amount(v_cohead_number, v_asset_accnt_id),2),0)
+            
+            
+                 INTO
+                 v_shipped_value,
+                 v_issued_value,
+                 v_posted_cogs,
+                 v_posted_ship,
+                 v_posted_asset,
+                 v_adj_cogs,
+                 v_adj_ship,
+                 v_adj_asset
+                 ;
+        EXCEPTION WHEN OTHERS THEN
+            RAISE EXCEPTION 'EXCEPTION RAISED - FIXME - log it...';
+        END;
+    END IF;
+
+    RAISE NOTICE ' values: total shipped=%, total issued=%    posted:  cogs(%)=%,  ship(%)=%, asset(%)=%   adjbefore cogs=%, ship=% asset=%',
+       v_shipped_value, v_issued_value,
+       
+         v_cogs_accnt_id,
+         v_posted_cogs,
+         v_ship_accnt_id,
+         v_posted_ship,
+         v_asset_accnt_id,
+         v_posted_asset,
+         
+         v_adj_cogs,
+         v_adj_ship,
+         v_adj_asset
+         
+         ;
+   
+
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+        LIMIT 1;
+    
+    
+    RAISE NOTICE 'push date = % , first available date to push %', v_date, v_first_open;
+    
+    IF v_first_open >= v_date THEN
+        v_date = v_first_open ;
+    END IF;
+
+    IF (v_shipped_value = 0.0 AND v_issued_value = 0.0 and
+        (ABS(v_posted_cogs) > 0.10 OR ABS(v_posted_ship) > 0.10 OR ABS(v_posted_asset) > 0.10)
+    ) THEN
+        -- this occurs where there is a voided shipment, and the 
+        --RETURN 'fifo values are zero, yet posted are not'; 
+        RAISE NOTICE 'fifo values are zero, yet posted are not';
+        
+    END IF;
+    
+    v_cogsdiff = (v_shipped_value * -1) - v_posted_cogs;
+    v_shipdiff = (v_shipped_value - v_issued_value) - v_posted_ship;
+    v_assetdiff = v_issued_value  - v_posted_asset;
+    
+     RAISE NOTICE 'change cogs=%, ship=%,  asset=%', v_cogsdiff, v_shipdiff, v_assetdiff;
+    
+    -- rounding error?
+    IF (
+            ((v_cogsdiff  + v_shipdiff + v_assetdiff) != 0.0)
+            AND
+            (v_shipped_value - v_issued_value)  = 0.0
+            AND
+            ABS(v_cogsdiff  + v_shipdiff + v_assetdiff) < 0.04
+       ) THEN
+        
+        v_shipdiff = ROUND(-1.0 * (v_cogsdiff   + v_assetdiff),2);
+    END IF;
+    
+    
+    IF (
+        ROUND(v_cogsdiff,2) = ROUND(v_adj_cogs,2)
+        AND
+        ROUND(v_shipdiff,2) = ROUND(v_adj_ship,2)
+        AND
+        ROUND(v_assetdiff,2) = ROUND(v_adj_asset,2)
+    ) THEN
+        -- no change..
+        RETURN 'NO CHANGE: cogs=' || v_cogsdiff || ' ship=' || v_shipdiff || ' asset=' ||  v_assetdiff;
+    END IF;
+
+    
+    IF ((v_cogsdiff  + v_shipdiff + v_assetdiff) != 0.0) THEN
+        RAISE EXCEPTION 'adjustment does not balance';
+    END IF;
+    
+    
+    IF (
+        v_cogsdiff  = 0.0
+        AND
+        v_shipdiff = 0.0
+        AND
+        v_assetdiff = 0.0
+    ) THEN
+    
+        -- will this just keep creating fifo
+    
+        PERFORM invfifo_apply_gl_cohead_revert_fifo(v_cohead_number);
+        RETURN 'NO FIFO DIFFERNECE';
+    END IF;
+    
+    RAISE NOTICE 'change cogs=% (ws), ship=%,  asset=%', v_cogsdiff, v_shipdiff, v_assetdiff;
+    
+    PERFORM invfifo_apply_gl_cohead_revert_fifo(v_cohead_number);
+    
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    SELECT period_temp_open(v_date)  INTO v_period_close_at_end;
+    
+    
+
+    --  Expense = use diff *-1  for apply value.
+
+    -- put the diff in cur gain/loss
+    IF v_shipdiff != 0.0 THEN 
+        SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                            'FIFO-COHEAD-' || v_cohead_number, 
+                            v_ship_accnt_id, -- shipping asset
+                            v_shipdiff,
+                           v_date ) INTO v_result;
+    
+        if (v_result < 1) THEN
+            
+            RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+        END IF;
+        
+    END IF;
+
+    -- fix the value
+    
+    IF v_assetdiff != 0.0 THEN 
+        SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                           'FIFO-COHEAD-' || v_cohead_number, 
+                            v_asset_accnt_id,  -- cogs
+                             v_assetdiff  ,
+                           v_date ) INTO v_result;
+    
+        if (v_result < 1) THEN
+            
+        
+            RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+        END IF;
+    END IF;
+
+    -- fix the value
+    
+    IF v_cogsdiff != 0.0 THEN 
+        SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                           'FIFO-COHEAD-' || v_cohead_number, 
+                            v_cogs_accnt_id,  -- cogs
+                            v_cogsdiff  ,
+                           v_date ) INTO v_result;
+    
+        if (v_result < 1) THEN
+            
+        
+            RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+        END IF;
+    END IF;
+    
+    
+    UPDATE glseries
+                SET glseries_notes='Fifo adjustment for ' || v_cohead_number
+                WHERE (glseries_sequence=v_glsequence);
+    
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+         
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+    
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed!';
+    END IF;
+    
+    RETURN 'CHANGE: cogs=' || v_cogsdiff || ' ship=' || v_shipdiff || ' asset=' ||  v_assetdiff  ||
+            ' WAS cogs=' || COALESCE(v_adj_cogs,0) || ' ship=' || COALESCE(v_adj_ship,0) || ' asset=' ||  COALESCE(v_adj_asset,0);
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_bydate(integer,boolean)
+  OWNER TO admin;    
+        
+    
+    
+-------------------- FIFO ADJ ---------------------------        
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_fetch_je_amount(text, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_number ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    v_ret NUMERIC;
+    
+BEGIN  
+    v_ret = 0;
+    
+    SELECT
+            SUM(ROUND(COALESCE( gltrans_amount,0),2))
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+        AND
+            gltrans_accnt_id = i_accnt_id
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_fetch_je_amount(text, integer)
+  OWNER TO admin;    
+         
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_fetch_je_sequence(text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    i_cohead_number ALIAS FOR $1;
+     
+    v_ret INTEGER;
+    
+BEGIN  
+    
+    SELECT
+            COALESCE(gltrans_sequence,0)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        LIMIT 1;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_fetch_je_sequence(text )
+  OWNER TO admin;    
+        
+    
+    
+-------------------- FIFO VALUES ---------------------------        
+          
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_fifo_total(integer, integer, text)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_id  ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    i_tx_type  ALIAS FOR $3;
+    v_tmp INTEGER;
+    v_ret NUMERIC;
+    
+BEGIN
+    
+    SELECT
+            COALESCE(SUM(invfifo_apply_gl_cohead_fifo_row(coitem_id, i_tx_type)),0)
+        INTO
+            v_ret
+        
+        FROM
+            coitem
+        LEFT JOIN
+            itemsite
+        ON
+            coitem_itemsite_id = itemsite_id
+    WHERE
+            coitem_cohead_id = i_cohead_id
+        AND
+            itemsite_stocked = true;
+    
+    RETURN v_ret;
+
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_fifo_total(integer, integer, text)
+  OWNER TO admin;    
+        
+
+--- for individual order row.
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_fifo_row(integer, text)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_coitem_id ALIAS FOR $1;
+    i_tx_type  ALIAS FOR $2;
+    v_number TEXT;
+    v_linenumber INTEGER;
+    v_subnumber INTEGER;
+    v_total NUMERIC;
+    v_reserved NUMERIC;
+    v_cohead_id INTEGER;
+    v_itemsite_id INTEGER;
+
+    v_tx TEXT;
+    
+    v_item_number TEXT;
+    v_really_shipped  NUMERIC;
+    v_fifo_qty NUMERIC;
+    v_fifo_total NUMERIC;
+BEGIN
+    
+    SELECT
+        cohead_id,
+        cohead_number,
+        coitem_linenumber,
+        coitem_subnumber,
+        -- factor in reserved for non-shpped?
+        
+        COALESCE(coitem_qtyshipped,0) - COALESCE(coitem_qtyreturned,0),
+        coitem_itemsite_id
+         
+    INTO
+        v_cohead_id,
+        v_number,
+        v_linenumber,
+        v_subnumber,
+        v_total,
+        v_itemsite_id
+    
+    FROM
+            coitem
+        LEFT JOIN
+            cohead
+        ON
+            coitem_cohead_id = cohead_id
+         
+    WHERE 
+        coitem_id = i_coitem_id;
+    
+     SELECT
+            COALESCE(SUM(shipitem_qty),0)
+        INTO
+            v_really_shipped
+        FROM
+            shipitem
+        WHERE
+            shipitem_orderitem_id = i_coitem_id;
+                 
+
+    
+    v_reserved = v_really_shipped - v_total;
+    
+--     RAISE NOTICE 'v_total = %, v_really_shipped = %',v_total,v_really_shipped;
+    
+    v_tx :=  '-' || v_linenumber;
+    IF v_subnumber > 0 THEN 
+        v_tx := v_tx || '.' || v_subnumber;
+    END IF;
+    
+    -- looking for the start date of the first open yearperiod
+
+    -- find the fifo value...
+    SELECT
+        COALESCE(SUM(invdetail_qty* -1),0) ,
+        COALESCE(SUM(invdetail_qty * -1 * invfifo_landedunitcost),0)
+        INTO
+            v_fifo_qty,
+            v_fifo_total
+        FROM
+            invdetailview
+        WHERE
+            
+             invhist_ordnumber = v_number || v_tx
+            
+        AND
+            invhist_itemsite_id = v_itemsite_id
+        AND
+            invfifo_void = 0 
+        AND
+            invhist_transtype = 'SH';
+             
+    
+    
+    -- add the shipped values...
+  
+    
+    -- sanity check.
+    
+    IF v_fifo_qty != (v_total + v_reserved) THEN
+        --- what failed..
+        SELECT item_number INTO v_item_number
+            FROM item LEFT JOIN itemsite ON itemsite_item_id = item_id
+            WHERE itemsite_id = (SELECT coitem_itemsite_id FROM coitem where coitem_id = i_coitem_id);
+            
+        RAISE EXCEPTION 'docnum=%, fifo qty for coitem_id = %   % do not match fifo = %, shipped = % , reserved = %',
+                v_number || v_tx, i_coitem_id, v_item_number, v_fifo_qty, v_total, v_reserved;
+    END IF;
+    
+    --RAISE NOTICE 'docnum=%, fifo qty for coitem_id = %  equals   fifo = %, shipped = %',
+    --            v_number || v_tx, i_coitem_id, v_fifo_qty, v_total;
+    
+    IF i_tx_type  = 'ISSUED' THEN
+        
+        RETURN v_fifo_total;
+    END IF;
+    
+    -- shipped total
+    if (v_reserved < 1) THEN
+        -- nothing reserved.. so everything is shipped.
+        RETURN v_fifo_total;
+    END IF;
+    -- reserved value =
+    RETURN v_fifo_total -  (v_reserved * (v_fifo_total / v_fifo_qty));
+    
+        
+     
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_fifo_row(integer, text, date)
+  OWNER TO admin;    
+        
+
+   
+    
+             
+         
+        
+        
+-------------------- POSTED VALUES ---------------------------        
+        
+-- fetch the total sum value for a specific account...      
+        
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_accnt_total(integer, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cohead_id  ALIAS FOR $1;
+   
+    i_accnt_id  ALIAS FOR $2;
+    
+    v_ret NUMERIC;
+    v_cohead_number TEXT;
+    _r RECORD;
+    i_docnumber TEXT[];
+    
+BEGIN
+         
+       SELECT cohead_number into v_cohead_number from cohead where cohead_id = i_cohead_id;
+       --  this finds all the 'issue to shipment' lines...
+       
+       -- fix me it needs to use fifo to ignore reveresed... NOPE !!= it needs all of them...
+    
+       -- US10311
+
+
+--       SELECT
+--            COALESCE(SUM( gltrans_amount ),0)  
+--         INTO
+--             v_ret
+--         FROM
+--             gltrans
+--         LEFT JOIN
+--             invdetailview
+--         ON
+--             invhist_id = gltrans_misc_id
+--         WHERE
+--             
+--                 invfifo_cohead_id = i_cohead_id
+--              
+--              
+--             AND
+--                 gltrans_accnt_id = i_accnt_id
+--             AND
+--                 NOT gltrans_deleted
+--             AND
+--                 gltrans_posted
+--             AND
+--                 gltrans_source='S/R';
+--         
+--         
+--         
+--     -- hopefully none of the above catches docnumber = shipment or cohead_number..  
+--          
+--         
+--     SELECT
+--            COALESCE(SUM( gltrans_amount ),0)  + v_ret
+--         INTO
+--             v_ret
+--         FROM
+--             gltrans
+--         LEFT JOIN
+--             shiphead
+--         ON
+--             gltrans_docnumber =  shiphead_number
+--             AND
+--             shiphead_number != v_cohead_number
+--             
+--         WHERE
+--                 shiphead_order_id = i_cohead_id
+--             AND
+--                 gltrans_accnt_id = i_accnt_id
+--             AND
+--                 NOT gltrans_deleted
+--             AND
+--                 gltrans_posted
+--             AND
+--                 gltrans_source='S/R'
+-- 
+--             AND gltrans_id NOT IN (
+-- 
+--                     -- exclude able so not dobule counted..
+--                     SELECT
+--                               gltrans_id
+--                             
+--                            FROM
+--                                gltrans
+--                            LEFT JOIN
+--                                invdetailview
+--                            ON
+--                                invhist_id = gltrans_misc_id
+--                            WHERE
+-- 
+--                                    invfifo_cohead_id = i_cohead_id
+-- 
+-- 
+--                                AND
+--                                    gltrans_accnt_id = i_accnt_id
+--                                AND
+--                                    NOT gltrans_deleted
+--                                AND
+--                                    gltrans_posted
+--                                AND
+--                                    gltrans_source='S/R'
+--         );
+-- 
+-- 
+--     
+--     --  catch recall?!?  
+--      SELECT
+--             COALESCE(SUM( gltrans_amount ),0)  + v_ret
+--          INTO
+--              v_ret
+--          FROM
+--              gltrans
+--          LEFT JOIN
+--              cohead
+--          ON
+--              gltrans_docnumber =  cohead_number
+--          LEFT JOIN
+--             shiphead
+--         ON
+--             gltrans_docnumber =  shiphead_number
+--          WHERE
+--                  cohead_id = i_cohead_id
+--              AND
+--                  gltrans_accnt_id = i_accnt_id
+--              AND
+--                  NOT gltrans_deleted
+--              AND
+--                  gltrans_posted
+--              AND
+--                  gltrans_source='S/R';
+
+
+
+----- new cals 
+--         $shiphead = DB_DataObject::factory('shiphead');
+--         $shiphead->shiphead_order_id = $cohead->pid();
+--         $numbers = $shiphead->fetchAll('shiphead_number');
+--         $numbers[]= $cohead->cohead_number;
+--         $ors = array();
+--         foreach($numbers as $n) {
+--             $ors[] = "gltrans_docnumber like '{$cohead->escape($n)}%'";
+--             $ors[] = "gltrans_docnumber = '{$cohead->escape($n)}'";
+--         }
+--         
+--         
+--         $this->whereAdd( implode(' OR ', $ors));
+
+        i_docnumber := ARRAY[]::TEXT[];
+        
+        IF (NOT ARRAY[v_cohead_number] <@ i_docnumber) THEN
+            SELECT array_append(i_docnumber, v_cohead_number) INTO i_docnumber;
+        END IF;
+
+        IF (NOT ARRAY[v_cohead_number || '%'] <@ i_docnumber) THEN
+            SELECT array_append(i_docnumber, v_cohead_number || '%') INTO i_docnumber;
+        END IF;
+
+        FOR _r IN SELECT
+                            shiphead_number
+                            
+                    FROM
+                            shiphead
+                    WHERE
+                            shiphead_order_id = i_cohead_id LOOP
+
+            IF (NOT ARRAY[_r.shiphead_number] <@ i_docnumber) THEN
+                SELECT array_append(i_docnumber, _r.shiphead_number) INTO i_docnumber;
+            END IF;
+
+            IF (NOT ARRAY[_r.shiphead_number || '%'] <@ i_docnumber) THEN
+                SELECT array_append(i_docnumber, _r.shiphead_number || '%') INTO i_docnumber;
+            END IF;
+
+        END LOOP;
+
+        SELECT
+                SUM(COALESCE(gltrans_amount))
+        INTO
+                v_ret
+        FROM
+                gltrans
+        WHERE
+                gltrans_accnt_id = i_accnt_id
+            AND
+                gltrans_posted
+            AND
+                NOT gltrans_deleted
+            AND
+                gltrans_docnumber LIKE ANY (i_docnumber);
+
+        RETURN v_ret;        
+     END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_accnt_total(integer, integer)
+  OWNER TO admin;    
+
+
+
+------------------ VALIDATE QUANTITIES - Help spot bugs with posting ----
+
+      
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_check_qty(i_cohead_id integer, i_cohead_number text)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    
+    v_balance NUMERIC;
+    
+BEGIN           
+            -- this really checks the inventory histor to see if it matches the
+            -- order..
+            
+            --- there are 2 potential issues here:
+            
+            --  history matching order
+            -- order matching history..
+            
+    SELECT
+        sum(ABS( rec_shipped + tx_total - rec_returned )) INTO v_balance
+    
+        FROM (
+            SELECT 
+                invhist_itemsite_id,
+                join_item.item_number as item_number,
+                COALESCE ((
+                    SELECT
+                            SUM(COALESCE(coitem_qtyreturned,0))
+                        FROM
+                            coitem
+                        WHERE
+                                coitem_cohead_id = i_cohead_id
+                            and
+                                coitem_itemsite_id = invhist_itemsite_id
+                    ) ,0)
+                AS rec_returned,
+                COALESCE ((
+                    SELECT
+                            SUM(coitem_qtyshipped)
+                        FROM
+                            coitem
+                        WHERE
+                            coitem_cohead_id = i_cohead_id
+                        and
+                            coitem_itemsite_id = invhist_itemsite_id
+                    ), 0)
+                AS rec_shipped,
+            
+                COALESCE(SUM(invdetail_qty),0) as tx_total
+                 
+            
+            
+            FROM
+                invdetail 
+            
+                LEFT JOIN invhist AS join_invhist ON
+                    invdetail.invdetail_invhist_id = join_invhist.invhist_id
+                LEFT JOIN invfifo AS join_invfifo ON
+                    invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id
+                LEFT JOIN itemsite AS join_itemsite ON
+                    join_invhist.invhist_itemsite_id = join_itemsite.itemsite_id
+                LEFT JOIN item AS join_item ON
+                    join_itemsite.itemsite_item_id = join_item.item_id 
+                WHERE ( 
+                
+                    invhist_ordtype = 'SO'
+                    AND
+                    (
+                        invhist_ordnumber LIKE i_cohead_number || '-%'
+                    OR
+                        invhist_ordnumber = i_cohead_number
+                    )
+                ) 
+                GROUP BY invhist_itemsite_id, join_item.item_number 
+             
+               
+        ) x;
+        
+        
+    IF (v_balance > 0) THEN
+        RETURN -1;
+    END IF;
+         
+    -- next check
+    
+     SELECT
+            sum(ABS(qty_shipped + COALESCE(qty_invhist ,0))) INTO v_balance
+    
+        FROM (
+    
+            SELECT
+                    SUM(COALESCE(coitem_qtyshipped,0) - COALESCE(coitem_qtyreturned,0)) as qty_shipped,
+                    
+                    (SELECT
+                        COALESCE(SUM(invdetail_qty),0) as tx_total
+                        FROM
+                            invdetail 
+                        
+                            LEFT JOIN invhist AS join_invhist ON
+                                invdetail.invdetail_invhist_id = join_invhist.invhist_id
+                            LEFT JOIN invfifo AS join_invfifo ON
+                                invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id
+                            LEFT JOIN itemsite AS join_itemsite ON
+                                join_invhist.invhist_itemsite_id = join_itemsite.itemsite_id
+                            LEFT JOIN item AS join_item ON
+                                join_itemsite.itemsite_item_id = join_item.item_id 
+                            WHERE ( 
+                            
+                                invhist_ordtype = 'SO'
+                                AND
+                                (
+                                    invhist_ordnumber LIKE i_cohead_number || '-%'
+                                OR
+                                    invhist_ordnumber = i_cohead_number
+                                )
+                                AND
+                                invhist_itemsite_id = coitem_itemsite_id
+                            ) 
+                            GROUP BY invhist_itemsite_id, join_item.item_number 
+                        
+                    ) as qty_invhist
+                    
+                FROM
+                    coitem
+                WHERE
+                    coitem_cohead_id = i_cohead_id
+                GROUP BY
+                    coitem_itemsite_id
+                 
+         ) x;
+    IF (v_balance > 0) THEN
+         RETURN -2;
+    END IF;
+     
+    RETURN 0;
+      
+     
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION invfifo_apply_gl_cohead_check_qty(  integer,   text)
+  OWNER TO admin;   
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_revert_fifo(i_cohead_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_ret INTEGER;
+    v_tmp INTEGER;
+    v_glsequence INTEGER;
+    _r RECORD;
+    v_result INTEGER;
+    v_date DATE;
+    v_first_open DATE;
+    v_post BOOLEAN;
+    v_period_close_at_end INTEGER;
+    v_min_date DATE;
+    v_max_date DATE;
+    
+    
+BEGIN
+    
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+    
+
+    
+    -- need to check if we are actually going to do anything
+    -- otherwise we will be opening the period all the time... which is really slow..
+    
+    SELECT 
+            MIN(gltrans_date),
+            MAX(gltrans_date)
+    INTO
+            v_min_date,
+            v_max_date
+    FROM
+            gltrans
+    WHERE
+            gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+    
+    
+    IF (v_max_date >= v_first_open) THEN
+        PERFORM invfifo_apply_gl_cohead_delete_fifo_je(i_cohead_number);
+    END IF;
+    
+    IF (v_min_date < v_first_open) THEN
+        
+        SELECT period_temp_open(v_first_open)  INTO v_period_close_at_end;
+
+        SELECT fetchGLSequence() INTO v_glsequence;
+
+        v_post := false;
+
+        FOR _r IN SELECT 
+                        COALESCE(SUM(gltrans_amount * -1), 0) AS v_amount,
+                        gltrans_accnt_id
+                FROM
+                        gltrans
+                WHERE
+                        gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+                    AND
+                        gltrans_source = 'G/L'
+                    AND
+                       gltrans_doctype = 'JE'
+                    AND
+                        NOT gltrans_deleted
+                    AND
+                        gltrans_posted 
+                    AND
+                        gltrans_date < v_first_open
+
+                GROUP BY gltrans_accnt_id LOOP
+
+                IF (_r.v_amount <> 0) THEN
+
+                    v_post := true;
+
+
+                    SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'FIFO-COHEAD-' || i_cohead_number, 
+                                _r.gltrans_accnt_id,
+                                _r.v_amount,
+                               v_first_open ) INTO v_result;
+
+                    IF (v_result < 1) THEN
+                        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+                    END IF;
+                END IF;
+        END LOOP;
+
+        IF (NOT v_post) THEN
+            RETURN -1;
+        END IF;
+
+        UPDATE glseries
+                    SET glseries_notes='Fifo adjustment for ' || i_cohead_number
+                    WHERE (glseries_sequence=v_glsequence);
+
+
+
+        SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+
+        if (v_result < 1) THEN
+            RAISE EXCEPTION 'post GL seriese failed.';
+        END IF;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+    END IF;
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_revert_fifo(text )
+  OWNER TO admin;    
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_delete_fifo_je(i_cohead_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    i_cohead_number ALIAS FOR $1;
+    v_period_close_at_end INTEGER;
+    v_ret INTEGER;
+    v_first_open DATE;
+    
+BEGIN  
+    
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+
+    SELECT period_temp_open(invfifo_apply_gl_cohead_fetch_je_date(i_cohead_number))  INTO v_period_close_at_end;
+     
+        
+    PERFORM
+        deleteGlSeries(gltrans_sequence, 'Journal edited by FIFO on ' || to_char(NOW(), 'Day Mon DD YYY') ) 
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        AND
+            gltrans_date >= v_first_open;
+        
+        
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+    
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_delete_fifo_je(text )
+  OWNER TO admin; 
+   
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_fetch_je_date(i_cohead_number text)
+    RETURNS  DATE
+    
+AS $BODY$
+DECLARE        
+   
+     
+    v_ret DATE;
+    
+BEGIN  
+    
+    --RAISE NOTICE 'invfifo_apply_gl_cohead_fetch_je_amount(''%'', %)', i_cohead_number, i_accnt_id;
+    
+    SELECT
+            MIN(gltrans_date) 
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-COHEAD-' || i_cohead_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_fetch_je_date(text)
+  OWNER TO admin;  
+
+
+
+
+
+---- reverse Year end Adjustment 
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_cohead_reverse_year_end_fifo_je()
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE    
+    v_first_open DATE;
+    v_date DATE;
+    _r RECORD;
+    v_result INTEGER;
+    v_glsequence INTEGER;
+    v_ship_accnt_id INTEGER;
+    v_cogs_other_accnt_id INTEGER;
+    v_amount NUMERIC;
+
+BEGIN  
+
+    SELECT
+        costcat_shipasset_accnt_id
+    INTO
+        v_ship_accnt_id
+    FROM
+        costcat
+    LIMIT 1;
+
+    SELECT
+        accnt_id
+    INTO
+        v_cogs_other_accnt_id
+    FROM
+        accnt
+    WHERE
+        accnt_descrip = 'Cost of Goods Sold - Other'
+    LIMIT 1;
+    
+    IF (NOT FOUND) THEN
+        RAISE EXCEPTION 'Can not found - Cost of Goods Sold - Other';
+    END IF;
+    
+    SELECT
+            yearperiod_start
+    INTO
+            v_first_open
+    FROM
+            yearperiod
+    WHERE
+            NOT yearperiod_closed
+
+    ORDER BY 
+            yearperiod_start ASC
+    LIMIT 1;
+    
+
+    SELECT
+            MAX(gltrans_date),
+            COALESCE(SUM(gltrans_amount),0)
+    INTO
+            v_date,
+            v_amount
+    FROM
+            gltrans
+    WHERE
+           gltrans_accnt_id  = v_ship_accnt_id
+        AND
+            gltrans_doctype = 'JE'
+        AND
+            (
+                gltrans_notes LIKE '%to make accounts corret%'
+                OR
+                gltrans_docnumber = 'FIFO-COHEAD-REVERSE-YEAR-END-FIFO'
+                OR
+                gltrans_notes = 'year end rounding'
+            )
+        AND
+            gltrans_posted
+        AND
+            NOT gltrans_deleted;
+           
+    IF (v_amount = 0) THEN
+        RETURN -1;
+    END IF;
+
+    IF (v_date < v_first_open) THEN
+        v_date = v_first_open;
+    END IF;
+
+    SELECT fetchGLSequence() INTO v_glsequence;
+
+    SELECT insertIntoGLSeries(
+                v_glsequence,
+                'G/L',
+                'JE',
+                'FIFO-COHEAD-REVERSE-YEAR-END-FIFO', 
+                v_ship_accnt_id,
+                v_amount * -1,
+               v_date ) INTO v_result;
+
+    IF (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+    END IF;
+
+    SELECT insertIntoGLSeries(
+                v_glsequence,
+                'G/L',
+                'JE',
+                'FIFO-COHEAD-REVERSE-YEAR-END-FIFO', 
+                v_cogs_other_accnt_id,
+                v_amount,
+               v_date ) INTO v_result;
+
+    IF (v_result < 1) THEN
+        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+    END IF;
+
+    UPDATE glseries
+                SET glseries_notes='FIFO COHEAD REVERSE YEAR END FIFO'
+                WHERE (glseries_sequence=v_glsequence);
+    
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed. result : %', v_result;
+    END IF;
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_cohead_reverse_year_end_fifo_je()
+  OWNER TO admin; 
+
+
+
+
+
+
diff --git a/pgsql/x-fifo-invfifo-apply-gl-invchead.sql b/pgsql/x-fifo-invfifo-apply-gl-invchead.sql
new file mode 100644 (file)
index 0000000..e6db9dd
--- /dev/null
@@ -0,0 +1,680 @@
+
+-- SELECT invfifo_apply_gl_invchead(invchead_id) FROM invchead;
+ -- select invfifo_apply_gl_invchead(invchead_id) from invchead where invchead_id NOT IN ( SELECT  cobmisc_invchead_id FROM cobmisc WHERE cobmisc_invchead_id IS NOT NULL);
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_all()
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE        
+    v_period_close_at_end INTEGER;
+    
+BEGIN
+
+        SELECT
+            period_temp_open(period_start)
+        INTO
+            v_period_close_at_end
+        FROM
+            period
+        LEFT JOIN
+            yearperiod
+        ON
+            period_yearperiod_id = yearperiod_id
+        WHERE
+            NOT yearperiod_closed
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+
+
+        PERFORM 
+                invfifo_apply_gl_invchead(invchead_id) 
+        FROM 
+                invchead
+        ORDER BY
+                invchead_id ASC;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+
+        RETURN 'OK';
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_all()
+  OWNER TO admin; 
+
+
+
+DROP FUNCTION IF EXISTS invfifo_apply_gl_invchead(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead(integer)
+  RETURNS  TEXT
+    
+AS $BODY$
+DECLARE      
+    i_invchead_id ALIAS FOR $1;
+    v_gltrans_docnumber TEXT;
+    v_cogs_accnt_id     INTEGER;
+    v_asset_accnt_id    INTEGER;
+    v_landed_value     NUMERIC;
+    v_posted_cogs       NUMERIC;
+    v_adj_cogs          NUMERIC;
+    v_cogsdiff          NUMERIC;
+    v_glsequence        INTEGER;
+    v_resultbool        BOOLEAN;
+    v_first_open        DATE;
+    v_date              DATE;
+    v_start_date        DATE;
+    v_result            INTEGER;
+    v_period_close_at_end INTEGER;
+    v_tmp  INTEGER;
+BEGIN
+    
+
+    SELECT DISTINCT(salesaccnt_cos_accnt_id) INTO v_cogs_accnt_id FROM salesaccnt;
+
+    SELECT
+        costcat_asset_accnt_id
+    INTO
+        v_asset_accnt_id
+    FROM
+        costcat
+    LIMIT 1;
+    
+    SELECT
+        invchead_invcnumber,
+        invchead_invcdate
+    INTO
+        v_gltrans_docnumber,
+        v_date
+    FROM
+        invchead
+    WHERE
+        invchead_id = i_invchead_id;
+    
+    IF (v_gltrans_docnumber = '') THEN
+        RAISE EXCEPTION 'Can not found the invoice - invchead_id = %', i_invchead_id;
+    END IF;
+    
+    SELECT fetchMetricText('invfifo_start_date') INTO v_start_date;
+    IF v_start_date IS NULL THEN
+        RAISE EXCEPTION 'PERFORM setmetric(''invfifo_start_date'',  ''YOUR START DATE'');  -- do this!';
+    END IF;
+    
+    IF v_date < v_start_date::date THEN
+        RAISE NOTICE 'SKIP - ignoring transaction before start date';
+        RETURN 0;
+    END IF;
+
+
+    -- check if is a cobmisc based..
+    SELECT
+            cobmisc_id
+        INTO
+            v_tmp
+        FROM
+            cobmisc
+        WHERE
+            cobmisc_invchead_id  = i_invchead_id
+        LIMIT 1;
+
+    IF FOUND THEN
+        RAISE NOTICE 'SKIP - handled by cohead code';
+        RETURN 0;
+    END IF;
+    
+    
+
+
+
+    SELECT
+        
+        ROUND(invfifo_apply_gl_invchead_fifo_total(v_gltrans_docnumber, v_cogs_accnt_id),2),
+
+        ROUND(invfifo_apply_gl_invchead_accnt_total(v_gltrans_docnumber, v_cogs_accnt_id) ,2),
+
+        ROUND(invfifo_apply_gl_invchead_fetch_je_amount(v_gltrans_docnumber,v_cogs_accnt_id) ,2)
+    INTO
+        v_landed_value,
+        v_posted_cogs,
+        v_adj_cogs
+    ;
+    RAISE NOTICE 'gltrans_docnumber = % v_landed_value = %  v_posted_cogs = % v_adj_cogs = % ',
+                v_gltrans_docnumber,
+                v_landed_value,
+                v_posted_cogs,
+                v_adj_cogs
+    ;  
+
+    IF (v_landed_value = 0.0  AND ABS(v_posted_cogs) > 0.10  ) THEN
+        -- this occurs where there is a voided shipment, and the 
+
+        RAISE NOTICE 'fifo values are zero, yet posted are not';
+        RETURN 'SKIP - fifo value issue';
+
+    END IF;
+
+    v_cogsdiff = (v_landed_value * -1) - v_posted_cogs;
+
+    RAISE NOTICE 'change cogs = % ', v_cogsdiff;
+    
+    IF (v_cogsdiff  = 0.0 ) THEN
+
+        SELECT invfifo_apply_gl_invchead_fetch_je_sequence(v_gltrans_docnumber) INTO v_glsequence;
+        -- delete existing
+    
+        IF v_glsequence > 0 THEN
+            PERFORM invfifo_apply_gl_invchead_revert_fifo(v_gltrans_docnumber);
+        END IF;
+
+        RETURN 'NO FIFO DIFFERNECE';
+    END IF;
+
+    IF (ROUND(v_cogsdiff,2) = ROUND(v_adj_cogs,2) ) THEN
+        -- no change..
+        RETURN 'NO CHANGE: cogs=' || v_cogsdiff;
+    END IF;
+
+
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+
+    IF v_first_open >= v_date THEN
+        v_date = v_first_open ;
+    END IF;
+
+    SELECT period_temp_open(v_date) INTO v_period_close_at_end;
+    
+    
+    -- try and remove the old values?
+    SELECT invfifo_apply_gl_invchead_fetch_je_sequence(v_gltrans_docnumber) INTO v_glsequence;
+        -- delete existing
+    
+    IF v_glsequence > 0 THEN
+        PERFORM invfifo_apply_gl_invchead_revert_fifo(v_gltrans_docnumber);
+    END IF;
+    
+    
+    
+
+    SELECT fetchGLSequence() INTO v_glsequence;
+    
+    -- fix the value
+    
+    
+    
+
+    IF v_cogsdiff != 0.0 THEN 
+        SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                           'FIFO-INVCHEAD-' || v_gltrans_docnumber, 
+                            v_asset_accnt_id, 
+                            v_cogsdiff * -1,
+                           v_date ) INTO v_result;
+
+        if (v_result < 1) THEN
+
+            RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+        END IF;
+    END IF;
+    -- fix the value
+
+    IF v_cogsdiff != 0.0 THEN 
+        SELECT insertIntoGLSeries(
+                            v_glsequence,
+                            'G/L',
+                            'JE',
+                           'FIFO-INVCHEAD-' || v_gltrans_docnumber, 
+                            v_cogs_accnt_id, 
+                            v_cogsdiff ,
+                           v_date ) INTO v_result;
+
+        if (v_result < 1) THEN
+
+            RAISE EXCEPTION 'insertIntoGLSeries INV ASS failed';
+        END IF;
+    END IF;
+
+    UPDATE 
+        glseries
+    SET 
+        glseries_notes='Fifo adjustment for ' || v_gltrans_docnumber
+    WHERE 
+        (glseries_sequence=v_glsequence);
+
+
+
+    SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+    
+    if (v_result < 1) THEN
+        RAISE EXCEPTION 'post GL seriese failed! glsequence = % result = %', v_glsequence, v_result;
+    END IF;
+
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+
+    RAISE NOTICE 'glsequence = % result = %', v_glsequence, v_result;
+    RETURN 'CHANGE: cogs=' || v_cogsdiff ||
+            ' WAS cogs=' || COALESCE(v_adj_cogs,0);
+    
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead(integer)
+  OWNER TO admin;    
+        
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_revert_fifo(i_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE  
+    v_first_open DATE;
+    v_min_date DATE;
+    v_max_date DATE;
+
+    v_glsequence INTEGER;
+    _r RECORD;
+    v_result INTEGER;
+    v_period_close_at_end INTEGER;
+    v_post BOOLEAN;
+    
+    
+    
+BEGIN
+     RAISE NOTICE 'invfifo_apply_gl_invchead_revert_fifo= %', i_number;
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+    
+    SELECT 
+            MIN(gltrans_date),
+            MAX(gltrans_date)
+    INTO
+            v_min_date,
+            v_max_date
+    FROM
+            gltrans
+    WHERE   
+            gltrans_docnumber = 'FIFO-INVCHEAD-' || i_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+            gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+    
+    
+    IF (v_max_date >= v_first_open) THEN
+        PERFORM invfifo_apply_gl_invchead_delete_je(i_number);
+    END IF;
+    
+    IF (v_min_date < v_first_open) THEN
+        
+        SELECT period_temp_open(v_first_open)  INTO v_period_close_at_end;
+
+        SELECT fetchGLSequence() INTO v_glsequence;
+
+        v_post := false;
+
+        FOR _r IN SELECT 
+                        COALESCE(SUM(gltrans_amount * -1), 0) AS v_amount,
+                        gltrans_accnt_id
+                FROM
+                        gltrans
+                WHERE
+                        gltrans_docnumber = 'FIFO-INVCHEAD-' || i_number
+                    AND
+                        gltrans_source = 'G/L'
+                    AND
+                       gltrans_doctype = 'JE'
+                    AND
+                        NOT gltrans_deleted
+                    AND
+                        gltrans_posted 
+                    AND
+                        gltrans_date < v_first_open
+
+                GROUP BY gltrans_accnt_id LOOP
+
+                IF (_r.v_amount <> 0) THEN
+
+                    v_post := true;
+
+
+                    SELECT insertIntoGLSeries(
+                                v_glsequence,
+                                'G/L',
+                                'JE',
+                                'FIFO-INVCHEAD-' || i_number, 
+                                _r.gltrans_accnt_id,
+                                _r.v_amount,
+                               v_first_open ) INTO v_result;
+
+                    IF (v_result < 1) THEN
+                        RAISE EXCEPTION 'insertIntoGLSeries SHIP ASS  failed';
+                    END IF;
+                END IF;
+        END LOOP;
+
+        IF (NOT v_post) THEN
+            RETURN -1;
+        END IF;
+
+        UPDATE glseries
+                    SET glseries_notes='Fifo adjustment for ' || i_number
+                    WHERE (glseries_sequence=v_glsequence);
+
+
+
+        SELECT postGLSeriesNoSumm(v_glsequence,COALESCE(NULL,fetchJournalNumber('G/L'))) INTO v_result;
+
+        if (v_result < 1) THEN
+            RAISE EXCEPTION 'post GL seriese failed.';
+        END IF;
+
+        IF v_period_close_at_end > 0 THEN
+            PERFORM period_temp_close(v_period_close_at_end);
+        END IF;
+
+    END IF;
+       
+    RETURN 0;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_revert_fifo(text )
+  OWNER TO admin;   
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_delete_je(i_number text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    v_first_open DATE;
+    v_period_close_at_end INTEGER;
+    v_ret INTEGER;
+    
+BEGIN  
+
+    SELECT
+        yearperiod_start
+    INTO
+        v_first_open
+    FROM
+        yearperiod
+    WHERE
+        NOT yearperiod_closed
+
+    ORDER BY
+        yearperiod_start ASC
+    LIMIT 1;
+
+    SELECT period_temp_open(v_first_open) INTO v_period_close_at_end; 
+    PERFORM
+        deleteGlSeries(gltrans_sequence, 'Journal edited by FIFO on ' || to_char(NOW(), 'Day Mon DD YYY') ) 
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-INVCHEAD-' || i_number
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        AND
+            gltrans_date >= v_first_open;
+        
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_close(v_period_close_at_end);
+    END IF;
+           
+    RETURN 1;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_delete_je(text )
+  OWNER TO admin;   
+
+
+
+
+        
+-------------------- POSTED VALUES ---------------------------        
+        
+-- fetch the total sum value for a specific account...      
+        
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_accnt_total(text, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_gltrans_docnumber  ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    v_ret NUMERIC;
+    
+BEGIN
+      
+      SELECT
+           ROUND(COALESCE(SUM(
+                CASE WHEN accnt_type = 'A' THEN
+                    gltrans_amount * -1
+                ELSE
+                    gltrans_amount
+                END
+            ),0),2) 
+        INTO
+            v_ret
+        FROM
+            gltrans
+        LEFT JOIN accnt AS join_accnt ON gltrans_accnt_id = accnt_id
+
+        WHERE
+            gltrans_docnumber = i_gltrans_docnumber
+            AND
+                gltrans_accnt_id = i_accnt_id
+            AND
+                NOT gltrans_deleted
+            AND
+                gltrans_posted
+            AND
+                gltrans_source='S/O';
+        
+                        
+    RETURN v_ret;        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_accnt_total(text, integer)
+  OWNER TO admin;    
+
+
+  
+-------------------- FIFO ADJ ---------------------------        
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_fetch_je_amount(text, integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_gltrans_docnumber  ALIAS FOR $1;
+    i_accnt_id  ALIAS FOR $2;
+    v_ret NUMERIC;
+    
+BEGIN
+    
+    SELECT
+        ROUND(COALESCE(SUM(
+                CASE WHEN accnt_type = 'A' THEN
+                    gltrans_amount * -1
+                ELSE
+                    gltrans_amount
+                END
+        ),0),2)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        LEFT JOIN accnt AS join_accnt ON gltrans_accnt_id = accnt_id
+
+        WHERE
+            gltrans_docnumber = 'FIFO-INVCHEAD-' || i_gltrans_docnumber
+        AND
+            gltrans_accnt_id = i_accnt_id
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_fetch_je_amount(text, integer)
+  OWNER TO admin;    
+         
+
+-------------------- FIFO VALUES ---------------------------        
+          
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_fifo_total(i_gltrans_docnumber text, i_accnt_id integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE  
+    v_asset NUMERIC;
+    
+BEGIN
+    
+    SELECT
+        
+        ROUND(ABS(COALESCE(SUM(join_invfifo.invfifo_landedunitcost * invdetail_qty),0)),2)
+    INTO
+        
+        v_asset
+    FROM
+        invdetail
+    LEFT JOIN invhist AS join_invhist ON invdetail.invdetail_invhist_id = join_invhist.invhist_id
+    LEFT JOIN invfifo AS join_invfifo ON invdetail.invdetail_id = join_invfifo.invfifo_invdetail_id
+
+    WHERE
+        join_invhist.invhist_ordnumber = i_gltrans_docnumber
+        AND
+        join_invhist.invhist_transtype != 'RL'
+        AND
+        join_invhist.invhist_ordtype = 'IN';
+    
+     
+    RETURN v_asset;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_fifo_total(text, integer)
+  OWNER TO admin;    
+
+
+
+-------------------- FETCH SEQUENCE ---------------------------        
+
+CREATE OR REPLACE FUNCTION invfifo_apply_gl_invchead_fetch_je_sequence(text)
+    RETURNS  INTEGER
+    
+AS $BODY$
+DECLARE        
+    i_gltrans_docnumber ALIAS FOR $1;
+     
+    v_ret INTEGER;
+    
+BEGIN  
+    
+    SELECT
+            COALESCE(gltrans_sequence,0)
+        INTO
+            v_ret
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = 'FIFO-INVCHEAD-' || i_gltrans_docnumber
+        AND
+            gltrans_source = 'G/L'
+        AND
+           gltrans_doctype = 'JE'
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_posted
+        LIMIT 1;
+           
+    RETURN v_ret;
+   
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_apply_gl_invchead_fetch_je_sequence(text )
+  OWNER TO admin;  
+
+-- testing..
+-- SELECT invfifo_apply_gl_invchead(9914);
diff --git a/pgsql/x-fifo-invfifo-apply-gl-pohead.sql b/pgsql/x-fifo-invfifo-apply-gl-pohead.sql
new file mode 100644 (file)
index 0000000..5b75b1c
--- /dev/null
@@ -0,0 +1,38 @@
+-- applying values from purchase orders
+
+
+-- basically purchase orders do not affect GL
+-- we maintain revgrpland and recvgrp record for item reciept so we can apply frieght charges to orders
+-- which moves $value between freight and inventory asset.
+
+
+
+
+-- purchase order tx's
+-- recieve stock
+-- return (ignored..)
+
+-- payments will adjust values at present..
+
+--Recieve Inventory
+--> debit      inventory asset
+--> credit     inventory recieved not billed.
+
+--- Voucher
+--> AP -- real value...
+--> debit -- inventory asset (difference in value between STDCOST...?)
+--> debit  inventory recieved not billed.
+
+
+--> our only key difference here is that the freight charges will need moving!??!
+
+-- where are our landed costs from?
+-- normally 'Cost of Frieght' => transfered to inventory asset (was done with a JE before.)
+-- we probably need a better way to account for this..
+
+
+
+-- gl affect will only be to move from Cost of freight into inventory
+-- does not affect our stock valuations..
+
diff --git a/pgsql/x-fifo-invfifo-cohead-fix-id.sql b/pgsql/x-fifo-invfifo-cohead-fix-id.sql
new file mode 100644 (file)
index 0000000..eba492a
--- /dev/null
@@ -0,0 +1,76 @@
+CREATE OR REPLACE FUNCTION invfifo_cohead_fix_id(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+v_cohead_id INTEGER;
+v_cohead_number TEXT;
+BEGIN
+    SELECT split_part(invhist_ordnumber, '-', 1) INTO v_cohead_number FROM invdetailview WHERE invdetail_id = i_invdetail_id;
+    SELECT cohead_id INTO v_cohead_id from cohead where cohead_number = v_cohead_number;
+    
+    UPDATE invfifo
+        SET
+            invfifo_cohead_id = v_cohead_id
+        WHERE
+            invfifo_invdetail_id = i_invdetail_id;
+            
+    RETURN true;
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+    
+ALTER FUNCTION   invfifo_cohead_fix_id(integer)
+  OWNER TO admin;
+  
+  
+  
+  
+  
+CREATE OR REPLACE FUNCTION invfifo_cohead_check_id() 
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE    
+
+v_tmp INTEGER;
+
+BEGIN
+    
+
+    SELECT
+            count(invdetail_id)
+        INTO
+            v_tmp
+        FROM
+            invdetailview
+        WHERE
+            invhist_ordtype = 'SO'
+        AND
+            invfifo_cohead_id = 0;
+            
+    IF v_tmp > 0 THEN
+        RETURN false;
+    END IF;
+    RETURN true;
+END
+$BODY$
+  LANGUAGE plpgsql STABLE
+  COST 100;
+    
+ALTER FUNCTION   invfifo_cohead_check_id()
+  OWNER TO admin;
+  
+  
+  
+  --
+  --SELECT
+  --  invfifo_fix_cohead_id(invdetail_id) from invdetailview
+  --   WHERE
+  --              invhist_ordtype  ='SO'
+  --              AND
+  --              invfifo_cohead_id = 0
+  --  
+  --                
diff --git a/pgsql/x-fifo-invfifo-cohead-void-flag.sql b/pgsql/x-fifo-invfifo-cohead-void-flag.sql
new file mode 100644 (file)
index 0000000..4b1d3d7
--- /dev/null
@@ -0,0 +1,425 @@
+-- aim is to flag the invfifo_void field with if
+-- shipments have been returned, so that fifo calcs will ignore any values.
+
+
+
+
+
+-- called with cohead_id and itemsite_id
+
+
+-- fill
+
+
+
+-- reset..
+
+-- update invfifo SET invfifo_void = 0 where  invfifo_invdetail_id IN (SELECT invdetail_id FROM invdetailview WHERE invhist_ordtype='SO' and invfifo_void !=0);
+-- SELECT invfifo_cohead_void_flag_order(cohead_id) FROM cohead;
+
+
+-- validation
+-- total without voided should match total all together
+
+ --SELECT SUM(invdetail_qty) FROM invdetailview where invhist_ordtype = 'SO';
+ --SELECT SUM(invdetail_qty) FROM invdetailview where invhist_ordtype = 'SO' and invfifo_void = 0;
+ --SELECT SUM(abs(invdetail_qty)) FROM invdetailview where invhist_ordtype = 'SO' and invfifo_void != 0;
+ --
+
+--SELECT invhist_ordnumber, aftervoid, beforevoid FROM
+--
+--    (SELECT invhist_ordnumber, SUM( CASE WHEN invfifo_void != 0 THEN 0 ELSE invdetail_qty END ) as aftervoid,
+--        SUM(invdetail_qty) as beforevoid FROM invdetailview WHERE invhist_ordtype = 'SO'    
+--        GROUP BY invhist_ordnumber
+--    ) x WHERE aftervoid != beforevoid ;
+
+
+CREATE OR REPLACE FUNCTION invfifo_cohead_void_flag_order_force(i_cohead_id integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+           
+    v_tmp INTEGER;
+    v_bool BOOLEAN; 
+    v_checksum NUMERIC;
+    v_cohead_number text;
+    v_ret boolean;
+BEGIN
+    
+    UPDATE invfifo SET invfifo_void = 0 WHERE invfifo_cohead_id = i_cohead_id;
+    
+    SELECT invfifo_cohead_void_flag_order(i_cohead_id ) INTO v_ret;
+    
+    RETURN v_ret;
+
+    
+     END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cohead_void_flag_order_force(integer )
+  OWNER TO admin;
+          
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_cohead_void_flag_order(i_cohead_id integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+           
+    v_tmp INTEGER;
+    v_bool BOOLEAN; 
+    v_checksum NUMERIC;
+    v_cohead_number text;
+BEGIN
+    
+    -- this is just way to slow...
+    
+    --SELECT
+    --        invfifo_cohead_check_id()
+    --    INTO
+    --        v_bool;
+    --
+    --IF NOT v_bool THEN
+    --    -- slowish.. 0.5s
+    --    PERFORM invfifo_cohead_fix_id(invdetail_id)
+    --        FROM
+    --            invdetailview
+    --        WHERE
+    --             invhist_ordtype  ='SO'
+    --             AND
+    --             invfifo_cohead_id = 0;
+    --             
+    --END IF;
+    --
+    SELECT
+            cohead_number
+        INTO
+            v_cohead_number
+        FROM
+            cohead
+        WHERE
+            cohead_id = i_cohead_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Error finding cohead_id %', i_cohead_id;
+    END IF;
+    --
+    --
+    PERFORM invfifo_cohead_void_flag_tx( invdetail_id, invhist_ordnumber, invhist_itemsite_id, invdetail_qty)
+        FROM
+            invdetailview
+        WHERE 
+            
+                invhist_ordtype = 'SO'
+            AND
+                invfifo_cohead_id = i_cohead_id
+            AND
+                invdetail_qty > 0
+             
+            ORDER BY
+                invdetail_id ASC;
+    -- do a sanity check.. - might be a bit slow... - find the total sum of voided transactions = eg. +v and -ve must be 0
+    SELECT 
+                COALESCE(SUM(invdetail_qty), 0.0)
+            INTO
+                v_checksum
+             FROM 
+                invdetailview
+             WHERE 
+                 
+                     invhist_ordtype = 'SO'
+                AND
+                    invfifo_cohead_id = i_cohead_id
+                 AND
+                     invfifo_void != 0  ;
+    
+    if (v_checksum != 0.0) THEN
+        -- reset all the foid flags, then try again..
+    
+        UPDATE
+                invfifo
+            set
+                invfifo_void = 0
+            where
+                invfifo_invdetail_id in (
+                    select invdetail_id
+                        from invdetailview
+                        where invhist_ordnumber like v_cohead_number || '%'
+                );
+        PERFORM invfifo_cohead_void_flag_tx( invdetail_id, invhist_ordnumber, invhist_itemsite_id, invdetail_qty)
+        FROM
+            invdetailview
+        WHERE 
+            
+                invhist_ordtype = 'SO'
+            AND
+                invfifo_cohead_id = i_cohead_id
+            AND
+                invdetail_qty > 0
+             
+            ORDER BY
+                invdetail_id ASC;
+         
+    END IF;
+    SELECT 
+                COALESCE(SUM(invdetail_qty), 0.0)
+            INTO
+                v_checksum
+             FROM 
+                invdetailview
+             WHERE 
+                 
+                     invhist_ordtype = 'SO'
+                AND
+                    invfifo_cohead_id = i_cohead_id
+                 AND
+                     invfifo_void != 0  ;
+    
+    if (v_checksum != 0.0) THEN
+         RAISE EXCEPTION 'order %  did not balance, %', v_cohead_number, v_checksum ;
+    END IF;
+    RETURN TRUE;
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cohead_void_flag_order(integer )
+  OWNER TO admin;
+          
+
+
+
+-- test: US10026-1
+-- SELECT invfifo_cohead_void_flag( 9740, 3116);
+
+-- test: HK10003-7
+-- SELECT invfifo_cohead_void_flag( 9647, 3239);
+
+
+CREATE OR REPLACE FUNCTION invfifo_cohead_void_flag(integer, integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+    i_cohead_id  ALIAS FOR $1;
+    i_itemsite_id  ALIAS FOR $2;
+    
+    v_cohead_number text;
+    
+    v_tmp_a text;
+    v_tmp_b NUMERIC;
+    v_tmp_c NUMERIC;
+
+BEGIN
+    
+    SELECT
+            cohead_number
+        INTO
+            v_cohead_number
+        FROM
+            cohead
+        WHERE
+            cohead_id = i_cohead_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Error finding cohead_id %', i_cohead_id;
+    END IF;
+    
+    -- only perform on voided records..
+
+    PERFORM invfifo_cohead_void_flag_tx( invdetail_id, invhist_ordnumber, i_itemsite_id, invdetail_qty)
+        FROM
+            (SELECT 
+                invdetail_id, invhist_ordnumber, invdetail_qty
+                FROM 
+                invdetailview
+                WHERE 
+                    
+                        invhist_ordtype = 'SO'
+                    AND
+                    (
+                        invhist_ordnumber LIKE v_cohead_number || '-%'
+                        OR
+                        invhist_ordnumber = v_cohead_number
+                    )
+                    AND
+                        invhist_itemsite_id = i_itemsite_id
+                    AND
+                        invdetail_qty > 0
+                    ORDER BY
+                        invdetail_id ASC
+            ) x;
+    -- validation.
+    
+        
+    SELECT
+        invhist_ordnumber,
+        aftervoid,
+        beforevoid
+        INTO
+        v_tmp_a,
+        v_tmp_b,
+        v_tmp_c
+        
+        FROM
+    
+        (SELECT
+            invhist_ordnumber,
+            SUM( CASE WHEN invfifo_void != 0 THEN 0 ELSE invdetail_qty END ) as aftervoid,
+            SUM(invdetail_qty) as beforevoid
+            FROM invdetailview
+            WHERE
+                invhist_ordtype = 'SO'
+            AND
+            (
+                invhist_ordnumber LIKE v_cohead_number || '-%'
+                OR
+                invhist_ordnumber = v_cohead_number
+            )
+            AND
+                invhist_itemsite_id = i_itemsite_id
+        
+            GROUP BY invhist_ordnumber
+        ) x
+            WHERE aftervoid != beforevoid
+        LIMIT 1;
+    IF FOUND THEN
+        --RAISE NOTICE 'quanties differ when applying void to %', v_tmp_a;
+    END IF;
+    
+
+
+    RETURN TRUE;
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cohead_void_flag(integer, integer )
+  OWNER TO admin;
+          
+
+--- invdetail_id , order number, 
+CREATE OR REPLACE FUNCTION invfifo_cohead_void_flag_tx(INTEGER, TEXT,INTEGER, NUMERIC)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+    i_invdetail_id  ALIAS FOR $1;
+    i_order_number ALIAS FOR $2;
+    i_itemsite_id  ALIAS FOR $3;
+    i_qty ALIAS FOR $4;
+    v_qty_balance NUMERIC;
+       v_void_of INTEGER;
+BEGIN
+    
+    
+    if (i_qty > 0) THEN
+        
+        --- got return - look for issues
+        
+        -- then it is always void!!!
+        
+        -- do we already have a void refreence for this?!?
+        
+        SELECT
+                invfifo_void
+            INTO
+                v_void_of
+            FROM
+                invdetailview
+            WHERE
+                invdetail_id = i_invdetail_id;
+        
+        IF v_void_of > 0 THEN
+            PERFORM invfifo_update_from_void(v_void_of, i_invdetail_id, true);
+            PERFORM invfifo_update_from_void(i_invdetail_id, v_void_of, true);
+            return true;
+        END IF;
+    
+            -- determine what it reverses...
+    
+            SELECT
+                    invdetail_id
+                INTO
+                    v_void_of
+                FROM
+                    invdetailview
+                WHERE
+                
+                    invhist_ordtype = 'SO'
+                AND
+                
+                    invhist_ordnumber = i_order_number
+                AND
+                    invhist_itemsite_id = i_itemsite_id
+                AND
+                    invdetail_qty = -1 * i_qty
+                AND
+                    (invfifo_void = 0 OR invfifo_void = -1)
+                ORDER BY
+                    -- FAVOUR REVERSING bad shipments first..
+                    CASE WHEN invhist_comments LIKE 'Return%' THEN 1 ELSE 0 END DESC,
+                
+                    invdetail_id ASC
+                LIMIT 1;
+                    
+            IF NOT FOUND THEN
+                RETURN false;
+            END IF;
+            
+--             RAISE EXCEPTION 'flagging issue as void %', v_void_of;
+            PERFORM invfifo_update_from_void(v_void_of, i_invdetail_id,true);
+--             RAISE NOTICE 'flagging return as void %', i_invdetail_id;
+            PERFORM invfifo_update_from_void(i_invdetail_id, v_void_of,true);
+            
+    
+          
+            return true;
+        
+        
+        
+    END IF;
+     
+    
+    RETURN FALSE;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cohead_void_flag_tx(INTEGER, TEXT,INTEGER, NUMERIC)
+  OWNER TO admin;
+          
+-- see if it works.. 
+
+--
+--SELECT invfifo_cohead_void_flag(10260, 3404);
+--
+--
+--SELECT count(invdetail_id) FROM invdetailview where invfifo_void != 0;
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-cost-at-qty.sql b/pgsql/x-fifo-invfifo-cost-at-qty.sql
new file mode 100644 (file)
index 0000000..b2def32
--- /dev/null
@@ -0,0 +1,110 @@
+
+
+
+-- find the qty available.. 
+CREATE OR REPLACE FUNCTION invfifo_cost_at_qty(integer, integer, numeric(18, 6))
+    RETURNS  numeric(18, 6) 
+    
+AS $BODY$
+DECLARE
+    i_itemsite_id  ALIAS FOR $1;
+    i_location_id  ALIAS FOR $2;
+    i_qty           ALIAS FOR $3;
+    v_ret               numeric(18, 6);
+    v_after              numeric(18, 6);
+      
+BEGIN
+       
+  
+    v_after :=0;
+   -- price at a specific qty.
+    SELECT   
+        invfifo_cost_before +
+            ((i_qty - invfifo_qty_before ) * invfifo_landedunitcost),
+            
+        invfifo_qty_after
+        INTO
+            v_ret,
+            v_after
+        FROM
+                invdetailview
+        WHERE
+            invfifo_qty_before <= i_qty
+            AND
+            invfifo_qty_after >= i_qty
+            AND    
+            invdetail_location_id = i_location_id
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0
+        LIMIT
+            1;
+    
+    IF NOT FOUND THEN
+        RETURN  -1;
+    END IF;    
+    IF v_after < 1 THEN
+        RETURN -1;
+    END IF;
+    
+    return v_ret;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cost_at_qty(integer, integer, numeric(18, 6))
+  OWNER TO admin;
+          
+
+-- find the last purchase price if it exists..
+
+CREATE OR REPLACE FUNCTION invfifo_cost_estimate(i_itemsite_id integer)
+    RETURNS  numeric(18, 6) 
+    
+AS $BODY$
+DECLARE
+    
+    v_ret numeric(18, 6);
+      
+BEGIN
+       
+   -- price at a specific qty.
+    SELECT   
+        invfifo_landedunitcost
+        INTO
+            v_ret
+        FROM
+            invdetailview
+        WHERE
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0
+            AND
+            invhist_transtype = 'RP'
+            
+        ORDER BY
+            invfifo_qty_after DESC
+        LIMIT
+            1;
+    
+    IF NOT FOUND THEN
+        RETURN  -1;
+    END IF;    
+    
+    return v_ret;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cost_estimate(i_itemsite_id integer)
+  OWNER TO admin;
+                    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-cost-before-in.sql b/pgsql/x-fifo-invfifo-cost-before-in.sql
new file mode 100644 (file)
index 0000000..588d042
--- /dev/null
@@ -0,0 +1,49 @@
+
+-- short cut to get the line before
+
+
+CREATE OR REPLACE FUNCTION invfifo_cost_before_in(NUMERIC, integer,integer)
+    RETURNS  NUMERIC 
+AS $BODY$
+DECLARE        
+           
+    i_invfifo_qty_before  ALIAS FOR $1;
+    i_location_id ALIAS FOR $2;
+    i_itemsite_id ALIAS FOR $3;
+    
+   
+    v_cost_before  NUMERIC;
+     
+
+BEGIN
+
+   SELECT
+            COALESCE(invfifo_cost_after,0.0)
+        INTO
+            v_cost_before
+        FROM
+            invdetailview
+        WHERE
+            invfifo_qty_after = i_invfifo_qty_before
+            AND            
+            invdetail_location_id = i_location_id
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0
+        ORDER BY
+            invfifo_qty_after DESC
+        LIMIT 1;
+        
+    RETURN COALESCE(v_cost_before,0);
+   
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cost_before_in(NUMERIC, integer,integer)
+  OWNER TO admin;
+     
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-cost-before-out.sql b/pgsql/x-fifo-invfifo-cost-before-out.sql
new file mode 100644 (file)
index 0000000..f875bae
--- /dev/null
@@ -0,0 +1,49 @@
+
+-- short cut to get the line before
+
+
+CREATE OR REPLACE FUNCTION invfifo_cost_before_out(NUMERIC, integer,integer)
+    RETURNS  NUMERIC 
+AS $BODY$
+DECLARE        
+           
+    i_invfifo_qty_before  ALIAS FOR $1;
+    i_location_id ALIAS FOR $2;
+    i_itemsite_id ALIAS FOR $3;
+    
+   
+    v_cost_before  NUMERIC;
+     
+
+BEGIN
+
+   SELECT
+            COALESCE(invfifo_cost_after,0.0)
+        INTO
+            v_cost_before
+        FROM
+            invdetailview
+        WHERE
+            invfifo_qty_after = i_invfifo_qty_before
+            AND            
+            invdetail_location_id = i_location_id
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0
+        ORDER BY
+            invfifo_qty_after DESC
+        LIMIT 1;
+        
+    RETURN COALESCE(v_cost_before,0);
+   
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_cost_before_out(NUMERIC, integer,integer)
+  OWNER TO admin;
+     
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-fill-all.sql b/pgsql/x-fifo-invfifo-fill-all.sql
new file mode 100644 (file)
index 0000000..5d38f01
--- /dev/null
@@ -0,0 +1,61 @@
+
+-- should not be needed anymore - is used to generate the intial data for invfifo
+
+
+CREATE OR REPLACE FUNCTION invfifo_fill_all(integer, integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+    i_location_id  ALIAS FOR $1;
+    i_itemsite_id  ALIAS FOR $2;
+ BEGIN   
+     
+    PERFORM  invfifo_fill(invdetail_id,true) FROM (
+                    SELECT
+                            invdetail_id
+                        FROM
+                            invdetailview
+       
+                        WHERE
+                            invdetail_location_id = i_location_id
+                            AND
+                            invhist_itemsite_id = i_itemsite_id
+                        ORDER BY
+                            invhist_transdate ASC,
+                            invdetail_id ASC
+                        
+                    ) x;
+    RETURN true;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_fill_all(integer, integer)
+  OWNER TO admin;
+          
+
+CREATE OR REPLACE FUNCTION invfifo_fill_all_itemsite(i_itemsite_id integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+    
+ BEGIN   
+     PERFORM  invfifo_fill_all(location_id,itemsite_id ) FROM (
+        SELECT
+                distinct(invdetail_location_id) as location_id ,
+                i_itemsite_id as itemsite_id
+            FROM
+                invdetailview
+            where
+                invhist_itemsite_id = i_itemsite_id
+    ) x;
+    RETURN true;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_fill_all(integer, integer)
+  OWNER TO admin;
+          
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-fill.sql b/pgsql/x-fifo-invfifo-fill.sql
new file mode 100644 (file)
index 0000000..a0c7016
--- /dev/null
@@ -0,0 +1,335 @@
+
+
+--- fills in the basic data from the invdetail table..
+-- fired from the trigger...
+
+-- only updates the qty's etc..
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_fill_all(integer, integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+    i_location_id  ALIAS FOR $1;
+    i_itemsite_id  ALIAS FOR $2;
+ BEGIN   
+     
+    PERFORM  invfifo_fill(invdetail_id,true) FROM (
+                    SELECT
+                            invdetail_id
+                        FROM
+                            invdetailview
+       
+                        WHERE
+                            invdetail_location_id = i_location_id
+                            AND
+                            invhist_itemsite_id = i_itemsite_id
+                        ORDER BY
+                            invhist_transdate ASC,
+                            invdetail_id ASC
+                        
+                    ) x;
+    RETURN true;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_fill_all(integer, integer)
+  OWNER TO admin;
+          
+
+
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_fill(integer)
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE
+    i_invdetail_id  ALIAS FOR $1;
+    v_ret boolean ;
+BEGIN
+    SELECT invfifo_fill(i_invdetail_id, false) INTO v_ret;
+    RETURN v_ret;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fill(integer )
+  OWNER TO admin;
+          
+
+
+-- if this is called sequentially on a location or product, then there
+-- is no need to update the following data, as it get's updated
+
+     
+
+CREATE OR REPLACE FUNCTION invfifo_fill(i_invdetail_id integer, i_skip_after boolean)
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE        
+            
+    
+    r_fifo RECORD;
+    r_invhist RECORD;
+    
+    v_costmethod TEXT;
+    v_unitcost  NUMERIC;
+    v_ret  NUMERIC;
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    
+    v_qty_before NUMERIC;
+    v_qty_after NUMERIC;
+    
+    v_cost_before NUMERIC;
+    v_change_qty NUMERIC;
+    
+    v_is_update BOOLEAN;
+BEGIN
+     
+    -- does a fifo row exist?
+    
+    SELECT
+            *
+        INTO
+            r_fifo
+        FROM
+            invfifo
+        WHERE
+            invfifo_invdetail_id = i_invdetail_id;
+    
+    
+    
+    
+    
+    
+    v_is_update := false;
+    -- already there..
+    IF FOUND THEN
+        -- should we do an update or anything?
+        -- probably not.. we can trans invfifo's before calling this.
+        
+        
+        -- make sure we have the correct amounts...
+        v_is_update := true;
+        
+        
+        
+        
+        --RETURN true;
+    END IF;
+    
+    
+    -- current record..
+    
+    SELECT
+            *
+        INTO
+            r_invhist
+        FROM
+            invdetail
+        LEFT JOIN
+            invhist
+        ON
+            invdetail_invhist_id = invhist_id
+        WHERE
+            invdetail_id = i_invdetail_id;
+    
+    
+    -- check if it's FIFO valued..
+    SELECT
+            itemsite_costmethod
+        INTO
+            v_costmethod
+        FROM
+            itemsite
+        WHERE
+            itemsite_id = r_invhist.invhist_itemsite_id;
+        
+    
+    IF (v_costmethod != 'S' OR NOT fetchMetricBool('UseStandardAsFIFO')) THEN
+        RETURN NEW;
+    END IF;
+    
+    -- work out the stock before this..
+    
+    SELECT
+            COALESCE(invfifo_qty_after, 0),
+            COALESCE(invfifo_cost_after, 0)
+        INTO
+            v_qty_before,
+            v_cost_before
+        FROM
+            invdetailview
+        WHERE
+            invdetail_location_id = r_invhist.invdetail_location_id
+            AND
+            (
+                (
+                    invhist_transdate < r_invhist.invhist_transdate
+                )
+                OR
+                (   invhist_transdate = r_invhist.invhist_transdate
+                    AND
+                    invdetail_id < i_invdetail_id
+                )
+            )
+            
+            AND
+                invhist_itemsite_id = r_invhist.invhist_itemsite_id
+            AND
+                -- if r_invhist.invdetail_qty
+                (
+                    (r_invhist.invdetail_qty > 0 AND  invdetail_qty > 0)
+                    OR
+                    (r_invhist.invdetail_qty < 0 AND  invdetail_qty < 0)
+                )
+            ORDER BY
+                invhist_transdate DESC,
+                invdetail_id DESC
+            LIMIT 1;
+      
+    --RAISE NOTICE 'qty before = %', v_qty_before;
+    v_diff := 0;
+    v_qty_before := COALESCE(v_qty_before, 0.0);
+    v_cost_before := COALESCE(v_cost_before, 0.0);
+    
+    v_change_qty := ABS(r_invhist.invdetail_qty);
+    
+    
+    
+    
+    IF v_is_update THEN
+        -- if the values are the same, then just return..
+        
+        
+        IF (r_fifo.invfifo_void != 0) THEN
+            v_change_qty = 0;
+        END IF;
+        
+        
+        IF (
+            r_fifo.invfifo_qty_before = v_qty_before
+            AND
+            r_fifo.invfifo_qty_after = v_qty_before + v_change_qty
+           ) THEN
+            RETURN true;
+        END IF;
+        
+        
+        v_diff := (v_qty_before + v_change_qty )- r_fifo.invfifo_qty_before ;
+        -- otherwise update..
+        
+        UPDATE
+            invfifo
+         
+        SET 
+         
+            invfifo_qty_before =  v_qty_before,
+            invfifo_qty_after  = v_qty_before + v_change_qty
+             
+        WHERE
+            invfifo_invdetail_id = i_invdetail_id;
+       
+        
+        
+        
+    
+    
+    ELSE
+        v_diff :=   v_change_qty;
+        
+        INSERT INTO  invfifo (
+            invfifo_invdetail_id,  invfifo_unitcost  , invfifo_totalcost,
+            invfifo_cost_before, invfifo_cost_after,
+            
+            invfifo_qty_before, invfifo_qty_after,
+            invfifo_is_estimate, invfifo_recalc_queued,
+            
+            invfifo_cust_id, invfifo_vend_id
+        ) VALUES  (
+            r_invhist.invdetail_id, 0, 0,
+            v_cost_before, v_cost_before,  -- these are the same value - as by default we do not adjust the future..
+            
+            v_qty_before, v_qty_before + v_change_qty,
+            false, true,
+            
+            null, null
+        );
+    END IF;
+    -- next adjust quanties of future items by the qty.
+    
+    
+    IF i_skip_after THEN
+        RETURN true;
+    END IF;
+    
+    IF v_diff = 0.0 THEN
+        RETURN true;
+    END IF;
+    
+    
+    UPDATE
+            invfifo
+         
+         SET 
+         
+            invfifo_qty_before = invfifo_qty_before +  v_diff,
+            invfifo_qty_after  = invfifo_qty_after +  v_diff
+             
+         FROM
+            invdetail, invhist
+             
+         WHERE
+                invfifo_invdetail_id = invdetail_id
+             AND
+                invhist_id = invdetail_invhist_id
+             AND
+                invdetail_location_id = r_invhist.invdetail_location_id
+             AND
+                invhist_transdate > r_invhist.invhist_transdate
+             AND
+                invhist_itemsite_id = r_invhist.invhist_itemsite_id
+             AND
+                (
+                    (r_invhist.invdetail_qty> 0 AND  invdetail_qty > 0)
+                    OR
+                    (r_invhist.invdetail_qty < 0 AND  invdetail_qty < 0)
+                );
+    
+    
+    -- at this point it should call the relivant updater ... to fill in values..
+    -- that in turn will flag all the dirty values..
+    
+    
+    -- this may cause a big slowdown?!?!
+    --PERFORM invfifo_update_from_invdetail(i_invdetail_id);
+    
+    -- initially the trigger will not cause a update of all the dependant data..??
+    -- it will probably only just flag stuff as dirty..
+    -- we will need to run a call periodically to try and recalc stuff.
+    
+    
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fill(integer, boolean )
+  OWNER TO admin;
+          
+    
+    
+    
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-fix-cohead-id.sql b/pgsql/x-fifo-invfifo-fix-cohead-id.sql
new file mode 100644 (file)
index 0000000..f332815
--- /dev/null
@@ -0,0 +1,74 @@
+CREATE OR REPLACE FUNCTION invfifo_cohead_fix_id(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+v_cohead_id INTEGER;
+v_cohead_number TEXT;
+BEGIN
+    SELECT split_part(invhist_ordnumber, '-', 1) INTO v_cohead_number FROM invdetailview WHERE invdetail_id = i_invdetail_id;
+    SELECT cohead_id INTO v_cohead_id from cohead where cohead_number = v_cohead_number;
+    
+    UPDATE invfifo
+        SET
+            invfifo_cohead_id = v_cohead_id
+        WHERE
+            invfifo_invdetail_id = i_invdetail_id;
+            
+    RETURN true;
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+    
+ALTER FUNCTION   invfifo_cohead_fix_id()
+  OWNER TO admin;
+  
+  
+  
+  
+  
+CREATE OR REPLACE FUNCTION invfifo_cohead_check_id() STABLE
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+
+v_tmp INTEGER;
+
+BEGIN
+    
+
+    SELECT
+            count(invdetail_id)
+        INTO
+            v_tmp
+        FROM
+            invdetailview
+        WHERE
+            invhist_ordtype = 'SO'
+        AND
+            invfifo_cohead_id = 0
+    IF v_tmp > 0 THEN
+        RETURN false;
+    END;
+    RETURN true;
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+    
+ALTER FUNCTION   invfifo_cohead_check_id()
+  OWNER TO admin;
+  
+  
+  
+  --
+  --SELECT
+  --  invfifo_fix_cohead_id(invdetail_id) from invdetailview
+  --   WHERE
+  --              invhist_ordtype  ='SO'
+  --              AND
+  --              invfifo_cohead_id = 0
+  --  
+  --                
diff --git a/pgsql/x-fifo-invfifo-fixCmvoid.sql b/pgsql/x-fifo-invfifo-fixCmvoid.sql
new file mode 100644 (file)
index 0000000..ba78c9a
--- /dev/null
@@ -0,0 +1,140 @@
+
+DROP FUNCTION IF EXISTS invfifo_fixCmvoid();
+
+CREATE OR REPLACE FUNCTION invfifo_fixCmvoid()
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    v_location INTEGER;
+    v_count INTEGER;
+    v_itemloc_id INTEGER;
+    v_itemloc_qty NUMERIC;
+    v_hasItemloc BOOLEAN;
+    v_ret INTEGER;
+    _r RECORD;
+BEGIN
+    v_ret := 0;
+    FOR _r IN (SELECT * FROM invhist WHERE invhist_comments LIKE 'Credit Voided%' AND NOT invhist_hasdetail) LOOP
+    
+        -- get's location 
+        SELECT 
+            cmhead_location_id 
+        INTO 
+            v_location 
+        FROM 
+            cmhead
+        WHERE 
+            cmhead_number = _r.invhist_ordnumber;
+
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'could not find the location of credit memo : %' , _r.invhist_ordnumber;
+        END IF;
+        
+        
+        -- item loc qty / and id
+        
+        v_hasItemloc := TRUE;
+        SELECT
+            itemloc_id,
+            itemloc_qty
+        INTO
+            v_itemloc_id,
+            v_itemloc_qty
+        FROM 
+            itemloc
+        WHERE
+            itemloc_itemsite_id = _r.invhist_itemsite_id
+            AND
+            itemloc_location_id = v_location;
+
+        IF NOT FOUND THEN
+            v_itemloc_qty = 0;
+            v_hasItemloc = FALSE;
+        END IF;
+        
+        -- check if no records already found for it.?
+        
+
+        SELECT 
+            COUNT(invdetail_id)
+        INTO
+            v_count
+        FROM 
+            invdetail
+        WHERE
+            invdetail_invhist_id = _r.invhist_id
+            AND
+            invdetail_location_id = v_location
+            AND
+            invdetail_qty > 0;
+        
+        IF (v_count > 0) THEN
+            
+            RAISE NOTICE 'Invdetail found, credit memo : %, invhist_id : %, location : %, qty : %',
+                                                     _r.invhist_ordnumber, _r.invhist_id, v_location, invdetail_qty;
+                                                     
+            CONTINUE;
+        END IF;
+        
+        v_ret = v_ret + 1;
+        
+        -- add the invdetail record...
+        
+        INSERT INTO invdetail
+        ( invdetail_invhist_id, invdetail_location_id,
+          invdetail_qty, invdetail_comments,
+          invdetail_qty_before, invdetail_qty_after,
+          invdetail_expiration 
+        )
+        VALUES
+        ( _r.invhist_id, v_location,
+          _r.invhist_invqty, 'FIX CM VOID - ' || _r.invhist_ordnumber,
+          v_itemloc_qty, (v_itemloc_qty+_r.invhist_invqty),
+          '2100-01-01'::date 
+        );
+        -- flag has detail..
+
+        UPDATE 
+            invhist
+        SET 
+            invhist_hasdetail = TRUE
+        WHERE 
+            invhist_hasdetail = FALSE
+            AND 
+            invhist_id=_r.invhist_id;
+
+        -- update itemloc or create
+        IF (v_hasItemloc) THEN
+            UPDATE 
+                itemloc
+            SET 
+                itemloc_qty = (v_itemloc_qty + _r.invhist_invqty)
+            WHERE 
+                itemloc_id = v_itemloc_id;
+                
+
+            CONTINUE;
+        END IF;
+
+        INSERT INTO itemloc
+        ( itemloc_itemsite_id, itemloc_location_id,
+          itemloc_qty, itemloc_expiration
+        )
+        VALUES
+        ( _r.invhist_itemsite_id, v_location,
+          _r.invhist_invqty, '2100-01-01'::date 
+        );    
+        
+
+    END LOOP;
+
+    RETURN 'UPDATE ' || v_ret || ' CREDIT MEMOS' ;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixCmvoid()
+  OWNER TO admin;    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-fixInvdetail.sql b/pgsql/x-fifo-invfifo-fixInvdetail.sql
new file mode 100644 (file)
index 0000000..c998670
--- /dev/null
@@ -0,0 +1,498 @@
+
+DROP FUNCTION IF EXISTS invfifo_fixInvdetail(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_fixInvdetail( i_invhist_id integer)
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    
+    v_location INTEGER;
+    v_count INTEGER;
+    v_itemloc_id INTEGER;
+    v_itemloc_qty NUMERIC;
+    v_hasItemloc BOOLEAN;
+    v_invdetail_id INTEGER;
+    v_cohead_id INTEGER;
+    v_cohead_number TEXT;
+    _r RECORD;
+BEGIN
+    
+        SELECT * INTO _r FROM invhist WHERE invhist_id = i_invhist_id;
+
+
+        -- verify it does not already exist..
+        SELECT invdetail_id INTO v_invdetail_id FROM invdetail where invdetail_invhist_id = i_invhist_id;
+        IF FOUND THEN
+            return "ALREADY THERE";
+        END IF;
+
+        -- work out it's cohead_id
+       -- invhist_ordnumber
+        SELECT split_part(_r.invhist_ordnumber, '-', 1) INTO v_cohead_number;
+        SELECT cohead_id INTO v_cohead_id from cohead where cohead_number = v_cohead_number;
+   
+        
+        -- get's location 
+        SELECT 
+            cohead_location_src
+        INTO 
+            v_location 
+        FROM 
+            cohead
+        WHERE 
+            cohead_id = v_cohead_id;
+
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'could not find the location of sales order : %' , v_cohead_id;
+        END IF;
+        
+        
+        
+        
+        
+        -- item loc qty / and id
+        
+        v_hasItemloc := TRUE;
+        SELECT
+            itemloc_id,
+            itemloc_qty
+        INTO
+            v_itemloc_id,
+            v_itemloc_qty
+        FROM 
+            itemloc
+        WHERE
+            itemloc_itemsite_id = _r.invhist_itemsite_id
+            AND
+            itemloc_location_id = v_location;
+
+        IF NOT FOUND THEN
+            v_itemloc_qty = 0;
+            v_hasItemloc = FALSE;
+        END IF;
+        
+        -- check if no records already found for it.?
+        
+
+        SELECT 
+            COUNT(invdetail_id)
+        INTO
+            v_count
+        FROM 
+            invdetail
+        WHERE
+            invdetail_invhist_id = _r.invhist_id
+            AND
+            invdetail_location_id = v_location
+            AND
+            invdetail_qty > 0;
+        
+        IF (v_count > 0) THEN
+            
+            RAISE EXCEPTION 'Invdetail found';
+        END IF;
+       
+        -- add the invdetail record...
+        
+        INSERT INTO invdetail
+        ( invdetail_invhist_id, invdetail_location_id,
+          invdetail_qty, invdetail_comments,
+          invdetail_qty_before, invdetail_qty_after,
+          invdetail_expiration 
+        )
+        VALUES
+        ( _r.invhist_id, v_location,
+          _r.invhist_invqty, 'FIX INVDETAIL - ' || _r.invhist_ordnumber,
+          v_itemloc_qty * -1, (v_itemloc_qty-_r.invhist_invqty),
+          '2100-01-01'::date 
+        );
+        -- flag has detail..
+
+        UPDATE 
+            invhist
+        SET 
+            invhist_hasdetail = TRUE
+        WHERE 
+            invhist_hasdetail = FALSE
+            AND 
+            invhist_id=_r.invhist_id;
+
+        -- update itemloc or create
+        IF (v_hasItemloc) THEN
+            UPDATE 
+                itemloc
+            SET 
+                itemloc_qty = (v_itemloc_qty - _r.invhist_invqty)
+            WHERE 
+                itemloc_id = v_itemloc_id;
+        
+        ELSE
+
+            INSERT INTO itemloc
+            ( itemloc_itemsite_id, itemloc_location_id,
+              itemloc_qty, itemloc_expiration
+            )
+            VALUES
+            ( _r.invhist_itemsite_id, v_location,
+              _r.invhist_invqty * -1, '2100-01-01'::date 
+            );    
+        
+        END IF;
+
+    SELECT invdetail_id FROM invdetail INTO v_invdetail_id WHERE invdetail_invhist_id = _r.invhist_id AND invdetail_location_id = v_location;
+
+    UPDATE 
+        invfifo
+    SET 
+        invfifo_cohead_id = v_cohead_id
+    WHERE 
+        invfifo_invdetail_id = v_invdetail_id;
+
+    RETURN 'INSERTED' ;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixInvdetail(integer )
+  OWNER TO admin;    
+DROP FUNCTION IF EXISTS invfifo_fixInvdetail_in(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_fixInvdetail_in( i_invhist_id integer)
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    
+    v_location INTEGER;
+    v_count INTEGER;
+    v_itemloc_id INTEGER;
+    v_itemloc_qty NUMERIC;
+    v_hasItemloc BOOLEAN;
+    v_invdetail_id INTEGER;
+    v_cohead_id INTEGER;
+    v_tmp INTEGER;
+    
+    
+    v_transfer_number TEXT;
+    _r RECORD;
+BEGIN
+    
+        SELECT *
+            INTO
+                _r
+            FROM
+                invhist
+            LEFT JOIN
+                itemsite
+            on
+                invhist_itemsite_id = itemsite_id
+            WHERE
+                invhist_id = i_invhist_id;
+
+        
+        -- verify it does not already exist..
+        SELECT invdetail_id INTO v_invdetail_id FROM invdetail where invdetail_invhist_id = i_invhist_id;
+        IF FOUND THEN
+            return "ALREADY THERE";
+        END IF;
+
+        IF _r.invhist_ordtype != 'IN' THEN
+                return "Not an invoice";
+        END IF;
+
+
+        -- work out it's invoice....
+        
+        SELECT
+                count(invcitem_id)
+            INTO
+                v_tmp
+            
+            from
+                invcitem
+            LEFT JOIN
+                invchead
+            ON
+                invcitem_invchead_id = invchead_id
+            WHERE
+                    invcitem_updateinv
+                AND
+                    invcitem_item_id = _r.itemsite_item_id
+                AND
+                     _r.invhist_invqty  = invcitem_ordered
+                AND
+                    invchead_ordernumber like 'XF-%'
+                and
+                    invchead_gldistdate = _r.invhist_transdate::date;
+        
+        
+        
+        
+        IF v_tmp != 1 THEN
+            RAISE EXCEPTION 'could not find matching invoice';
+        END IF;
+        
+        -- now we know there is an invoice for it... 
+        
+        SELECT
+                split_part(invchead_ordernumber, '-', 4) 
+            INTO
+                v_transfer_number
+            from
+                invcitem
+            LEFT JOIN
+                invchead
+            ON
+                invcitem_invchead_id = invchead_id
+            WHERE
+                    invcitem_updateinv
+                AND
+                    invcitem_item_id = _r.itemsite_item_id
+                AND
+                    _r.invhist_invqty = invcitem_ordered
+                AND
+                    invchead_ordernumber like 'XF-%'
+                and
+                    invchead_gldistdate = _r.invhist_transdate::date
+                LIMIT 1;
+        
+        
+        -- from the transfer we can work out the location
+        
+        SELECT
+                invhist_transfer_from
+            INTO 
+                v_location
+            FROM
+                invhist_transfer
+            WHERE
+                invhist_transfer_number = v_transfer_number;
+                
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'could not find the location of transfer: %' , v_transfer_number;
+        END IF;
+        
+        
+        
+        
+        
+        -- item loc qty / and id
+        
+        v_hasItemloc := TRUE;
+        SELECT
+            itemloc_id,
+            itemloc_qty
+        INTO
+            v_itemloc_id,
+            v_itemloc_qty
+        FROM 
+            itemloc
+        WHERE
+            itemloc_itemsite_id = _r.invhist_itemsite_id
+            AND
+            itemloc_location_id = v_location;
+
+        IF NOT FOUND THEN
+            v_itemloc_qty = 0;
+            v_hasItemloc = FALSE;
+        END IF;
+        
+        -- check if no records already found for it.?
+        
+
+        SELECT 
+            COUNT(invdetail_id)
+        INTO
+            v_count
+        FROM 
+            invdetail
+        WHERE
+            invdetail_invhist_id = _r.invhist_id
+            AND
+            invdetail_location_id = v_location
+            AND
+            invdetail_qty > 0;
+        
+        IF (v_count > 0) THEN
+            
+            RAISE EXCEPTION 'Invdetail found';
+        END IF;
+       
+        -- add the invdetail record...
+        
+        INSERT INTO invdetail
+        ( invdetail_invhist_id, invdetail_location_id,
+          invdetail_qty , invdetail_comments,
+          invdetail_qty_before, invdetail_qty_after,
+          invdetail_expiration 
+        )
+        VALUES
+        ( _r.invhist_id, v_location,
+          _r.invhist_invqty * -1, 'FIX INVDETAIL - ' || v_transfer_number,
+          v_itemloc_qty, (v_itemloc_qty-_r.invhist_invqty),
+          '2100-01-01'::date 
+        );
+        -- flag has detail..
+
+        UPDATE 
+            invhist
+        SET 
+            invhist_hasdetail = TRUE
+        WHERE 
+            invhist_hasdetail = FALSE
+            AND 
+            invhist_id=_r.invhist_id;
+
+        -- update itemloc or create
+        IF (v_hasItemloc) THEN
+            UPDATE 
+                itemloc
+            SET 
+                itemloc_qty = (v_itemloc_qty - _r.invhist_invqty)
+            WHERE 
+                itemloc_id = v_itemloc_id;
+        
+        ELSE
+
+            INSERT INTO itemloc
+            ( itemloc_itemsite_id, itemloc_location_id,
+              itemloc_qty, itemloc_expiration
+            )
+            VALUES
+            ( _r.invhist_itemsite_id, v_location,
+              _r.invhist_invqty, '2100-01-01'::date 
+            );    
+        
+        END IF;
+
+         
+
+    RETURN 'INSERTED' ;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixInvdetail_in(integer)
+  OWNER TO admin;    
+--select invfifo_fixInvdetail_in( invhist_id ) from invhist left join invdetail on invdetail_invhist_id = invhist_id where invdetail_id IS NULL and invhist_ordtype = 'IN'  limit 1;
+
+DROP FUNCTION IF EXISTS invfifo_fixInvdetail_up(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_fixInvdetail_up( i_invdetail_id integer)
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    
+    v_location INTEGER;
+    v_count INTEGER;
+    v_itemloc_id INTEGER;
+    v_itemloc_qty NUMERIC;
+    v_hasItemloc BOOLEAN;
+    v_invdetail_id INTEGER;
+    v_cohead_id INTEGER;
+    v_tmp INTEGER;
+    
+    v_transfer_number TEXT;
+    _r RECORD;
+BEGIN
+    
+        SELECT *
+            INTO
+                _r
+            FROM
+                invdetailview
+            
+            WHERE
+                invdetail_id = i_invdetail_id
+                AND
+                invdetail_comments like 'FIX INVDETAIL%'
+                AND
+                invdetail_qty > 0;
+
+        IF NOT FOUND THEN
+            PERFORM invfifo_fill(i_invdetail_id);
+        
+            return 'ALREADY FIXED';
+        END IF;
+        
+        
+        -- item loc qty / and id
+        
+        v_hasItemloc := TRUE;
+        SELECT
+            itemloc_id,
+            itemloc_qty
+        INTO
+            v_itemloc_id,
+            v_itemloc_qty
+        FROM 
+            itemloc
+        WHERE
+            itemloc_itemsite_id = _r.invhist_itemsite_id
+            AND
+            itemloc_location_id = _r.invdetail_location_id;
+
+        IF NOT FOUND THEN
+            v_itemloc_qty = 0;
+            v_hasItemloc = FALSE;
+        END IF;
+        
+        -- check if no records already found for it.?
+        
+       
+        -- add the invdetail record...
+        UPDATE invdetail SET
+            invdetail_qty = _r.invdetail_qty * -1,
+            invdetail_qty_after = _r.invdetail_qty_before - _r.invdetail_qty
+            WHERE
+            invdetail_id = i_invdetail_id;
+              
+
+        -- update itemloc or create
+        IF (v_hasItemloc) THEN
+            UPDATE 
+                itemloc
+            SET 
+                itemloc_qty = (v_itemloc_qty - ( 2 * _r.invhist_invqty))
+            WHERE 
+                itemloc_id = v_itemloc_id;
+        
+        ELSE
+            -- this should not happen....
+            INSERT INTO itemloc
+            ( itemloc_itemsite_id, itemloc_location_id,
+              itemloc_qty, itemloc_expiration
+            )
+            VALUES
+            ( _r.invhist_itemsite_id, _r.invdetail_location_id,
+               -1 * _r.invhist_invqty, '2100-01-01'::date 
+            );    
+        
+        END IF;
+        PERFORM invfifo_fill(i_invdetail_id);
+         
+
+    RETURN 'FIXED' ;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixInvdetail_up(integer)
+  OWNER TO admin;    
+--  selecT invfifo_fixInvdetail_up(invdetail_id) from invdetail where invdetail_comments like 'FIX INVD%' limit 1;
+
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-fixPoVariance.sql b/pgsql/x-fifo-invfifo-fixPoVariance.sql
new file mode 100644 (file)
index 0000000..2054886
--- /dev/null
@@ -0,0 +1,579 @@
+
+-- delete the variance of the old void purchase order..
+-- it looks like this will only void the variance transaction - not any other part of the trnasactions.
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_fixPoVariance_all()
+    RETURNS  TEXT
+AS $BODY$
+DECLARE    
+    _r RECORD;
+    v_asset_accnt_id INTEGER;
+    v_resultbool BOOLEAN;
+    v_count INTEGER := 0;
+    v_skip_count INTEGER := 0;
+    v_gltrans_sequence INTEGER;
+    v_item_number TEXT;
+BEGIN
+   
+    IF (NOT fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
+        RETURN 'Purchase Price Variance on Receipt option is FALSE';
+    END IF;
+    
+    SELECT costcat_asset_accnt_id INTO v_asset_accnt_id FROM costcat LIMIT 1;
+    FOR _r IN SELECT gltrans_id, gltrans_docnumber,gltrans_amount
+                FROM
+                    gltrans
+                WHERE
+                    gltrans_accnt_id = v_asset_accnt_id
+                    AND gltrans_doctype = 'PO' 
+                    AND gltrans_source = 'S/R' 
+                    AND gltrans_notes = 'Return Inventory to P/O' LOOP
+        
+        
+        RAISE NOTICE 'gltrans_docnumber : % , gltrans_amount : % , gltrans_id : % ', _r.gltrans_docnumber, _r.gltrans_amount, _r.gltrans_id;
+        
+
+        SELECT 
+            item_number 
+        INTO
+            v_item_number
+        FROM 
+            item 
+        WHERE
+            item_id = (
+                        SELECT 
+                            itemsite_item_id 
+                        FROM  
+                            poitem 
+                        LEFT JOIN itemsite ON itemsite_id = poitem_itemsite_id 
+                        WHERE
+                            poitem_pohead_id = (SELECT pohead_id FROM pohead WHERE pohead_number = reverse(regexp_replace(reverse(_r.gltrans_docnumber),'^[0-9]{1,}-', '')))
+                            AND
+                            poitem_linenumber = (SELECT reverse(split_part(reverse(_r.gltrans_docnumber),'-',1))::integer)
+                        );
+            
+        
+        SELECT 
+            gltrans_sequence 
+        INTO 
+            v_gltrans_sequence
+        FROM
+            gltrans
+        WHERE
+            gltrans_docnumber = reverse(regexp_replace(reverse(_r.gltrans_docnumber),'^[0-9]{1,}-', ''))
+            AND
+            gltrans_id < _r.gltrans_id
+            AND
+            gltrans_doctype = 'PO'
+            AND
+            gltrans_source = 'S/R'
+            AND
+            gltrans_notes LIKE 'Purchase price variance adjusted for P/O%' || v_item_number
+            AND
+            gltrans_accnt_id = v_asset_accnt_id
+            AND
+            gltrans_misc_id = -1
+            AND
+            NOT gltrans_deleted
+        ORDER BY gltrans_id DESC LIMIT 1;
+        
+        IF NOT FOUND THEN
+            v_skip_count = v_skip_count + 1;
+            RAISE NOTICE 'SKIP - NO Variance found for %', _r.gltrans_docnumber;
+            CONTINUE;
+        END IF;
+        
+
+        SELECT deleteGlSeries(v_gltrans_sequence ,  'Fix Purchase Price Variance on ' || to_char(NOW(), 'Day Mon DD YYY') ) INTO v_resultbool;
+
+        IF (v_resultbool) THEN
+            v_count = v_count + 1;
+            RAISE NOTICE 'Deleted sequence : % ', v_gltrans_sequence;
+        ELSE
+            RAISE EXCEPTION 'Fail to delete sequence : % ', v_gltrans_sequence;
+        END IF;
+
+    END LOOP;
+    
+
+    RETURN 'DONE - Fixed : ' || v_count || ' transactions ,  Skip count : ' || v_skip_count;
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixPoVariance_all()
+  OWNER TO admin;
+
+
+-- void the variance on voucher
+-- this inserts a GL transaction to have the effect of voiding the Variance posted on a reciept
+
+
+CREATE OR REPLACE FUNCTION invfifo_voidvoucher(i_pohead_number text)
+    RETURNS  TEXT
+AS $BODY$
+DECLARE    
+    _r RECORD;
+    _v RECORD;
+    v_asset_accnt_id INTEGER;
+    v_lb_accnt_id INTEGER;
+    v_result INTEGER;
+    v_amount NUMERIC := 0;
+    
+BEGIN
+   
+    IF (NOT fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
+        RETURN 'Purchase Price Variance on Receipt option is FALSE';
+    END IF;
+
+    SELECT 
+            costcat_asset_accnt_id,
+            costcat_liability_accnt_id
+    INTO 
+            v_asset_accnt_id,
+            v_lb_accnt_id
+    FROM 
+            costcat 
+    LIMIT 1;
+
+    FOR _v IN SELECT
+                    vohead_number
+            FROM 
+                    vohead
+            LEFT JOIN 
+                    pohead
+            ON  
+                    pohead_id = vohead_pohead_id
+            WHERE
+                    pohead_number = i_pohead_number LOOP
+    
+
+
+            RAISE NOTICE 'Voucher number :  %', _v.vohead_number;
+
+    
+    
+            FOR _r IN SELECT 
+                                COALESCE(gltrans_amount,0) AS gltrans_amount,
+                                gltrans_date
+                        FROM 
+                                gltrans 
+                        WHERE 
+                                gltrans_docnumber = _v.vohead_number 
+                            AND 
+                                gltrans_accnt_id = v_asset_accnt_id LOOP
+
+
+                IF (_r.gltrans_amount <> 0) THEN
+                    SELECT insertGLTransaction(
+                                                  fetchJournalNumber('AP-VO'), 'A/P', 'VO', _v.vohead_number,
+                                                  'Reverse the variance on voucher for P/O ' || i_pohead_number,
+                                                  v_lb_accnt_id,
+                                                  getPrjAccntId(0, v_asset_accnt_id), NULL,
+                                                  _r.gltrans_amount,
+                                                  _r.gltrans_date::date ) INTO v_result;
+
+                    IF (v_result < 0 AND v_result != -3) THEN -- error but not 0-value transaction
+                        RAISE NOTICE 'Result  : %' , v_result;
+                        CONTINUE;
+                    END IF;
+
+                    v_amount = v_amount + _r.gltrans_amount;
+                END IF;
+
+            END LOOP;
+    END LOOP;
+
+    RETURN 'Reserved! Amount : ' || v_amount;
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_voidvoucher(text)
+  OWNER TO admin;
+
+
+
+-- re-calculate the variance for recevied items
+
+CREATE OR REPLACE FUNCTION invfifo_addVariance(i_number text, i_invhist_id integer)
+    RETURNS  INTEGER
+AS $BODY$
+DECLARE    
+    _p RECORD;
+    _r RECORD;
+    v_diff NUMERIC;
+    v_qty NUMERIC;
+    v_date DATE;
+    v_purchprice_accnt_id INTEGER;
+    v_lb_accnt_id INTEGER;
+    v_result INTEGER;
+    v_gltrans_id INTEGER;
+    
+BEGIN
+   
+    IF (NOT fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
+        RETURN 'Purchase Price Variance on Receipt option is FALSE';
+    END IF;
+
+    SELECT 
+            costcat_purchprice_accnt_id,
+            costcat_liability_accnt_id
+    INTO 
+            v_purchprice_accnt_id,
+            v_lb_accnt_id
+    FROM 
+            costcat 
+    LIMIT 1;
+    
+    SELECT
+            *,
+            currToBase(pohead_curr_id, poitem_unitprice,  pohead_orderdate) AS poitem_unitprice_base
+    INTO
+            _p
+    FROM
+            pohead,poitem,itemsite,item
+    WHERE
+            pohead_id = poitem_pohead_id
+        AND
+            poitem_itemsite_id = itemsite_id
+        AND
+            itemsite_item_id = item_id
+        AND
+            poitem_linenumber = reverse(split_part(reverse(i_number), '-', 1))::integer
+        AND
+            pohead_number = reverse(regexp_replace(reverse(i_number),'^[0-9]{1,}-', ''));
+
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Can not found PO # : %', reverse(regexp_replace(reverse(i_number),'^[0-9]{1,}-', ''));
+    END IF;
+
+    SELECT 
+            invhist_value_after - invhist_value_before,
+            invdetail_qty,
+            invhist_transdate::date
+    INTO
+            v_diff,
+            v_qty,
+            v_date
+    FROM
+            invdetailview
+    WHERE
+            invhist_id = i_invhist_id;
+    
+    SELECT
+            gltrans_id
+    INTO    
+            v_gltrans_id
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_purchprice_accnt_id
+        AND
+            gltrans_doctype = 'PO'
+        AND
+            gltrans_notes = 'Purchase price variance adjusted for P/O ' || _p.pohead_number || ' for item ' || _p.item_number
+        AND
+            NOT gltrans_deleted;
+
+    IF FOUND THEN
+        RETURN 0;
+    END IF;
+        
+    SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
+                                   'S/R', 'PO', _p.pohead_number,
+                                  'Purchase price variance adjusted for P/O ' || _p.pohead_number || ' for item ' || _p.item_number,
+                                  v_lb_accnt_id,
+                                  v_purchprice_accnt_id, -1,
+                                  (_p.poitem_unitprice_base * v_qty) - v_diff,
+                                  v_date::DATE, true ) INTO v_result;
+    
+
+    RETURN v_result;
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_addVariance(text, integer)
+  OWNER TO admin;
+
+
+-- void all the exist variance and add one for whole order-----------------
+
+CREATE OR REPLACE FUNCTION invfifo_addVariance_all(i_pohead_number text)
+    RETURNS  INTEGER
+AS $BODY$
+DECLARE    
+    _p RECORD;
+    v_date DATE;
+    v_purchprice_accnt_id INTEGER;
+    v_lb_accnt_id INTEGER;
+    v_result INTEGER;
+    v_base NUMERIC;
+    v_diff NUMERIC;
+    v_value NUMERIC;
+    v_gltrans_amount NUMERIC;
+    
+BEGIN
+   
+    v_result := 0;
+
+    IF (NOT fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
+        RETURN 'Purchase Price Variance on Receipt option is FALSE';
+    END IF;
+
+    SELECT 
+            costcat_purchprice_accnt_id,
+            costcat_liability_accnt_id
+    INTO 
+            v_purchprice_accnt_id,
+            v_lb_accnt_id
+    FROM 
+            costcat 
+    LIMIT 1;
+    
+    SELECT 
+            SUM(currToBase(pohead_curr_id, poitem_unitprice,  pohead_orderdate) * (poitem_qty_received - poitem_qty_returned))
+    INTO
+            v_base
+    FROM 
+            poitem
+    LEFT JOIN
+            pohead
+    ON
+            pohead_id = poitem_pohead_id
+
+    WHERE pohead_number = i_pohead_number;
+
+
+    SELECT
+            SUM(invhist_value_after - invhist_value_before)
+    INTO
+            v_diff
+    FROM
+            invdetailview
+    WHERE
+            (
+                invhist_ordnumber LIKE i_pohead_number || '-%'
+                OR
+                invhist_ordnumber = i_pohead_number
+            )
+        AND
+            invfifo_void = 0;
+
+    SELECT
+            *
+    INTO
+            _p
+    FROM
+            pohead
+    WHERE   
+            pohead_number = i_pohead_number;
+
+
+    SELECT 
+            MAX(recv_date)::date
+    INTO
+            v_date
+    FROM
+            recv
+    LEFT JOIN
+            recvgrp
+    ON
+            recvgrp_id = recv_recvgrp_id
+    WHERE
+            (recvgrp_void = 0 OR recvgrp_void IS NULL)
+        AND
+            recv_order_number = i_pohead_number;
+
+
+    PERFORM deleteGlSeries( gltrans_sequence,  'Fix Purchase Price Variance on ' || to_char(NOW(), 'Day Mon DD YYY') )
+
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_purchprice_accnt_id
+        AND
+            gltrans_doctype = 'PO'
+        AND
+            gltrans_notes LIKE 'Purchase price variance adjusted for P/O ' || _p.pohead_number || '%'
+            OR
+            gltrans_notes LIKE 'Void Purchase price variance adjusted for P/O ' || _p.pohead_number || '%'
+        AND
+            NOT gltrans_deleted;
+
+
+    v_value = v_base - v_diff;
+
+        
+    IF (ABS(v_value) <> 0) THEN
+        SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
+                                       'S/R', 'PO', _p.pohead_number,
+                                      'Purchase price variance adjusted for P/O ' || _p.pohead_number || ' on ' || v_date,
+                                      v_lb_accnt_id,
+                                      v_purchprice_accnt_id, -1,
+                                      v_value,
+                                      v_date::DATE, true ) INTO v_result;
+    END IF;
+    
+
+    RETURN v_result;
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_addVariance_all(text)
+  OWNER TO admin;
+
+
+
+
+-- fix the unit cost difference...
+-- eg: receive item is $1
+--     void is $2
+-- add a transaction for the difference
+
+CREATE OR REPLACE FUNCTION invfifo_fixUnitCost(i_pohead_number text)
+    RETURNS  INTEGER
+AS $BODY$
+DECLARE    
+    v_purchprice_accnt_id INTEGER;
+    v_lb_accnt_id INTEGER;
+    v_diff NUMERIC;
+    v_result INTEGER;
+    _r RECORD;
+    v_date DATE;
+
+    
+BEGIN
+   
+    v_result := 0;
+    v_diff := 0;
+
+    SELECT 
+            costcat_purchprice_accnt_id,
+            costcat_liability_accnt_id
+    INTO 
+            v_purchprice_accnt_id,
+            v_lb_accnt_id
+    FROM 
+            costcat 
+    LIMIT 1;
+
+    FOR _r IN SELECT
+                        gltrans_id,
+                        gltrans_docnumber,
+                        gltrans_amount
+              FROM
+                        gltrans
+              WHERE
+                        gltrans_accnt_id = v_purchprice_accnt_id
+                    AND
+                        gltrans_doctype IN ('PO') 
+                    AND
+                        gltrans_date >= fetchMetricText('invfifo_start_date')::date 
+                    AND
+                        gltrans_notes = 'Return Inventory to P/O'
+                    AND
+                        NOT gltrans_deleted
+                    AND
+                        gltrans_docnumber LIKE i_pohead_number || '%' 
+
+              ORDER BY gltrans_docnumber LOOP
+
+
+        SELECT 
+                v_diff + COALESCE(gltrans_amount,0) + COALESCE(_r.gltrans_amount,0)
+        INTO
+                v_diff
+        FROM
+                gltrans
+        WHERE
+                gltrans_docnumber = _r.gltrans_docnumber
+            AND
+                gltrans_id < _r.gltrans_id
+            AND
+                gltrans_accnt_id = v_purchprice_accnt_id
+            AND
+                gltrans_doctype IN ('PO') 
+            AND
+                gltrans_date >= fetchMetricText('invfifo_start_date')::date
+            AND 
+                NOT gltrans_deleted
+            AND
+                gltrans_notes LIKE 'Receive Inventory from P/O%'
+
+        ORDER BY gltrans_id DESC LIMIT 1;
+
+
+    END LOOP;
+    
+    PERFORM deleteGlSeries( gltrans_sequence,  'Void Unit cost adjusted on ' || to_char(NOW(), 'Day Mon DD YYY') )
+
+    FROM
+            gltrans
+    WHERE
+            gltrans_docnumber = i_pohead_number
+        AND
+            gltrans_accnt_id = v_purchprice_accnt_id
+        AND
+            gltrans_doctype IN ('PO') 
+        AND
+            gltrans_date >= fetchMetricText('invfifo_start_date')::date
+        AND 
+            NOT gltrans_deleted
+        AND
+            gltrans_notes LIKE 'Unit cost adjusted for P/O%';
+
+    RAISE NOTICE 'Unit cost diff : %', v_diff;
+
+    SELECT 
+            MAX(gltrans_date)
+    INTO
+            v_date
+    FROM
+            gltrans
+    WHERE
+            gltrans_accnt_id = v_purchprice_accnt_id
+        AND
+            gltrans_doctype IN ('PO') 
+        AND
+            gltrans_date >= fetchMetricText('invfifo_start_date')::date 
+        AND
+            NOT gltrans_deleted
+        AND
+            gltrans_docnumber LIKE i_pohead_number || '%' ;
+
+
+    IF (ABS(v_diff) <> 0) THEN
+        SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
+                                       'S/R', 'PO', i_pohead_number,
+                                      'Unit cost adjusted for P/O ' || i_pohead_number || ' on ' || v_date,
+                                      v_lb_accnt_id,
+                                      v_purchprice_accnt_id, -1,
+                                      v_diff,
+                                      v_date::DATE, true ) INTO v_result;
+    END IF;
+
+
+    RETURN v_result;
+    
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_fixUnitCost(text)
+  OWNER TO admin;
diff --git a/pgsql/x-fifo-invfifo-hourly.sql b/pgsql/x-fifo-invfifo-hourly.sql
new file mode 100644 (file)
index 0000000..025b3f1
--- /dev/null
@@ -0,0 +1,193 @@
+
+-- hourly run
+-- do some updates...
+
+
+CREATE OR REPLACE FUNCTION invfifo_hourly()
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE    
+    v_first_open DATE;
+    v_ret NUMERIC;
+    v_last_flag INTEGER;
+ BEGIN   
+    
+   
+    -- what we will need to do
+    -- before running fifo code...
+    
+    -- voids!?
+    -- invadj void... should be fixed by posting adjustments..
+    
+    -- pohead void..
+    -- 5 seconds.. on average.. will probably increase a bit....
+    
+      
+    SELECT
+            period_start
+        INTO
+            v_first_open
+        FROM
+            period
+        WHERE
+            NOT period_closed
+        AND
+            NOT period_freeze
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+        
+    
+    RAISE NOTICE 'flagging purchase voids';
+    
+    PERFORM invfifo_pohead_void_flag_order(pohead_id) FROM
+        (SELECT pohead_id FROM  pohead where pohead_orderdate >= v_first_open) x; 
+
+    -- fix the cohead_id so that our coflagging is faster..
+    -- 8 seconds on a backlog...
+    
+    
+    SELECT COALESCE(fetchMetricValue('invfifo_cohead_fix_id'),0)::integer INTO v_last_flag;
+
+    RAISE NOTICE 'flagging cohead ids';
+    PERFORM
+            invfifo_cohead_fix_id(invdetail_id) from
+            (SELECT
+                invdetail_id
+            FROM
+                invdetailview
+            WHERE
+                     invhist_ordtype  ='SO'
+                     AND
+                     invfifo_cohead_id = 0
+                     AND
+                     invdetail_id > v_last_flag
+            ) x;
+         
+   
+    PERFORM setmetric('invfifo_cohead_fix_id', (select max(invdetail_id)::text FROM invdetail));
+    
+    RAISE NOTICE 'flagging cohead voids';
+    -- next flag cohead voids..
+    -- ~ 5.8 seconds.
+    PERFORM invfifo_cohead_void_flag_order(cohead_id) FROM
+            (SELECT cohead_id FROM  cohead where cohead_orderdate  >=  v_first_open) x;
+   
+    SELECT COALESCE(fetchMetricValue('invfifo_invadj_void_flag'),0)::integer INTO v_last_flag;
+
+    -- inventory adjustments..
+    
+    -- 16 seconds.
+    RAISE NOTICE 'flagging invjadjust voids';
+    PERFORM invfifo_invadj_void_flag(invdetail_id) FROM
+            (SELECT
+                    invdetail_id
+                FROM
+                    invdetailview
+                WHERE
+                    invhist_transtype = 'AD'
+                and
+                    invfifo_void = 0
+                AND
+                    invdetail_id > v_last_flag
+                AND
+                    invhist_transdate >=  v_first_open) x;
+   
+   
+    PERFORM setmetric('invfifo_invadj_void_flag', (select max(invdetail_id)::text FROM invdetail));
+
+
+
+    --- we have flagged all the voids now..
+    -- the assumtion is that fill has worked 
+
+    
+    -- we now need to run the fifo filling
+    -- first on any invhist that have never been run..
+    
+    -- any 10 that have never been calculated..
+    -- ~ 7 seconds..
+    
+    SELECT COALESCE(fetchMetricValue('invfifo_update_from_invdetail_all'),0)::integer INTO v_last_flag;
+
+      RAISE NOTICE 'running fifo calcs on new items';
+    
+    PERFORM invfifo_update_from_invdetail_all(itemsite_id) FROM 
+        (SELECT
+                distinct(invhist_itemsite_id) as itemsite_id
+            FROM
+                invdetailview
+            WHERE
+                invhist_itemsite_id >  v_last_flag
+            ORDER BY
+                invhist_itemsite_id ASC
+            LIMIT 10
+        ) x;
+    
+    PERFORM
+        setmetric('invfifo_update_from_invdetail_all', (
+            select max(itemsite_id)::text FROM
+                (SELECT
+                        distinct(invhist_itemsite_id) as itemsite_id
+                    FROM
+                        invdetailview
+                    WHERE
+                        invhist_itemsite_id >  v_last_flag
+                    ORDER BY
+                        invhist_itemsite_id ASC
+                    LIMIT 10
+                ) x
+        ));
+                
+    
+     
+    -- any that have changed recently.. (max 10)
+    -- 600 ms to do the scan for new records..
+    
+     RAISE NOTICE 'running fifo calcs on new transactions';
+     
+     PERFORM invfifo_update_from_invdetail_all(itemsite_id) FROM 
+        (SELECT
+                distinct(invhist_itemsite_id) as itemsite_id
+            FROM
+                invdetailview
+            WHERE
+                invdetail_id > COALESCE( (
+                    SELECT invfifopos_last_invdetail_id FROM invfifopos WHERE invfifopos_itemsite_id = invhist_itemsite_id
+                    ) ,0)
+            ORDER BY
+                itemsite_id ASC
+          
+        ) x;
+    
+    RAISE NOTICE 'running fifo calcs on squish amounts';
+    
+    -- try any infifo calcs that have failed.. -- this might need running seperatly..
+     PERFORM invfifo_update_from_invdetail_all(invfifopos_itemsite_id) FROM 
+        (SELECT
+                 invfifopos_itemsite_id 
+            FROM
+                invfifopos 
+            WHERE
+                invfifopos_lastadjustment > 0.0
+            ORDER BY
+                 random() ASC
+            LIMIT
+                10
+          
+        ) x;
+    
+    -- finally run the applications..
+    
+    
+    
+
+    RETURN v_ret;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_hourly()
+  OWNER TO admin;
diff --git a/pgsql/x-fifo-invfifo-invadj-void-flag.sql b/pgsql/x-fifo-invfifo-invadj-void-flag.sql
new file mode 100644 (file)
index 0000000..0d49114
--- /dev/null
@@ -0,0 +1,172 @@
+-- clear
+--UPDATE invfifo set invfifo_void = 0 WHERE invfifo_invdetail_id IN (SELECT invdetail_id FROM invdetailview where invfifo_void !=0 AND  invhist_transtype = 'AD');
+
+
+-- fill
+-- SELECT invfifo_invadj_void_flag(invdetail_id) FROM invdetailview where invhist_transtype = 'AD' and invfifo_void = 0;
+
+
+CREATE OR REPLACE FUNCTION invfifo_invadj_void_flag(integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+    i_invdetail_id  ALIAS FOR $1;
+    
+    r_invdetail RECORD;
+    
+    v_reverse_of INTEGER;
+    
+    v_first_open DATE;
+    
+BEGIN
+    
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_invjadj_void_flag-- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'AD') THEN
+        RAISE EXCEPTION 'invfifo_invjadj_void_flag called on non-purchased item';
+    END IF;
+    
+    -- is it already voided..
+    
+    IF r_invdetail.invfifo_void != 0 THEN
+        RETURN false;
+    END IF;
+    
+     
+    -- search for a previous matching adjustment that this would be the reverse of..
+    -- from now on, we can not do this for closed periods.
+    
+     SELECT
+            period_start
+        INTO
+            v_first_open
+        FROM
+            period
+        WHERE
+            NOT period_closed
+        AND
+            NOT period_freeze
+        ORDER BY
+            period_start ASC
+        LIMIT 1;
+        
+    
+    
+    SELECT
+            invdetail_id
+        INTO
+            v_reverse_of
+        FROM
+            invdetailview
+        WHERE
+            invdetail_location_id = r_invdetail.invdetail_location_id
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invhist_transtype = 'AD'
+            AND
+            invdetail_qty = -1 * r_invdetail.invdetail_qty
+            AND
+            invfifo_void = 0
+            AND
+            invdetail_id < i_invdetail_id
+            AND
+            invhist_transdate >= v_first_open
+        LIMIT 1;
+        
+    IF NOT FOUND THEN
+        return false;
+    END IF;
+    
+            
+         
+    PERFORM invfifo_update_from_void(i_invdetail_id, v_reverse_of, true);
+    PERFORM invfifo_update_from_void(v_reverse_of,i_invdetail_id, true);
+   
+    
+    RETURN true;
+     
+     
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_invadj_void_flag(integer  )
+  OWNER TO admin;
+          
+
+
+  -- code was used to sync data...
+        --
+        ---- this might not be needed...
+        --SELECT
+        --        count(invadj_id)
+        --    INTO
+        --        v_invadj_id
+        --    FROM
+        --        invadj
+        --    WHERE
+        --          invadj_posted
+        --        AND
+        --          invadj_transdate  = r_invdetail.invhist_transdate::date
+        --        AND
+        --          invadj_location_id = r_invdetail.invdetail_location_id
+        --        AND
+        --          invadj_itemsite_id  = r_invdetail.invhist_itemsite_id
+        --        AND
+        --            invadj_qty_by = r_invdetail.invdetail_qty;
+        --            
+        --    IF v_invadj_id != 0 THEN
+        --        RAISE EXCEPTION 'could not match adjustment for invdetail_id=%', i_invdetail_id;
+        --    END IF;
+        --    
+        --SELECT
+        --        invadj_id,
+        --        CASE
+        --            WHEN invadj_voided_by_id !=0 THEN 1
+        --            WHEN invadj_voids_id !=0 THEN 1
+        --        ELSE 0
+        --        END 
+        --        
+        --    INTO
+        --        v_invadj_id,
+        --        v_is_void
+        --    FROM
+        --        invadj
+        --    WHERE
+        --          invadj_posted
+        --        AND
+        --          invadj_transdate  = r_invdetail.invhist_transdate::date
+        --        AND
+        --          invadj_location_id = r_invdetail.invdetail_location_id
+        --        AND
+        --          invadj_itemsite_id  = r_invdetail.invhist_itemsite_id
+        --        AND
+        --            invadj_qty_by = r_invdetail.invdetail_qty;
+        --
+        --UPDATE
+        --    invadj
+        --        SET
+        --        invadj_invdetail_id = i_invdetail_id
+        --        WHERE
+        --        invadj_id =v_invadj_id;
+        --        
+        --        
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-pohead-void-flag.sql b/pgsql/x-fifo-invfifo-pohead-void-flag.sql
new file mode 100644 (file)
index 0000000..f6d30af
--- /dev/null
@@ -0,0 +1,310 @@
+-- aim is to flag the invfifo_void field with if
+-- deliveries have been returned, so that fifo calcs will ignore any values.
+
+
+
+-- ordtype = 'PO' => transtype = 'RP';
+
+
+
+
+-- called with cohead_id and itemsite_id
+
+--reset
+-- update invfifo SET invfifo_void = 0 where  invfifo_invdetail_id IN (SELECT invdetail_id FROM invdetailview WHERE invhist_ordtype='PO' AND invfifo_void !=0);
+
+-- fill
+-- SELECT invfifo_pohead_void_flag_order(pohead_id) FROM pohead;
+
+-- est
+-- SELECT invfifo_pohead_void_flag_order(1286) ;
+
+
+
+-- validation
+-- total without voided should match total all together
+
+-- SELECT SUM(invdetail_qty) FROM invdetailview where invhist_ordtype = 'PO';
+-- SELECT SUM(invdetail_qty) FROM invdetailview where invhist_ordtype = 'PO' and invfifo_void = 0;
+-- SELECT SUM(ABS(invdetail_qty)) FROM invdetailview where invhist_ordtype = 'PO' and invfifo_void != 0;
+--
+--SELECT invhist_ordnumber, aftervoid, beforevoid FROM
+--
+--    (SELECT invhist_ordnumber, SUM( CASE WHEN invfifo_void != 0 THEN 0 ELSE invdetail_qty END ) as aftervoid,
+--        SUM(invdetail_qty) as beforevoid FROM invdetailview WHERE invhist_ordtype = 'PO'    
+--        GROUP BY invhist_ordnumber
+--    ) x WHERE aftervoid != beforevoid ;
+
+
+--  
+
+CREATE OR REPLACE FUNCTION invfifo_pohead_void_flag_order(integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+    v_checksum NUMERIC;
+
+    i_pohead_id  ALIAS FOR $1;
+    
+    v_pohead_number text;
+BEGIN
+    
+    SELECT
+            pohead_number
+        INTO
+            v_pohead_number
+        FROM
+            pohead
+        WHERE
+            pohead_id = i_pohead_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Error finding pohead_id %', i_pohead_id;
+    END IF;
+    
+    PERFORM invfifo_pohead_void_flag_tx( invdetail_id, invhist_ordnumber, invhist_itemsite_id, invdetail_qty)
+        FROM
+            invdetailview
+        WHERE 
+            
+                invhist_ordtype = 'PO'
+            AND
+            (
+                invhist_ordnumber LIKE v_pohead_number || '-%'
+                OR
+                invhist_ordnumber = v_pohead_number
+            )
+             
+            ORDER BY
+                invdetail_id ASC;
+    SELECT 
+                COALESCE(SUM(invdetail_qty), 0.0)
+            INTO
+                v_checksum
+             FROM 
+                invdetailview
+             WHERE 
+                 
+                     invhist_ordtype = 'PO'
+                 AND
+                 (
+                     invhist_ordnumber LIKE v_pohead_number || '-%'
+                     OR
+                     invhist_ordnumber = v_pohead_number
+                 )
+                 AND
+                     invfifo_void != 0  ;
+    
+    if (v_checksum != 0.0) THEN
+         RAISE EXCEPTION 'order %  did not balance, %', v_pohead_number, v_checksum ;
+    END IF;
+
+    RETURN TRUE;
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_pohead_void_flag_order(integer  )
+  OWNER TO admin;
+          
+
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_pohead_void_flag(integer, integer)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+    i_pohead_id  ALIAS FOR $1;
+    i_itemsite_id  ALIAS FOR $2;
+    v_checksum NUMERIC;
+    v_pohead_number text;
+BEGIN
+    
+    SELECT
+            pohead_number
+        INTO
+            v_pohead_number
+        FROM
+            pohead
+        WHERE
+            pohead_id = i_pohead_id;
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Error finding pohead_id %', i_pohead_id;
+    END IF;
+    
+     
+    PERFORM invfifo_pohead_void_flag_tx( invdetail_id, invhist_ordnumber, i_itemsite_id, invdetail_qty)
+        FROM
+            (SELECT 
+                invdetail_id, invhist_ordnumber, invdetail_qty
+                FROM 
+                invdetailview
+                WHERE 
+                    
+                        invhist_ordtype = 'PO'
+                    AND
+                    (
+                        invhist_ordnumber LIKE v_pohead_number || '-%'
+                        OR
+                        invhist_ordnumber = v_pohead_number
+                    )
+                    AND
+                        invhist_itemsite_id = i_itemsite_id 
+                    ORDER BY
+                        invdetail_id ASC
+            ) x;
+    -- verify that the totals are the same.
+      SELECT 
+                COALESCE(SUM(invdetail_qty), 0.0)
+               INTO
+                v_checksum
+                FROM 
+                invdetailview
+                WHERE 
+                    
+                        invhist_ordtype = 'PO'
+                    AND
+                    (
+                        invhist_ordnumber LIKE v_pohead_number || '-%'
+                        OR
+                        invhist_ordnumber = v_pohead_number
+                    )
+                    AND
+                        invhist_itemsite_id = i_itemsite_id
+                    AND
+                        invfifo_void ! =0
+                   ;
+    
+    if (v_checksum != 0.0) THEN
+        RAISE EXCEPTION 'order %  did not balance, %', v_pohead_number, v_checksum ;
+    END IF;
+    RETURN TRUE;
+     
+ END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_pohead_void_flag(integer, integer )
+  OWNER TO admin;
+          
+
+--- invdetail_id , order number, 
+CREATE OR REPLACE FUNCTION invfifo_pohead_void_flag_tx(INTEGER, TEXT,INTEGER, NUMERIC)
+    RETURNS  boolean
+    
+AS $BODY$
+DECLARE        
+          
+
+    i_invdetail_id  ALIAS FOR $1;
+    i_order_number ALIAS FOR $2;
+    i_itemsite_id  ALIAS FOR $3;
+    i_qty ALIAS FOR $4;
+    v_qty_balance NUMERIC;
+    v_void_of INTEGER;
+    
+BEGIN
+    
+    
+    if (i_qty < 0) THEN
+        
+        --- got return - look for issues
+        
+        -- then it is always void!!!
+            --RAISE NOTICE 'flagging return as void %', i_invdetail_id;
+    
+    
+            -- try and determine what it's trying to void..
+            SELECT
+                invfifo_void
+            INTO
+                v_void_of
+            FROM
+                invdetailview
+            WHERE
+               invdetail_id = i_invdetail_id;
+            
+            IF v_void_of > 0 THEN
+                PERFORM invfifo_update_from_void(v_void_of, i_invdetail_id,true);
+            
+                PERFORM invfifo_update_from_void(i_invdetail_id, v_void_of,true);
+                return true;
+            END IF;
+            
+            
+            
+            SELECT
+                    invdetail_id
+                INTO
+                    v_void_of
+                FROM
+                    invdetailview
+                WHERE
+                
+                    invhist_ordtype = 'PO'
+                AND
+                
+                    invhist_ordnumber = i_order_number
+                AND
+                    invhist_itemsite_id = i_itemsite_id
+                AND
+                    invdetail_qty = -1 * i_qty
+                AND
+                    (invfifo_void = 0 OR invfifo_void = -1) 
+                ORDER BY
+                    invdetail_id ASC
+                LIMIT 1;
+            
+            
+            IF NOT FOUND THEN
+                RETURN false;
+            END IF;
+            PERFORM invfifo_update_from_void(v_void_of, i_invdetail_id,true);
+            
+            PERFORM invfifo_update_from_void(i_invdetail_id, v_void_of,true);
+            
+             
+            return true;
+        
+        
+        
+    END IF;
+     
+    
+    RETURN false;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_pohead_void_flag_tx(INTEGER, TEXT,INTEGER, NUMERIC)
+  OWNER TO admin;
+          
+-- see if it works.. 
+--update invfifo set invfifo_void =0 WHERE invfifo_void != 0;
+--
+--SELECT invfifo_cohead_void_flag(10260, 3404);
+--
+--
+--SELECT count(invdetail_id) FROM invdetailview where invfifo_void != 0;
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-unitcost-at-qty.sql b/pgsql/x-fifo-invfifo-unitcost-at-qty.sql
new file mode 100644 (file)
index 0000000..01c1d0a
--- /dev/null
@@ -0,0 +1,146 @@
+
+
+
+-- find the qty available.. 
+CREATE OR REPLACE FUNCTION invfifo_unitcost_at_qty(integer, integer, numeric(18, 6))
+    RETURNS  numeric(18, 6) 
+    
+AS $BODY$
+DECLARE
+    i_itemsite_id  ALIAS FOR $1;
+    i_location_id  ALIAS FOR $2;
+    i_qty           ALIAS FOR $3;
+    v_ret               numeric(18, 6);
+    
+      
+BEGIN
+       
+   -- price at a specific qty.
+    SELECT
+            invfifo_landedunitcost
+        
+        INTO
+            v_ret
+        FROM
+            invdetailview
+        WHERE
+            invfifo_qty_after <= i_qty
+            AND    
+            invdetail_location_id = i_location_id
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invdetail_qty > 0
+            AND
+            invhist_transtype = 'RP' -- purchases only!
+            AND
+            invfifo_void = 0
+        LIMIT
+            1;
+    
+    IF  FOUND THEN
+         return v_ret;
+         
+    END IF;    
+    
+    return 0;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_unitcost_at_qty(integer, integer, numeric(18, 6))
+  OWNER TO admin;
+          
+          -- find the qty available.. 
+CREATE OR REPLACE FUNCTION invfifo_unitcost_at_date(integer,  date)
+    RETURNS  numeric(18, 6) 
+    
+AS $BODY$
+DECLARE
+    i_itemsite_id  ALIAS FOR $1;
+   
+    i_date           ALIAS FOR $2;
+    v_ret               numeric(18, 6);
+    
+      
+BEGIN
+       
+   -- price at a specific qty.
+    SELECT
+        invfifo_landedunitcost
+        
+        INTO
+            v_ret
+        FROM
+            invdetailview
+        WHERE
+            invhist_transdate < i_date
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invhist_transtype = 'RP' -- purchases only!
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0
+        ORDER BY
+            invhist_transdate  DESC
+        LIMIT
+            1;
+    
+    IF  FOUND THEN
+         return v_ret;
+         
+    END IF;
+    
+    
+    
+    -- not found, then try next purchase price..
+    
+    SELECT
+        invfifo_landedunitcost
+        
+        INTO
+            v_ret
+        FROM
+            invdetailview
+        WHERE
+            invhist_transdate >= i_date
+            AND
+            invhist_itemsite_id = i_itemsite_id
+            AND
+            invhist_transtype = 'RP' -- purchases only!
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0
+        ORDER BY
+            invhist_transdate  ASC
+        LIMIT
+            1;
+    
+    IF  FOUND THEN
+         return v_ret;
+         
+    END IF;    
+    
+    -- if we really can not find any purchases, then we should use the stdcost?
+
+    SELECT stdcost(itemsite_item_id) INTO v_ret FROM itemsite where itemsite_id = i_itemsite_id;
+
+    return v_ret;
+
+
+    --return 0;
+    
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_unitcost_at_date(integer, date)
+  OWNER TO admin;
+          
+          
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-adjustment-in.sql b/pgsql/x-fifo-invfifo-update-from-adjustment-in.sql
new file mode 100644 (file)
index 0000000..ebb7473
--- /dev/null
@@ -0,0 +1,466 @@
+-- similar to credit memo ?
+--  DO NOT USE last purchase price - use stdcost price.
+-- as it's a fake value.. 
+--- updates the invfifo values for shipped and unitcost
+
+
+-- basicly complete..
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_adjustment_in(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100; 
+
+----------------------------
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_adjustment_in(integer, boolean)
+    RETURNS  NUMERIC 
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+    
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+   
+    v_unitcost  NUMERIC;
+    v_landedcost NUMERIC;
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_cost_before NUMERIC;
+    v_soldqty_before  NUMERIC;
+    v_est_unitcost NUMERIC;
+    r_invadj RECORD;
+
+BEGIN
+     
+    -- fetch our current transaction..
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    -- double check fifo qty's...
+    -- somewhere they might have got messed up..
+    
+    if r_invdetail.invfifo_qty_before <= r_invdetail.invfifo_qty_after THEN
+        PERFORM invfifo_fill(i_invdetail_id);
+        SELECT
+                *
+            INTO
+                r_invdetail
+            FROM
+                invdetailview  
+            WHERE
+                invdetail_id    = i_invdetail_id;
+    END IF;        
+    
+    
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_adjustment_in-- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'AD') THEN
+        RAISE EXCEPTION 'invfifo_update_from_adjustment_in called on non-purchased item';
+    END IF;
+    
+    
+    -- find the inventory adjustment relating to this..
+    
+    SELECT
+            *
+        INTO
+            r_invadj
+        FROM
+            invadj
+        WHERE
+            invadj_invdetail_id = i_invdetail_id;
+            
+    
+    
+    IF FOUND THEN
+        -- should not be called... - wrapper does not call this..
+        -- if we have a adjustment and it's flagged as voided..
+        -- record this as a void transaction..
+        
+        if (r_invdetail.invfifo_void = 0) THEN
+            UPDATE invadj SET invadj_voided_by_id =0 , invadj_voids_id =0 WHERE
+                invadj_invdetail_id = i_invdetail_id;
+        ELSE
+            RAISE EXCEPTION 'invfifo_update_from_adjustment_in called on voided invdetail_id %', i_invdetail_id;
+        END IF;
+    
+    END IF;
+    
+    --RAISE NOTICE 'invfifo_cost_before_in( %, %, %)', r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id;
+    
+    
+    
+    -- try and base it on  last purchase to this location.    
+    SELECT invfifo_unitcost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        v_est_unitcost;
+        
+        
+        
+     IF v_est_unitcost  = 0.0 THEN
+        -- otherwise look anywhere for a purchase price.. nearest to this date..
+     
+        SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+           v_est_unitcost;
+    END IF;
+    
+    v_unitcost = ROUND(v_est_unitcost,2);
+    v_landedcost = ROUND(v_est_unitcost,2);
+    
+    
+    
+    SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                        v_cost_before;
+    
+    --RAISE NOTICE 'before cost = %',  v_cost_before;
+   
+     
+    
+    
+    
+    
+    
+    
+    --IF FALSE THEN 
+    --    
+    --    -- to stop the price changing all the time, when the adjustment 'up'
+    --    -- is to cope with broken -ve stock values.
+    --    
+    --    SELECT
+    --            invfifo_qty_after
+    --        INTO
+    --            v_soldqty_before
+    --        FROM
+    --            invdetailview
+    --        WHERE
+    --            invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --            AND
+    --            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --            AND
+    --            (
+    --                invhist_transdate < r_invdetail.invhist_transdate
+    --                OR
+    --                (
+    --                    invhist_transdate = r_invdetail.invhist_transdate
+    --                    AND
+    --                    invdetail_id < r_invdetail.invdetail_id
+    --                )
+    --            )
+    --            
+    --            AND
+    --            invfifo_void = 0
+    --              AND
+    --            -- it's a purchase.
+    --            invdetail_qty < 0
+    --       
+    --        ORDER BY
+    --            invhist_transdate DESC,
+    --            invdetail_id DESC
+    --        LIMIT 1;
+    --                 
+    --    --RAISE NOTICE 'soldqty before = %  -- curqtybefore = %', v_soldqty_before, r_invdetail.invfifo_qty_before;
+    --    
+    --    IF v_soldqty_before >= r_invdetail.invfifo_qty_before THEN
+    --        -- we have sold more than we have recieved...
+    --        -- so the value will fluctuate if based on historical transactions.
+    --        -- so use the unti cost..
+    --        SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+    --                    v_cost_before;
+    --        
+    --        v_unitcost := r_invdetail.invhist_unitcost;
+    --        v_landedcost := r_invdetail.invhist_unitcost;
+    --        
+    --        
+    --    ELSE 
+    --        
+    --        
+    --        
+    --        IF r_invdetail.invfifo_qty_before > 0 THEN 
+    --                
+    --              -- this finds the last sale price from any transaction..
+    --              
+    --            SELECT
+    --                    invfifo_unitcost,
+    --                    invfifo_landedunitcost
+    --                INTO
+    --                    v_unitcost,
+    --                    v_landedcost
+    --                FROM
+    --                    invdetailview
+    --                WHERE
+    --                    -- invfifo_cust_id = v_cust_id (not lookinf for sale to this customer - any purchase before..)
+    --                    -- any locaiton
+    --                    --AND
+    --                    invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --                    AND
+    --                    invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --                    AND
+    --                    invfifo_qty_after < r_invdetail.invfifo_qty_after
+    --                    AND
+    --                    -- it's a purchase.
+    --                    invdetail_qty > 0
+    --                    AND
+    --                    invfifo_void = 0
+    --               
+    --                ORDER BY
+    --                    invhist_transdate DESC,
+    --                    invdetail_id DESC
+    --                    
+    --                LIMIT
+    --                    1;
+    --                    
+    --                    
+    --              -- RAISE NOTICE 'got landed cost from last tx before this in location';     
+    --              IF NOT FOUND THEN
+    --                      -- try any locaiton..
+    --                      
+    --                    SELECT
+    --                          invfifo_unitcost,
+    --                          invfifo_landedunitcost
+    --                      INTO
+    --                          v_unitcost,
+    --                          v_landedcost
+    --                      FROM
+    --                          invdetailview
+    --                      WHERE
+    --                          -- invfifo_cust_id = v_cust_id (not lookinf for sale to this customer - any purchase before..)
+    --                          -- any locaiton
+    --                          --AND
+    --                          --invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --                          --AND
+    --                          invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --                          --AND
+    --                          --invfifo_qty_after < r_invdetail.invfifo_qty_after -- this is meaningless.. 
+    --                          AND
+    --                          invhist_transdate < r_invdetail.invhist_transdate 
+    --                          
+    --                          AND
+    --                            invfifo_void = 0
+    --                            AND
+    --                          -- it's a purchase.
+    --                          invdetail_qty > 0
+    --                     
+    --                      ORDER BY
+    --                          invhist_transdate DESC,
+    --                          invdetail_id DESC
+    --                          
+    --                      LIMIT
+    --                          1;
+    --                --  RAISE NOTICE 'got landed cost from last tx before this';
+    --              END IF;
+    --                    
+    --                      
+    --              
+    --            -- if landed is not calculated - and we use that as the value.
+    --            -- then copy the unit cost..
+    --            IF v_landedcost < v_unitcost AND v_landedcost  > 0.0 THEN
+    --                v_unitcost = v_landedcost;
+    --            END IF;
+    --              
+    --                      
+    --            IF NOT FOUND THEN
+    --                 RAISE EXCEPTION 'invfifo_update_from_adjustment_in found where nothing was adjusted before.';
+    --            END IF;
+    --              
+    --              
+    --            SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+    --                    v_cost_before;
+    --              
+    --              
+    --        ELSE
+    --            -- if it's the first line, and it's an adjustment, we can only guess the unitcost.
+    --            
+    --            
+    --            SELECT
+    --                   invfifo_unitcost,
+    --                   invfifo_landedunitcost
+    --               INTO
+    --                   v_unitcost,
+    --                   v_landedcost
+    --               FROM
+    --                   invdetailview
+    --               WHERE
+    --                   -- invfifo_cust_id = v_cust_id (not lookinf for sale to this customer - any purchase before..)
+    --                   -- any locaiton
+    --                   --AND
+    --                   --invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --                   --AND
+    --                   invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --                   --AND
+    --                   --invfifo_qty_after < r_invdetail.invfifo_qty_after -- this is meaningless.. 
+    --                   AND
+    --                   invhist_transdate < r_invdetail.invhist_transdate 
+    --                   
+    --                   AND
+    --                    
+    --                   -- it's a purchase.
+    --                   invdetail_qty > 0
+    --                   AND
+    --                          -- it's a purchase.
+    --                   invfifo_void = 0
+    --              
+    --               ORDER BY
+    --                   invhist_transdate DESC,
+    --                   invdetail_id DESC
+    --                   
+    --               LIMIT
+    --                   1;
+    --            --RAISE NOTICE 'got landed cost from last tx before this';
+    --            
+    --            
+    --            IF NOT FOUND OR v_landedcost = 0.0 THEN 
+    --              
+    --                v_unitcost := r_invdetail.invhist_unitcost;
+    --                v_landedcost := r_invdetail.invhist_unitcost;
+    --            END IF;
+    --            
+    --            
+    --            
+    --            v_cost_before := 0.0;
+    --        END IF;
+    --        
+    --    END IF; -- if we have oversold..
+    --    
+    --END IF;  
+    
+    v_cost_before := COALESCE(v_cost_before,0.0);
+    
+    
+    -- fix the rounding issues.
+   
+    
+    
+     
+    -- THERE FOR
+    -- update invfifo
+    v_new_after := ( v_landedcost  * r_invdetail.invdetail_qty) + v_cost_before;
+    
+    
+    
+    
+    
+    -- has it changed...
+    IF (
+             r_invdetail.invfifo_unitcost = v_unitcost
+             AND
+             r_invdetail.invfifo_landedunitcost = v_landedcost
+             AND
+             r_invdetail.invfifo_cost_after = v_new_after
+             AND
+             r_invdetail.invfifo_cost_before= v_cost_before
+       ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landedcost,
+            invfifo_cost_after = v_new_after,
+            invfifo_cost_before= v_cost_before 
+            
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND( v_new_after - r_invdetail.invfifo_cost_after,2);
+    
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    -- we can not skip this step, as outgoing stock that depends on it
+    -- needs to have the right values.
+    
+    --IF NOT i_update_after THEN
+    --    RETURN v_diff;
+    --END IF;
+    -- update the values after this one..
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0;
+    
+    
+    -- FLAG The sales after this date as dirty..
+    --UPDATE invfifo
+    --    SET
+    --       invfifo_recalc_queued = true
+    --     
+    --    FROM
+    --        invdetail, invhist           
+    --     WHERE
+    --        invfifo_invdetail_id = invdetail_id
+    --        AND
+    --        invhist_id = invdetail_invhist_id
+    --        AND            
+    --        invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --        AND
+    --        invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --        AND
+    --        -- stock outbound is greater than we started with.
+    --        invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+    --        AND
+    --        invdetail_qty < 0
+    --        AND
+    --        invfifo_void = 0;
+    --        
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_adjustment_in(integer,boolean)
+  OWNER TO admin;
+  
+-- testing..
+--SELECT invfifo_update_from_adjustment_in(3792,true);
diff --git a/pgsql/x-fifo-invfifo-update-from-adjustment-out.sql b/pgsql/x-fifo-invfifo-update-from-adjustment-out.sql
new file mode 100644 (file)
index 0000000..a8694ec
--- /dev/null
@@ -0,0 +1,232 @@
+--- updates the invfifo values for shipped and unitcost
+
+-- purchase order return from shipping.. (note we just pop it of the stack as usual, even though it affects landed cost, as our landed cost
+-- is affected by this.
+
+-- triggers a update of poheads...
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_adjustment_out(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100; 
+
+----------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_adjustment_out(integer, boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+    r_invadj RECORD;
+   
+    v_unitcost  NUMERIC;
+    v_landedcost NUMERIC;
+    v_est_unitcost NUMERIC;
+    v_new_after NUMERIC;
+    v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_vend_id INTEGER;
+    v_pohead_number TEXT;
+  
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_adjustment_out -- need to add invfifo gen code';
+    END IF;
+    
+     IF (r_invdetail.invhist_transtype != 'AD') THEN
+        RAISE EXCEPTION 'invfifo_update_from_adjustment_out called on non-adjustment';
+    END IF;
+    
+    
+    
+    -- if it's void transaction or void of transaction
+    -- then the value is '0'
+    
+    
+      SELECT
+            *
+        INTO
+            r_invadj
+        FROM
+            invadj
+        WHERE
+            invadj_invdetail_id = i_invdetail_id;
+            
+    IF FOUND THEN
+        -- should not be called... - wrapper does not call this..
+        -- if we have a adjustment and it's flagged as voided..
+        -- record this as a void transaction..
+        
+        if (r_invdetail.invfifo_void = 0) THEN
+            UPDATE invadj SET invadj_voided_by_id =0 , invadj_voids_id =0 WHERE
+                invadj_invdetail_id = i_invdetail_id;
+        ELSE
+            RAISE EXCEPTION 'invfifo_update_from_adjustment_in called on voided invdetail_id %', i_invdetail_id;
+        END IF;
+    
+    END IF;
+    
+    
+    
+    
+    
+    
+     
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        v_invfifo_cost_before;
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+        v_invfifo_cost_after;
+    
+    
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    IF v_invfifo_cost_before < 0 THEN
+        
+        -- we have, and never will have enough stock to supply this..
+        
+        SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+        
+        -- this is just a wild gues...
+        v_invfifo_cost_after = v_invfifo_cost_before +
+                ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+
+
+    END IF;
+    IF v_invfifo_cost_after <= 0.0 THEN
+        -- we are selling more than we have..
+        -- we should find out what was the last purchase price and use that as the unitcost..
+        SELECT invfifo_unitcost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+            v_est_unitcost;
+        
+        -- if we can not find a unit cost from this location..
+        -- then try last purchase
+        IF v_est_unitcost  =0.0 THEN 
+            SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+               v_est_unitcost;
+        END IF;
+        
+         --  RAISE NOTICE 'est unit cost is %',v_est_unitcost ;    
+        v_invfifo_cost_after = r_invdetail.invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * v_est_unitcost;
+    END IF;
+     
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    v_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+    v_landedcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+            
+    IF (
+        r_invdetail.invfifo_unitcost = v_unitcost
+        AND
+        r_invdetail.invfifo_landedunitcost = v_landedcost
+        AND
+        r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+        AND
+        r_invdetail.invfifo_cost_before = v_invfifo_cost_before
+        --- we might need these???
+        --AND
+        --r_invdetail.invfifo_cust_id = v_cust_id
+        --AND
+        --r_invdetail.invfifo_cohead_id = v_cohead_id
+    ) THEN
+        RETURN 0;
+    END IF;
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landedcost,
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+
+            invfifo_recalc_queued = false
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    
+    
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+     
+     
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_adjustment_out(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-credit-memo-void.sql b/pgsql/x-fifo-invfifo-update-from-credit-memo-void.sql
new file mode 100644 (file)
index 0000000..3a37697
--- /dev/null
@@ -0,0 +1,196 @@
+
+--- updates the invfifo values for shipped and unitcost
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_credit_memo_void(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+------------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_credit_memo_void(i_invdetail_id integer, i_update_after boolean)
+    RETURNS  NUMERIC
+
+AS $BODY$
+DECLARE        
+            
+   
+    r_invdetail RECORD;
+    
+    v_unitcost  numeric;
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_landed_unitcost NUMERIC;
+    v_est_unitcost NUMERIC;
+    v_cost_before NUMERIC;
+    v_last_id INTEGER;
+    v_cust_id INTEGER;
+    v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+    v_landedcost NUMERIC;
+
+
+
+BEGIN
+
+
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_creditmemo-- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'RS' AND r_invdetail.invhist_ordtype != 'CM') THEN
+        RAISE EXCEPTION 'invfifo_update_from_creditmemo called on non-credit memo item';
+    END IF;
+     
+    
+    -- there is a situation where this decreases stock when it's voided.
+    
+    if (r_invdetail.invdetail_qty > 0) THEN
+        RAISE EXCEPTION 'invfifo_update_from_creditmemo_void  called on positive stock item';
+    
+    END IF;
+    
+    --
+      
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        v_invfifo_cost_before;
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+        v_invfifo_cost_after;
+    
+    
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    IF v_invfifo_cost_before < 0 THEN
+    
+          SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+        
+            v_invfifo_cost_after = v_invfifo_cost_before +
+                    ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+          
+    
+         
+    END IF;
+    IF v_invfifo_cost_after <= 0.0 THEN
+        -- we are selling more than we have..
+        -- we should find out what was the last purchase price and use that as the unitcost..
+        v_invfifo_cost_after = v_invfifo_cost_before +
+                    ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+    
+    END IF;
+     
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    v_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+    v_landedcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+            
+    IF (
+        r_invdetail.invfifo_unitcost = v_unitcost
+        AND
+        r_invdetail.invfifo_landedunitcost = v_landedcost
+        AND
+        r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+        AND
+        r_invdetail.invfifo_cost_before = v_invfifo_cost_before
+        --- we might need these???
+        --AND
+        --r_invdetail.invfifo_cust_id = v_cust_id
+        --AND
+        --r_invdetail.invfifo_cohead_id = v_cohead_id
+    ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landedcost,
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+            invfifo_recalc_queued = false
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+     
+       
+     
+      
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_credit_memo_void(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-credit-memo.sql b/pgsql/x-fifo-invfifo-update-from-credit-memo.sql
new file mode 100644 (file)
index 0000000..bfe23ad
--- /dev/null
@@ -0,0 +1,214 @@
+
+--- updates the invfifo values for shipped and unitcost
+-- here comes a fun problem
+
+
+--- if it bases the incomming cost from the calculated cost, then it can go totally out of wack.
+-- so it is better to find the unit cost from the last purcahse
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_credit_memo(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+------------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_credit_memo(integer, boolean)
+    RETURNS  NUMERIC
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    
+    v_unitcost  numeric;
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_landed_unitcost NUMERIC;
+    v_est_unitcost NUMERIC;
+    v_cost_before NUMERIC;
+    v_last_id INTEGER;
+    v_cust_id INTEGER;
+    
+
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_creditmemo-- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'RS' AND r_invdetail.invhist_ordtype != 'CM') THEN
+        RAISE EXCEPTION 'invfifo_update_from_creditmemo called on non-purchased item';
+    END IF;
+     
+    
+    -- there is a situation where this decreases stock when it's voided.
+    
+    if (r_invdetail.invdetail_qty < 0) THEN
+        SELECT invfifo_update_from_credit_memo_void(i_invdetail_id, i_update_after) INTO v_diff;
+        RETURN v_diff;
+    
+    END IF;
+     
+     
+        
+    SELECT invfifo_unitcost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        v_est_unitcost;
+        
+        
+        
+     IF v_est_unitcost  = 0.0 THEN 
+    -- at_date will return std cost if there are no purchases...
+        SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+           v_est_unitcost;
+    END IF;
+    
+    
+
+
+      v_unitcost = v_est_unitcost;
+      v_landed_unitcost = v_est_unitcost;
+    
+    
+    
+       -- RAISE NOTICE 'Credit memo found where nothing was delivered to customer before.';
+    --END IF;    
+    
+    
+    
+    SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_cost_before;
+      
+    
+    -- THERE FOR
+    -- update invfifo
+    v_new_after := (v_landed_unitcost * r_invdetail.invdetail_qty) + v_cost_before;
+    
+    
+    
+    
+    -- has it changed...
+    IF (
+             r_invdetail.invfifo_unitcost = v_unitcost
+             AND
+             r_invdetail.invfifo_landedunitcost = v_landed_unitcost
+             AND
+             r_invdetail.invfifo_cost_after = v_new_after
+             AND
+             r_invdetail.invfifo_cost_before= v_cost_before
+             AND
+            r_invdetail.invfifo_cust_id = v_cust_id
+       ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landed_unitcost,
+            invfifo_cost_after = v_new_after,
+            invfifo_cost_before = v_cost_before,
+            invfifo_cust_id = v_cust_id
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_new_after - r_invdetail.invfifo_cost_after,2);
+    
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    -- update the values after this one..
+    
+      -- we can not skip this step, as outgoing stock that depends on it
+    -- needs to have the right values.
+    --IF NOT i_update_after THEN
+    --    RETURN v_diff;
+    --END IF;
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0;
+    
+    
+    -- FLAG The sales after this date as dirty..
+    --UPDATE invfifo
+    --    SET
+    --       invfifo_recalc_queued = true
+    --     
+    --    FROM
+    --        invdetail, invhist           
+    --     WHERE
+    --        invfifo_invdetail_id = invdetail_id
+    --        AND
+    --        invhist_id = invdetail_invhist_id
+    --        AND            
+    --        invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --        AND
+    --        invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --        AND
+    --        -- stock outbound is greater than we started with.
+    --        invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+    --        AND
+    --        invdetail_qty < 0
+    --        AND
+    --        invfifo_void = 0;
+    --        
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_credit_memo(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-invdetail-ahead.sql b/pgsql/x-fifo-invfifo-update-from-invdetail-ahead.sql
new file mode 100644 (file)
index 0000000..769a988
--- /dev/null
@@ -0,0 +1,143 @@
+
+
+-- this is triggered on a transfer where it needs to look ahead to match qty          
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail_ahead(integer)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE    
+    i_invdetail_id  ALIAS FOR $1;
+    
+    v_invhist_id INTEGER;
+    v_location_id INTEGER;
+    v_itemsite_id INTEGER;
+    v_next_up INTEGER;
+    v_end_qty NUMERIC;
+    v_date DATE;
+    
+    v_ret NUMERIC;
+    v_row NUMERIC;
+    
+    r_invdetail RECORD;
+    
+    invdetail_curs CURSOR (c_itemsite_id integer, c_first_transdate date,  c_invdetail_id integer, c_not_invhist_id integer) FOR
+            SELECT
+                invdetail_id,
+                invfifo_qty_before,
+                invdetail_location_id
+                
+            FROM
+                invdetailview
+            WHERE
+                invhist_itemsite_id = c_itemsite_id
+                AND
+                invfifo_void = 0
+                AND
+                (
+                    invhist_transdate > c_first_transdate
+                    OR
+                    (
+                        invhist_transdate  = c_first_transdate
+                        AND
+                        invdetail_id  > c_invdetail_id
+                    )
+                )
+                AND
+                invhist_id != c_not_invhist_id
+            ORDER BY
+                invhist_transdate ASC,
+                invdetail_id ASC;
+            
+         
+    
+    
+    
+ BEGIN   
+    
+    --RAISE NOTICE 'invfifo_update_from_invdetail_ahead: %', i_invdetail_id;
+    
+    SELECT
+        invdetail_location_id,
+        invhist_itemsite_id,
+        invfifo_qty_after,
+        invhist_id,
+        invhist_transdate
+    INTO
+        v_location_id,
+        v_itemsite_id,
+        v_end_qty,
+        v_invhist_id
+        v_date
+    FROM
+        invdetailview
+    WHERE
+        invdetail_id = i_invdetail_id;
+    
+    
+    
+    -- is it worth looking ahead?
+    
+    SELECT
+            invdetail_id
+        INTO
+            v_next_up
+        FROM
+            invdetailview
+        WHERE
+        
+            invdetail_location_id = v_location_id
+        AND
+            invhist_itemsite_id = v_itemsite_id
+        AND
+            invfifo_qty_after >= v_end_qty
+        AND
+            invdetail_qty > 0
+        AND
+            invfifo_void = 0
+            
+        LIMIT 1;
+    -- basically it's negative stock!
+    IF NOT FOUND THEN
+        RETURN 0;
+    END IF;
+        
+    
+        
+    v_ret = 0;
+    OPEN invdetail_curs(v_itemsite_id, v_date,i_invdetail_id,  v_invhist_id );
+    
+    FETCH invdetail_curs into r_invdetail;
+    WHILE FOUND LOOP
+    
+        -- stop if we have enough stock to fullfill it...
+        IF ( 
+            r_invdetail.invdetail_location_id = v_location_id
+            AND
+            r_invdetail.invfifo_qty_before >=  v_end_qty
+            
+        ) THEN
+            
+            EXIT;
+        END IF;
+        
+        SELECT ABS(invfifo_update_from_invdetail(r_invdetail.invdetail_id, false)) into v_row;
+        
+        v_ret = v_ret + v_row;
+            
+    
+    END LOOP;
+    CLOSE invdetail_curs;
+    
+    RETURN v_ret;
+    
+     
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_update_from_invdetail_ahead(integer)
+  OWNER TO admin;
+          
diff --git a/pgsql/x-fifo-invfifo-update-from-invdetail-all.sql b/pgsql/x-fifo-invfifo-update-from-invdetail-all.sql
new file mode 100644 (file)
index 0000000..986a2e4
--- /dev/null
@@ -0,0 +1,123 @@
+
+-- run a whole itemsite
+-- at present looks like the best way to update
+
+
+
+
+-- alternative approaches.
+-- loop each incomming
+--> PO 's value as is.
+--> transfers ... push active location to the one 
+-->  loop through find all sales of it.. (or transfer outs..)
+--> 
+
+--> STACK?
+ --> 
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail_all_force(integer)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE    
+    i_itemsite_id  ALIAS FOR $1;
+    v_ret NUMERIC;
+BEGIN   
+    DELETE FROM invfifopos WHERE invfifopos_itemsite_id = i_itemsite_id ;
+    
+    SELECT invfifo_update_from_invdetail_all(i_itemsite_id) INTO v_ret;
+    
+   RETURN v_ret;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_update_from_invdetail_all_force(integer)
+  OWNER TO admin;
+
+
+DROP FUNCTION IF EXISTS invfifo_update_from_invdetail_all(integer);
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail_all(integer)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE    
+    i_itemsite_id  ALIAS FOR $1;
+    v_last_invdetail_id INTEGER;
+    v_last_checked_id INTEGER;
+    v_ret NUMERIC;
+ BEGIN   
+    -- do we need to do this...
+    
+    -- it basically check to see if the last run resulted in '0.0' adjustment.
+    -- if so, no need to run again..
+    
+    SELECT
+            COALESCE(max(invdetail_id),0)
+        INTO
+            v_last_invdetail_id
+        FROM
+            invdetailview
+        where
+            invhist_itemsite_id = i_itemsite_id;
+            
+            
+    SELECT
+            COALESCE(invfifopos_last_invdetail_id,0 )
+        INTO
+            v_last_checked_id
+        FROM
+            invfifopos
+        where
+            invfifopos_itemsite_id= i_itemsite_id
+            AND
+            invfifopos_lastadjustment = 0.0;
+    
+    IF v_last_checked_id = v_last_invdetail_id OR v_last_invdetail_id = 0 THEN
+        RAISE NOTICE 'skipping  - max tx matches last run';
+    
+        RETURN 0;
+    END IF;
+    -- the transfer out must appear before the transfer in..
+    -- the other way to handle this is to NOOP the transfer out
+    -- and 
+    SELECT SUM(ABS(invfifo_update_from_invdetail(invdetail_id, false)))
+        INTO v_ret
+    FROM (
+        SELECT
+                invdetail_id
+            FROM
+                invdetailview
+            WHERE
+                invhist_itemsite_id = i_itemsite_id
+               -- AND
+               -- invfifo_void = 0
+            ORDER BY
+                -- real recieved stock first..
+            
+               -- CASE WHEN invdetail_qty >0  and (invhist_transtype = 'RP' OR invhist_transtype = 'AD' OR invhist_transtype = 'RS' ) THEN 1
+               -- ELSE -1 END DESC,
+                invhist_transdate ASC,
+                invdetail_id ASC
+            
+        ) x;
+    
+    
+    --- finall balancing occurs by running RL a few times??? with update on??
+     PERFORM  invfifopos_update(
+            i_itemsite_id,
+            COALESCE( (SELECT max(invdetail_id) FROM invdetailview where invhist_itemsite_id =  i_itemsite_id), 0),
+            v_ret
+    );
+  
+    RETURN v_ret;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   invfifo_update_from_invdetail_all(integer)
+  OWNER TO admin;
diff --git a/pgsql/x-fifo-invfifo-update-from-invdetail.sql b/pgsql/x-fifo-invfifo-update-from-invdetail.sql
new file mode 100644 (file)
index 0000000..dbdad53
--- /dev/null
@@ -0,0 +1,284 @@
+-- relay method, that calls various updates based on the type of line.
+
+
+--- updates the invfifo values for shipped and unitcost
+
+
+-- test: SELECT invfifo_update_from_invdetail(11598); SELECT * from invdetailview where invdetail_id = 11598;
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_invdetail(integer)
+  OWNER TO admin;
+-----------
+   
+CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail(integer,  boolean)
+    RETURNS  NUMERIC
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+    v_qty_before NUMERIC;
+    v_ret NUMERIC;
+    r_invdetail RECORD;
+    
+    v_ts_start timestamp with time zone;
+
+BEGIN
+    
+    
+    v_ts_start = clock_timestamp();
+    
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    -- no value to calc..
+    if (r_invdetail.invfifo_void != 0) THEN
+        SELECT
+            invfifo_update_from_void(i_invdetail_id, r_invdetail.invfifo_void, i_update_after)
+            INTO v_ret; 
+        RETURN v_ret;
+    END IF;
+    
+    -- should we fix broken voids here?
+    -- if before/after same and not void... -then fill needs calling..
+    
+    -- validate the quantity - as if this is wrong it causes all sorts of problems.
+     
+    
+    SELECT
+            COALESCE(invfifo_qty_after, 0)
+        INTO
+            v_qty_before
+        FROM
+            invdetailview
+        WHERE
+            invdetail_location_id = r_invdetail.invdetail_location_id
+            AND
+            (
+                (
+                    invhist_transdate < r_invdetail.invhist_transdate
+                )
+                OR
+                (   invhist_transdate = r_invdetail.invhist_transdate
+                    AND
+                    invdetail_id < i_invdetail_id
+                )
+            )
+            
+            AND
+                invhist_itemsite_id = r_invdetail.invhist_itemsite_id
+            AND
+                -- if r_invhist.invdetail_qty
+                (
+                    (r_invdetail.invdetail_qty > 0 AND  invdetail_qty > 0)
+                    OR
+                    (r_invdetail.invdetail_qty < 0 AND  invdetail_qty < 0)
+                )
+            ORDER BY
+                invhist_transdate DESC,
+                invdetail_id DESC
+            LIMIT 1;
+             
+    IF v_qty_before != r_invdetail.invfifo_qty_before THEN
+        PERFORM invfifo_fill(i_invdetail_id, true);
+    END IF;
+     
+    --RAISE NOTICE '% invfifo_update_from_invdetail (% : %/%) %s',
+    --        clock_timestamp(), i_invdetail_id ,
+    --        r_invdetail.invhist_transtype, r_invdetail.invhist_ordtype, r_invdetail.invdetail_qty;
+    --
+    IF (r_invdetail.invdetail_qty > 0) THEN      
+           -- calculate the cost before.. (incremental cost)
+            
+           IF (r_invdetail.invhist_transtype = 'RP') THEN
+               SELECT  invfifo_update_from_pohead(i_invdetail_id, i_update_after)
+                    INTO v_ret;
+              -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+               --     clock_timestamp() - v_ts_start, i_invdetail_id ;
+               RETURN v_ret;
+               
+           END IF;
+           
+          
+           -- if it's a transfer
+               -- then unit price is dependant on FIFO sale that the tx relates to.
+               
+           IF (r_invdetail.invhist_transtype = 'RL') THEN
+               SELECT invfifo_update_from_transfer_in(i_invdetail_id, i_update_after)
+                    INTO v_ret;
+              -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+              --      clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+               RETURN v_ret;
+           END IF;
+       
+               
+           -- what if it's a debit memo???
+           
+           -- if's it's a credit memo.
+           IF (r_invdetail.invhist_transtype = 'RS' AND r_invdetail.invhist_ordtype = 'CM' ) THEN
+                SELECT invfifo_update_from_credit_memo(i_invdetail_id, i_update_after)
+                    INTO v_ret;
+                --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+               --     clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+                RETURN v_ret;
+           END IF;
+           
+           IF (r_invdetail.invhist_transtype = 'RS' AND r_invdetail.invhist_ordtype = 'SO' ) THEN
+            -- This is a voided transaction..
+                SELECT invfifo_update_from_void(i_invdetail_id, r_invdetail.invfifo_void, i_update_after)
+                    INTO v_ret;
+               -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+               --     clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+                RETURN v_ret;
+           END IF;
+           
+           
+           IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype = 'IN' ) THEN
+                -- CAN BE RETurn from shipping.
+               SELECT  invfifo_update_from_return_invoice(i_invdetail_id, i_update_after)
+                    INTO v_ret;
+               -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+                --    clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+               RETURN v_ret;
+           END IF;
+           
+           
+           
+           
+        -- if it's an adjustment...
+               -- then the invhist is really the only tx record of this..
+           
+           IF (r_invdetail.invhist_transtype = 'AD') THEN
+               SELECT  invfifo_update_from_adjustment_in(i_invdetail_id, i_update_after)
+                    INTO v_ret;
+                --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+                --    clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+               RETURN v_ret;
+           END IF;
+           
+   
+           RAISE EXCEPTION 'Unknown transtype (IN) %, % %', r_invdetail.invhist_transtype,  r_invdetail.invhist_ordtype , i_invdetail_id;
+           RETURN false;
+       END IF;
+        
+       -- outgoing. 
+        
+        -- are these all based on FIFO values???
+        -- but some 
+        
+        
+        -- if's it's a shipment - record customer id...
+        IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype='SO') THEN
+            SELECT invfifo_update_from_shipment(i_invdetail_id, i_update_after)
+                 INTO v_ret;
+            --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+             --       clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+            RETURN v_ret;
+        END IF;
+       
+        IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype='IN') THEN
+           SELECT invfifo_update_from_invoice(i_invdetail_id, i_update_after)
+                INTO v_ret;
+            --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+            --        clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+            RETURN v_ret;
+        END IF;
+       
+        IF (r_invdetail.invhist_transtype = 'RL') THEN
+            -- this is handled by the transfer in
+            
+            SELECT
+                    invfifo_update_from_transfer_in(invdetail_id,i_update_after)
+                INTO
+                    v_ret
+                FROM
+                    invdetailview
+                WHERE
+                    invhist_id = r_invdetail.invhist_id
+                AND
+                    invdetail_id != i_invdetail_id;
+        
+          -- PERFORM invfifo_update_from_transfer_out(i_invdetail_id);
+           RETURN 0;
+        END IF;
+        -- return PO inventory..  -- SAME as a void transaction
+        IF (r_invdetail.invhist_transtype = 'RP') THEN
+           
+           
+            --RAISE EXCEPTION 'need to add rp back';
+           
+            SELECT invfifo_update_from_return_inventory(i_invdetail_id,  i_update_after)
+                INTO v_ret;
+             --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+             --       clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+            RETURN v_ret;
+        END IF;
+        
+        IF (r_invdetail.invhist_transtype = 'AD') THEN
+            SELECT invfifo_update_from_adjustment_out(i_invdetail_id, i_update_after)
+                 INTO v_ret;
+            --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
+             --       clock_timestamp() - v_ts_start, i_invdetail_id ;
+               
+            RETURN v_ret;
+        END IF;
+        -- return from shipping? alwasy
+        IF (r_invdetail.invhist_transtype = 'RS') THEN
+            -- can be
+             
+            -- ignore returned shipment with invalid values?!?!
+            -- these should be voided and not happend.
+            RETURN 0;
+            
+            
+        END IF;
+     
+        RAISE EXCEPTION 'Unknonw transtype (OUT) % , invdetail_id = %',r_invdetail.invhist_transtype, i_invdetail_id ;
+        RETURN 0;
+        
+      
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_invdetail(integer,boolean)
+  OWNER TO admin;
+    
+    
+
+--SELECT invfifo_update_from_invdetail(invdetail_id,true) FROM invdetail order by invdetail_id DESC limit 10;
+
+    
+    
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-invoice.sql b/pgsql/x-fifo-invfifo-update-from-invoice.sql
new file mode 100644 (file)
index 0000000..08c06cd
--- /dev/null
@@ -0,0 +1,207 @@
+--- updates the invfifo values for shipped and unitcost
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invoice(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_invoice(integer, boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+    
+    v_est_unitcost NUMERIC;
+    v_unitcost  NUMERIC;
+     v_new_after NUMERIC;
+    v_diff      NUMERIC;
+    v_last_id INTEGER;
+    v_cust_id INTEGER;
+    v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_shipment -- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'SH' OR r_invdetail.invhist_ordtype !='IN') THEN
+           
+        RAISE EXCEPTION 'invfifo_update_from_shipment called on non-invoice';
+    END IF;
+    
+    
+    --invhist_ordnumber        | 77862
+
+    -- gather the customer...
+         
+     
+    
+    SELECT
+            invchead_cust_id --, coitem_id
+        INTO
+            v_cust_id -- , v_coitem_id
+        FROM
+            invchead
+        
+        WHERE
+            invchead_invcnumber = r_invdetail.invhist_ordnumber  
+        LIMIT
+            1;
+
+    
+     
+    
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+    
+    --SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+    --    v_invfifo_cost_before;
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+        v_invfifo_cost_after;
+        
+    --IF v_invfifo_cost_before < 0 THEN
+    --    v_invfifo_cost_before = r_invdetail.invfifo_cost_before;
+    --END IF;
+    IF v_invfifo_cost_after < 0  THEN
+    
+            SELECT
+                invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before)  INTO
+                    v_est_unitcost;
+            IF v_est_unitcost > 0 THEN 
+                SELECT
+                    invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before + 1)  INTO
+                        v_est_unitcost;
+            END IF;      
+           
+            IF v_est_unitcost > 0.0 THEN
+                RAISE NOTICE 'one pc est cost %', abs(v_est_unitcost - v_invfifo_cost_before);
+                v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * abs(v_est_unitcost - v_invfifo_cost_before));
+            ELSE
+                
+                -- unit cost is a pretty nasty indicator of price..
+                -- a better indicator would be last purchase price...
+                SELECT
+                    invfifo_cost_estimate(r_invdetail.invhist_itemsite_id)
+                    INTO
+                    v_est_unitcost;
+                    
+                IF v_est_unitcost > 0.0 THEN 
+                    v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * v_est_unitcost);
+                ELSE
+                    -- finally give up and use the dodgy unit cost..
+                    v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost);
+                END IF;
+            END IF;
+    
+    
+        
+    END IF;    
+     IF (
+             r_invdetail.invfifo_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty)
+             AND
+             r_invdetail.invfifo_landedunitcost =  ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty)
+             AND
+             r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+             AND
+             r_invdetail.invfifo_cost_before= v_invfifo_cost_before
+             AND
+            r_invdetail.invfifo_cust_id = v_cust_id
+       ) THEN
+        RETURN 0;
+    END IF;
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),
+            invfifo_landedunitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+            invfifo_recalc_queued = false,
+            invfifo_cust_id = v_cust_id
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+     
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_invoice(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-pohead.sql b/pgsql/x-fifo-invfifo-update-from-pohead.sql
new file mode 100644 (file)
index 0000000..2defedf
--- /dev/null
@@ -0,0 +1,306 @@
+--- updates the invfifo values for shipped and unitcost
+
+-- for received goods.
+
+-- there is a annoying thing about this..
+-- if there was a return, then we can not credit all the values.
+
+-- eg.
+-- recv 162 ... return 162... recieve 172
+
+
+-- landed cost = (total cost of landed for this order / qty recieved.)
+
+-- so it things we have 300+ recieved.
+-- COST / 300
+
+-- our example is PO number: 20013  line 3?
+-- pohead_id                      | 1216
+
+--total_landed_cost = qty_received / (qty_recieved - qty_returned)
+--   ( landed cost / total recieved ) * total_really_recieved (eg. could be more than that value)
+   
+--In theory this landed cost will get removed by the reversals.... 
+   
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_pohead(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+   
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_pohead(integer,boolean)
+    RETURNS  NUMERIC
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+
+    r_invdetail RECORD;
+    
+    v_unitcost  NUMERIC;
+    v_new_after NUMERIC;
+    v_cost_before NUMERIC;
+    v_diff NUMERIC;
+    v_landed_unitcost NUMERIC;
+    v_total_landed_cost NUMERIC;
+    v_total_landed_qty  NUMERIC;
+    
+    v_last_id INTEGER;
+    v_vend_id INTEGER;
+    v_pohead_id INTEGER;
+    v_pohead_number TEXT;
+    v_poitem_linenumber INTEGER; 
+    v_ar  TEXT ARRAY;
+    
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_pohead -- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'RP') THEN
+        RAISE EXCEPTION 'invfifo_update_from_pohead called on non-purchased item';
+    END IF;
+    
+    
+     
+     
+     
+    
+    -- fetch the actual purchase price
+    -- this will probably be slow..
+      -- this takes around 200ms
+      
+    SELECT regexp_split_to_array(r_invdetail.invhist_ordnumber,'-') INTO v_ar;
+    
+    SELECT   array_to_string(v_ar[1: array_length(v_ar,1) -1 ], '-')  INTO v_pohead_number;
+     SELECT    v_ar[  array_length(v_ar,1)  ]::integer INTO v_poitem_linenumber;
+   
+      
+    --SELECT split_part(r_invdetail.invhist_ordnumber, '-', 1) INTO v_pohead_number;
+    --SELECT split_part(r_invdetail.invhist_ordnumber, '-', 2)::integer INTO v_poitem_linenumber;
+   -- pohead_orderdate
+         
+    
+    SELECT
+            currtobase(pohead_curr_id, poitem_unitprice, pohead_orderdate::date),
+            pohead_vend_id,
+            pohead_id 
+        INTO
+            v_unitcost ,
+            v_vend_id,
+            v_pohead_id
+            
+        FROM
+            poitem,pohead
+        where
+            poitem_pohead_id = pohead_id
+            AND
+            pohead_number  = v_pohead_number 
+            AND
+            poitem_linenumber = v_poitem_linenumber
+            --(pohead_number || '-' || poitem_linenumber)  = r_invdetail.invhist_ordnumber
+        LIMIT 1;
+    
+    -- find the total quantity of that order so that landed cost can be 
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'could not find purchase order. for %' , r_invdetail.invhist_ordnumber;
+    END IF;
+     
+     
+    -- this should not be calced like this...
+    -- we should base it on real recieved..?
+    
+    -- total landed cost for order
+    
+    SELECT
+        ROUND( SUM( gltrans_amount ) ,2)
+             
+    INTO
+        v_total_landed_cost
+    FROM
+            recvgrpland
+        LEFT JOIN
+            recvgrp
+        ON
+            recvgrp_id = recvgrpland_recvgrp_id
+        LEFT JOIN
+            gltrans
+        ON
+            gltrans_sequence = recvgrpland_glseries
+            AND
+            gltrans_amount > 0
+        
+    WHERE
+        recvgrp_pohead_id = v_pohead_id
+        AND
+        (recvgrp_void IS NULL OR recvgrp_void =0);
+    
+        RAISE NOTICE 'landed cost is %', v_total_landed_cost;
+    -- see if we have a landed cost..
+    -- we only support by quantity...
+    -- it could look at recvgrp for the type...
+    
+    SELECT
+            ROUND(SUM(recv_qty), 2)
+        INTO
+            v_total_landed_qty
+        FROM
+            recv
+        LEFT JOIN
+            recvgrp
+        ON
+            recv_recvgrp_id = recvgrp_id
+        WHERE
+            recvgrp_pohead_id = v_pohead_id
+            AND
+            (recvgrp_void IS NULL OR recvgrp_void =0);
+    
+    v_landed_unitcost := 0;
+    
+    IF (v_total_landed_qty > 0) THEN 
+        SELECT COALESCE(v_total_landed_cost / v_total_landed_qty,0) INTO v_landed_unitcost;
+    END IF;
+    
+--     RAISE NOTICE 'v_total_landed_qty is %', v_total_landed_qty;
+--     RAISE NOTICE 'v_landed_unitcost is %', v_landed_unitcost;
+--     RAISE NOTICE 'i_invdetail_id is %', i_invdetail_id;
+--     RAISE NOTICE 'v_unitcost + v_landed_unitcost is %', v_unitcost + v_landed_unitcost;
+-- RETURN 1;
+    -- look up before value.
+    SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_cost_before;
+       
+       
+    
+    -- THERE FOR
+    -- update invfifo
+    v_new_after := ((v_unitcost + v_landed_unitcost) * r_invdetail.invdetail_qty) + v_cost_before;
+    
+    
+    
+      IF (
+            r_invdetail.invfifo_unitcost = v_unitcost * 1.1
+            AND
+            r_invdetail.invfifo_landedunitcost =  v_unitcost + v_landed_unitcost
+            AND
+            r_invdetail.invfifo_cost_after = v_new_after
+            AND
+            r_invdetail.invfifo_cost_before= v_cost_before
+            AND
+            r_invdetail.invfifo_vend_id = v_vend_id
+
+       ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost * 1.1,
+            invfifo_landedunitcost = v_unitcost + v_landed_unitcost,
+            invfifo_cost_after = v_new_after,
+            invfifo_vend_id = v_vend_id,
+            invfifo_cost_before =v_cost_before
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_new_after - r_invdetail.invfifo_cost_after,2);
+    
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+      -- we can not skip this step, as outgoing stock that depends on it
+    -- needs to have the right values.
+    --IF NOT i_update_after THEN
+    --    RETURN v_diff;
+    --END IF;
+    
+    
+    --RAISE NOTICE 'diff if %' , v_diff;
+    -- update the values after this one..
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0;
+    
+    
+    -- FLAG The sales after this date as dirty..
+    UPDATE invfifo
+        SET
+           invfifo_recalc_queued = true
+         
+        FROM
+            invdetail, invhist           
+         WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            -- stock outbound is greater than we started with.
+            invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+            
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_pohead(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-return-inventory.sql b/pgsql/x-fifo-invfifo-update-from-return-inventory.sql
new file mode 100644 (file)
index 0000000..25d9f2d
--- /dev/null
@@ -0,0 +1,186 @@
+--- updates the invfifo values for shipped and unitcost
+
+-- purchase order return from shipping.. (note we just pop it of the stack as usual,
+--even though it affects landed cost, as our landed cost
+-- is affected by this.
+
+--  note, we actually need this where single items are returned from shipments..
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_return_inventory(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100; 
+
+----------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_return_inventory(integer, boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+    r_invadj RECORD;
+   
+    v_unitcost  NUMERIC;
+    v_landedcost NUMERIC;
+    v_est_unitcost NUMERIC;
+    v_new_after NUMERIC;
+    v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_vend_id INTEGER;
+    v_pohead_number TEXT;
+  
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_return_inventory -- need to add invfifo gen code';
+    END IF;
+    
+     IF (r_invdetail.invhist_transtype != 'RP') THEN
+        RAISE EXCEPTION 'invfifo_update_from_return_inventory called on non-inventory return';
+    END IF;
+    
+    
+    
+      
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        v_invfifo_cost_before;
+    
+    SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+        v_invfifo_cost_after;
+    
+    
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    IF v_invfifo_cost_before < 0 THEN
+    
+          SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+        
+            v_invfifo_cost_after = v_invfifo_cost_before +
+                    ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+          
+    
+         
+    END IF;
+    IF v_invfifo_cost_after <= 0.0 THEN
+        -- we are selling more than we have..
+        -- we should find out what was the last purchase price and use that as the unitcost..
+        v_invfifo_cost_after = v_invfifo_cost_before +
+                    ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+    
+    END IF;
+     
+    --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
+    v_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+    v_landedcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
+            
+    IF (
+        r_invdetail.invfifo_unitcost = v_unitcost
+        AND
+        r_invdetail.invfifo_landedunitcost = v_landedcost
+        AND
+        r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+        AND
+        r_invdetail.invfifo_cost_before = v_invfifo_cost_before
+        --- we might need these???
+        --AND
+        --r_invdetail.invfifo_cust_id = v_cust_id
+        --AND
+        --r_invdetail.invfifo_cohead_id = v_cohead_id
+    ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landedcost,
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+            invfifo_recalc_queued = false
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+     
+     
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_return_inventory(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-return-invoice.sql b/pgsql/x-fifo-invfifo-update-from-return-invoice.sql
new file mode 100644 (file)
index 0000000..7f7ff55
--- /dev/null
@@ -0,0 +1,223 @@
+--- updates the invfifo values for shipped and unitcost
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_return_invoice(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_return_invoice(integer, boolean)
+    RETURNS  NUMERIC
+
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+     i_update_after ALIAS FOR $2;
+
+    r_invdetail RECORD;
+    r_ship_detail RECORD;
+    
+    v_unitcost  numeric;
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_landed_unitcost NUMERIC;
+    v_cost_before NUMERIC;
+    
+    v_last_id INTEGER;
+    v_cust_id INTEGER;
+    v_cohead_id INTEGER;
+    v_coitem_id INTEGER;
+    
+    v_cohead_number TEXT;
+     v_ar  TEXT ARRAY;
+    
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_return_invoice-- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'SH' AND (r_invdetail.invhist_ordtype != 'IN') ) THEN
+        RAISE EXCEPTION 'invfifo_update_from_return_invoice called on non-invoice item';
+    END IF;
+    
+    
+    -- order numbers US1000-1, XF-US10000-1-rev1
+    
+    -- can be in format 80000 
+     
+    -- find the salesorder..
+    SELECT regexp_split_to_array(r_invdetail.invhist_ordnumber,'-') INTO v_ar;
+    
+    SELECT   array_to_string(v_ar[1: array_length(v_ar,1) -1 ], '-')  INTO v_cohead_number;
+    --SELECT    v_ar[  array_length(v_ar,1)  ]::integer INTO v_soitem_linenumber;
+   
+    
+    
+        
+        -- find the sale row...
+       SELECT
+               invfifo_unitcost ,
+               invfifo_landedunitcost
+           INTO
+               v_unitcost,
+               v_landed_unitcost
+           FROM
+               invdetailview
+           WHERE
+               invhist_itemsite_id = r_invdetail.invhist_itemsite_id
+               AND
+               invhist_transtype = 'SH'
+               AND
+               ( invhist_ordtype  = 'SO' OR invhist_ordtype  = 'IN') -- invoice or sales order.!
+               --AND            
+               --invdetail_location_id =  r_invdetail.invdetail_location_id
+               -- it may have been returned to a different location..
+               AND
+               (
+                    invhist_ordnumber like  v_cohead_number || '-%'
+                    OR
+                    invhist_ordnumber = r_invdetail.invhist_ordnumber
+               )
+               AND
+               invdetail_qty < 0
+               AND
+                invfifo_void = 0
+           LIMIT 1;
+       
+        
+    IF NOT FOUND THEN
+        RAISE EXCEPTION 'Cound not find sales order for shipment return. %', r_invdetail.invhist_ordnumber;
+    END IF;
+    
+    
+    -- purchase price should match sale price...
+         
+    SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_cost_before;
+    
+    
+    -- THERE FOR
+    -- update invfifo
+    v_new_after := (v_landed_unitcost * r_invdetail.invdetail_qty) + v_cost_before;
+    
+    
+      IF (
+            r_invdetail.invfifo_unitcost = v_unitcost  
+            AND
+            r_invdetail.invfifo_landedunitcost =    v_landed_unitcost
+            AND
+            r_invdetail.invfifo_cost_after = v_new_after
+            AND
+            r_invdetail.invfifo_cost_before= v_cost_before
+            AND
+            r_invdetail.invfifo_cust_id = v_cust_id
+
+       ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landed_unitcost,
+            invfifo_cost_after = v_new_after,
+            invfifo_cust_id = v_cust_id,
+            invfifo_cost_before = v_cost_before
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_new_after - r_invdetail.invfifo_cost_after);
+    
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+      -- we can not skip this step, as outgoing stock that depends on it
+    -- needs to have the right values.
+    --IF NOT i_update_after THEN
+    --    RETURN v_diff;
+    --END IF;
+    
+    -- update the values after this one..
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0;
+    
+    
+    -- FLAG The sales after this date as dirty..
+    --UPDATE invfifo
+    --    SET
+    --       invfifo_recalc_queued = true
+    --     
+    --    FROM
+    --        invdetail, invhist           
+    --     WHERE
+    --        invfifo_invdetail_id = invdetail_id
+    --        AND
+    --        invhist_id = invdetail_invhist_id
+    --        AND            
+    --        invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --        AND
+    --        invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --        AND
+    --        -- stock outbound is greater than we started with.
+    --        invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+    --        AND
+    --        invdetail_qty < 0
+    --        AND
+    --        invfifo_void = 0;
+    --        
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_return_invoice(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-return-shipping.sql b/pgsql/x-fifo-invfifo-update-from-return-shipping.sql
new file mode 100644 (file)
index 0000000..a48e699
--- /dev/null
@@ -0,0 +1,18 @@
+--- updates the invfifo values for shipped and unitcost
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_return_shipping(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-shipment.sql b/pgsql/x-fifo-invfifo-update-from-shipment.sql
new file mode 100644 (file)
index 0000000..9d83d3f
--- /dev/null
@@ -0,0 +1,330 @@
+--- updates the invfifo values for shipped and unitcost
+
+
+
+--
+-- 
+--CREATE OR REPLACE FUNCTION invfifo_fix_cohead_id(integer)
+--    RETURNS  boolean
+--AS $BODY$
+--DECLARE    
+--i_invdetail_id  ALIAS FOR $1;
+--v_cohead_id INTEGER;
+--v_cohead_number TEXT;
+--BEGIN
+--    SELECT split_part(invhist_ordnumber, '-', 1) INTO v_cohead_number FROM invdetailview WHERE invdetail_id = i_invdetail_id;
+--    SELECT cohead_id INTO v_cohead_id from cohead where cohead_number = v_cohead_number;
+--    
+--    UPDATE invfifo
+--        SET
+--            invfifo_cohead_id = v_cohead_id
+--        WHERE
+--            invfifo_invdetail_id = i_invdetail_id;
+--            
+--    RETURN true;
+--END
+--$BODY$
+--  LANGUAGE plpgsql VOLATILE
+--  COST 100;
+--  
+--  
+  --
+  --SELECT
+  --  invfifo_fix_cohead_id(invdetail_id) from invdetailview
+  --   WHERE
+  --              invhist_ordtype  ='SO'
+  --              AND
+  --              invfifo_cohead_id = 0
+  --  
+  --                
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_shipment(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+---------------------------------------------
+  
+CREATE OR REPLACE FUNCTION invfifo_update_from_shipment(integer, boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+     i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+   
+    v_unitcost  NUMERIC;
+    _after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_cust_id INTEGER;
+    v_cohead_id INTEGER;
+    v_cohead_number TEXT;
+   v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+    v_est_unitcost NUMERIC;
+    
+     v_landedcost NUMERIC;
+    
+BEGIN
+     
+    -- 0.9ms
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_shipment -- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'SH' OR r_invdetail.invhist_ordtype !='SO') THEN
+           
+        RAISE EXCEPTION 'invfifo_update_from_shipment called on non-shipmnet id=%', i_invdetail_id ;
+    END IF;
+    
+    -- gather the customer...
+    
+    IF r_invdetail.invfifo_cust_id = 0 OR  r_invdetail.invfifo_cohead_id = 0 THEN  
+        
+        --RAISE NOTICE 'searching for order';
+    
+        SELECT split_part(r_invdetail.invhist_ordnumber, '-', 1) INTO v_cohead_number;
+        --SELECT split_part(r_invhist.invhist_ordnumber, '-', 2) INTO v_cohead_linefull;
+        --SELECT split_part(v_cohead_linefull, '.', 1)::integer INTO v_cohead_linenumber;
+        --SELECT split_part(v_cohead_linefull, '-', 2)::integer INTO v_cohead_subnumber;
+        
+        --SELECT
+        --    CASE WHEN split_part(v_cohead_linefull,'.', 2) = ''
+        --        THEN 0
+        --        ELSE split_part(v_cohead_linefull,'.', 2)::integer END  INTO v_cohead_subnumber;
+    
+        
+        SELECT
+                cohead_cust_id, --, coitem_id
+                cohead_id
+            INTO
+                v_cust_id,
+                v_cohead_id
+            FROM
+             
+                cohead
+            
+            WHERE
+                cohead_number = v_cohead_number
+                --AND
+                --coitem_linenumber = v_cohead_number
+                --   (cohead_number || '-' || coitem_linenumber) = r_invhist.invhist_ordnumber
+                --OR
+                --   (cohead_number || '-' || coitem_linenumber || '.' || coitem_subnumber) = r_invhist.invhist_ordnumber
+            LIMIT
+                1;
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'can not find cohead %', v_cohead_number;
+        END IF;
+    ELSE
+        v_cust_id = r_invdetail.invfifo_cust_id;
+        v_cohead_id = r_invdetail.invfifo_cohead_id;
+    END IF;
+     
+    
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    -- if it's the first transaction...
+    IF r_invdetail.invfifo_qty_before <= 0.0 THEN
+        
+        v_invfifo_cost_before = 0.0;
+        
+        SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+            v_invfifo_cost_after;
+        
+        
+        -- can be zero --- if purchased cost was also 0.0
+        if v_invfifo_cost_after <  0 THEN
+            v_invfifo_cost_before = 0.0;
+            
+            SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+                   v_est_unitcost;
+        
+            -- if we really can not guess...
+            IF v_est_unitcost  =0.0 THEN 
+                v_est_unitcost =r_invdetail.invhist_unitcost;
+            END IF;
+            v_invfifo_cost_after = r_invdetail.invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * v_est_unitcost;
+        END IF;    
+    
+    
+    
+    ELSE 
+        -- 0.55 ms
+        
+        SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+        
+        --SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        --    v_invfifo_cost_before;
+        
+        -- test: SELECT invfifo_cost_at_qty(3162, 127, 2314)
+        
+        -- 0.36 ms
+        SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+            v_invfifo_cost_after;
+            
+          -- RAISE NOTICE 'costs befor = %  after = %', v_invfifo_cost_before, v_invfifo_cost_after;
+     
+        IF v_invfifo_cost_after < 0 THEN
+            
+            -- we can try and work out the unit cost if there is some stock available..
+            
+            SELECT
+                invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before)  INTO
+                    v_est_unitcost;
+            IF v_est_unitcost > 0 THEN 
+                SELECT
+                    invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before + 1)  INTO
+                        v_est_unitcost;
+            END IF;
+            
+            RAISE NOTICE 'one pc est cost %', abs(v_est_unitcost - v_invfifo_cost_before);
+            IF v_est_unitcost > 0.0 THEN 
+                v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * abs(v_est_unitcost - v_invfifo_cost_before));
+            ELSE 
+                    -- a better indicator would be last purchase price...
+                SELECT
+                    invfifo_cost_estimate(r_invdetail.invhist_itemsite_id)
+                    INTO
+                    v_est_unitcost;
+                    
+                IF v_est_unitcost > 0.0 THEN 
+                    v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * v_est_unitcost);
+                ELSE
+                    -- finally give up and use the dodgy unit cost..
+                    v_invfifo_cost_after = v_invfifo_cost_before + (ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost);
+                END IF;
+            END IF;
+        --    
+        --ELSE 
+        --
+        --   IF v_invfifo_cost_after < 0 OR v_invfifo_cost_after < v_invfifo_cost_before  THEN
+        --       v_invfifo_cost_after = r_invdetail.invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+        --   END IF;
+        --   
+        END IF;
+    END IF;
+    
+    v_unitcost = ROUND(ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),2);
+    v_landedcost = ROUND(ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),2);
+    
+    -- this is an error condition - let's hope the other fixes solve this..
+    --if (v_invfifo_cost_after < v_invfifo_cost_before) THEN
+    --    RAISE EXCEPTION 'cost should not be less?? % %', v_invfifo_cost_before , v_invfifo_cost_after;
+    --END IF;
+    
+    
+    --RAISE NOTICE 'costs befor = %  after = %', v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    IF (
+        r_invdetail.invfifo_unitcost = v_unitcost
+        AND
+        r_invdetail.invfifo_landedunitcost = v_landedcost
+        AND
+        r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+        AND
+        r_invdetail.invfifo_cost_before = v_invfifo_cost_before
+        AND
+        r_invdetail.invfifo_cust_id = v_cust_id
+        AND
+        r_invdetail.invfifo_cohead_id = v_cohead_id
+    ) THEN
+       -- RAISE NOTICE 'no change';
+        RETURN 0;
+    END IF;
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = v_unitcost,
+            invfifo_landedunitcost = v_landedcost,
+            
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+            
+            invfifo_recalc_queued = false,
+            invfifo_cust_id = v_cust_id,
+            invfifo_cohead_id = v_cohead_id
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    
+    --RAISE NOTICE 'diff is %', v_diff;
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+     
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_shipment(integer,boolean)
+  OWNER TO admin;
+
+
+--testing error in sg
+
+--SELECT invfifo_update_from_shipment(148992,true);
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-transfer-in.sql b/pgsql/x-fifo-invfifo-update-from-transfer-in.sql
new file mode 100644 (file)
index 0000000..5184611
--- /dev/null
@@ -0,0 +1,213 @@
+--- updates the invfifo values for shipped and unitcost
+
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_transfer_in(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+---------------------------------------------
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_transfer_in(integer, boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+   
+    v_unitcost  numeric(18, 6);
+    v_ret  numeric(18, 6);
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_vend_id INTEGER;
+    v_cost_before NUMERIC;
+    v_tmp NUMERIC;
+    v_tmp_i INTEGER;
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_transfer_in -- need to add invfifo gen code';
+    END IF;
+    
+    IF (r_invdetail.invhist_transtype != 'RL') THEN
+        RAISE EXCEPTION 'invfifo_update_from_transfer_in called on non-transfer';
+    END IF;
+    
+    
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    -- process the transfer out before the in..
+  
+  
+  
+  
+    SELECT
+            invfifo_update_from_transfer_out(invdetail_id,i_update_after)
+        INTO
+            v_tmp
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    != i_invdetail_id
+            AND
+            invhist_id = r_invdetail.invhist_id;
+            
+    IF NOT FOUND THEN
+        RAISE EXCEPTION  'invfifo_update_from_transfer_in could not find outgoing transfer';
+    END IF;
+     
+  
+    SELECT
+            *
+        INTO
+            r_invdetail_out
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    != i_invdetail_id
+            AND
+            invhist_id = r_invdetail.invhist_id;
+
+    
+    -- find out the cost before..
+    SELECT invfifo_cost_before_in(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_cost_before;      
+        
+    
+    --RAISE NOTICE ' invfifo_qty_after <%, invdetail_location_id= %, invhist_itemsite_id=%',
+    
+    --        r_invdetail.invfifo_qty_after,  r_invdetail.invdetail_location_id , r_invdetail.invhist_itemsite_id  ;
+    --RAISE NOTICE 'cost before is %', v_cost_before;
+    
+     -- THERE FOR
+    -- update invfifo
+    v_new_after := (ROUND( r_invdetail_out.invfifo_landedunitcost,2) * r_invdetail.invdetail_qty)
+                + v_cost_before;
+    
+    
+    IF (
+            r_invdetail.invfifo_unitcost = ROUND(r_invdetail_out.invfifo_unitcost,2)
+            AND
+            r_invdetail.invfifo_landedunitcost = ROUND(r_invdetail_out.invfifo_landedunitcost,2)
+            AND
+            r_invdetail.invfifo_cost_after = v_new_after
+            AND
+            r_invdetail.invfifo_cost_before = v_cost_before
+    
+    ) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = ROUND(r_invdetail_out.invfifo_unitcost,2),
+            invfifo_landedunitcost = ROUND(r_invdetail_out.invfifo_landedunitcost,2),
+            invfifo_cost_after = v_new_after,
+            invfifo_cost_before = v_cost_before
+            
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_new_after - r_invdetail.invfifo_cost_after,2);
+    
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+         -- we can not skip this step, as outgoing stock that depends on it
+    -- needs to have the right values.
+    
+    --IF NOT i_update_after THEN
+    --    RETURN v_diff;
+    --END IF;
+    
+    -- update the values after this one..
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty > 0
+            AND
+            invfifo_void = 0;
+    
+    --
+    ---- FLAG The sales after this date as dirty..
+    --UPDATE invfifo
+    --    SET
+    --       invfifo_recalc_queued = true
+    --     
+    --    FROM
+    --        invdetail, invhist           
+    --     WHERE
+    --        invfifo_invdetail_id = invdetail_id
+    --        AND
+    --        invhist_id = invdetail_invhist_id
+    --        AND            
+    --        invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --        AND
+    --        invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --        AND
+    --        -- stock outbound is greater than we started with.
+    --        invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+    --        AND
+    --        invdetail_qty < 0
+    --        AND
+    --        invfifo_void = 0;
+    --        
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_transfer_in(integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo-update-from-transfer-out.sql b/pgsql/x-fifo-invfifo-update-from-transfer-out.sql
new file mode 100644 (file)
index 0000000..6c259b0
--- /dev/null
@@ -0,0 +1,411 @@
+--- updates the invfifo values for shipped and unitcost
+
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_transfer_out(integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+---------------------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_transfer_out(integer,boolean)
+    RETURNS  NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_update_after ALIAS FOR $2;
+   
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+     v_invfifo_cost_before NUMERIC;
+    v_invfifo_cost_after NUMERIC;
+    v_est_unitcost NUMERIC;
+    v_unitcost NUMERIC;
+     v_new_after NUMERIC;
+     v_stock_qty  NUMERIC;
+    v_diff NUMERIC;
+    v_maxcost NUMERIC;
+    v_last_id INTEGER;
+    v_rev INTEGER;
+    
+    v_buyqty_before NUMERIC;
+BEGIN
+     
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_shipment -- need to add invfifo gen code';
+    END IF;
+    
+     IF (r_invdetail.invhist_transtype != 'RL') THEN
+        RAISE EXCEPTION 'invfifo_update_from_transfer_out called on non-transfer';
+    END IF;
+
+
+
+    -- this should do a void check...
+    
+    --
+    --SELECT
+    --        invdetail_location_id
+    --    INTO
+    --        v_our_rev_location_id
+    --    FROM
+    --        invdetail
+    --    WHERE
+    --        invhist_id = r_invdetail.invhist_id
+    --        AND
+    --        invdetail_id != r_invdetail.invdetail_id;
+    --
+    -- what if there are multiple reversals..
+    --
+    --SELECT
+    --        invhist_id
+    --    INTO
+    --        v_rev_invhist_id
+    --    FROM
+    --        invdetailview
+    --    WHERE
+    --        invhist_id != r_invdetail.invhist_id
+    --    AND
+    --        invdetail_qty = -1 * r_invdetail.invdetail_qty
+    --    AND
+    --        itemsite_id = r_invdetail.itemsite_id
+    --    AND
+    --        invhist_transdate::date = r_invdetail.invhist_transdate::date
+    --    AND
+    --        invdetail_location_id = r_invdetail.invdetail_location_id 
+    --    AND
+    --        invhist_transtype = 'RL'
+    --    AND
+    --        invfifo_void  = 0
+    --    LIMIT 1;
+    --
+    --
+    --
+    --IF FOUND THEN
+    --    -- see if the target location was the same as our reversal...
+    --            
+    --    SELECT
+    --            invdetail_id
+    --        INTO
+    --            v_tmp
+    --        FROM
+    --            invdetail
+    --        WHERE
+    --            invhist_id = v_rev_invhist_id
+    --            AND
+    --            invdetail_location_id = v_our_rev_location_id
+    --         
+    --            
+    --    IF FOUND THEN
+    --        -- flag them all void..
+    --        -- and return..
+    --        RAISE NOTICE 'voiding a reversed transfer';
+    --        PERFORM invfifo_update_from_void(invdetail_id,true) FROM invdetailview where invhist_id = r_invdetail.invdetail_id;
+    --        PERFORM invfifo_update_from_void(invdetail_id,true) FROM invdetailview where invhist_id = v_rev_invhist_id;
+    --        return 0;
+    --    END IF;
+    --END IF;
+    --        
+
+
+    
+    -- are we transfering out more than we actually have at this point in time?
+    -- if we are, then we are basing our calculation on what the future value of the product
+    -- is going to be.
+    -- which may vary.
+    
+    
+    SELECT invdetail_at_id(i_invdetail_id) - r_invdetail.invdetail_qty INTO v_stock_qty;
+    
+    
+    
+    -- let's try and forward calc
+    
+    --IF NOT i_update_after THEN
+    --
+    --    SELECT
+    --        invfifo_qty_after
+    --    INTO
+    --        v_buyqty_before
+    --    FROM
+    --        invdetailview
+    --    WHERE
+    --        invdetail_location_id =  r_invdetail.invdetail_location_id 
+    --        AND
+    --        invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+    --        AND
+    --        (
+    --            invhist_transdate < r_invdetail.invhist_transdate
+    --            OR
+    --            (
+    --                invhist_transdate = r_invdetail.invhist_transdate
+    --                AND
+    --                invdetail_id < r_invdetail.invdetail_id
+    --            )
+    --        )
+    --        
+    --        AND
+    --        invfifo_void = 0
+    --          AND
+    --        -- it's a purchase.
+    --        invdetail_qty > 0
+    --   
+    --    ORDER BY
+    --        invhist_transdate DESC,
+    --        invdetail_id DESC
+    --    LIMIT 1;
+    --
+    --    -- if we do not have enough stock at this point in time to fullfill it..
+    --    -- then try and do the forward calcs first..
+    --
+    --    IF v_buyqty_before < r_invdetail.invdetail_qty_after THEN
+    --    
+    --        PERFORM invfifo_update_from_invdetail_ahead(i_invdetail_id);
+    --        
+    --    END IF;
+    --
+    --
+    --
+    --
+    --
+    --END IF;
+    --
+    
+     
+    
+    --if this is the first transaction..
+    --if r_invdetail.invfifo_qty_before <= 0.0  AND v_stock_qty = 0 THEN
+    
+       -- RAISE NOTICE 'no stock to fullfill';
+    --
+    --    -- first line >> transferingout.. and we do not have 
+    --    
+    --    -- at this point in time do we have any to distribute?
+    --    
+    --    IF 
+    --    
+    --    
+   --     v_invfifo_cost_before = 0.0;
+   --     v_invfifo_cost_after = 0.0;
+    --    
+    --    
+    --    
+    --    
+    --    
+    --    SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+    --           v_est_unitcost;
+    --
+    --    -- if we really can not guess...
+    --    IF v_est_unitcost  =0.0 THEN 
+    --        v_est_unitcost =r_invdetail.invhist_unitcost;
+    --    END IF;
+    --    v_invfifo_cost_after = r_invdetail.invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * v_est_unitcost;
+    --
+    --ELSE 
+    
+      
+        
+        -- fetch the actual purchase price
+        -- it should be the reverse of this.
+        
+        -- previous line should be the indicator of this...
+        -- as weird adjustments happend.
+        SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+           
+        
+            
+        
+        IF (v_invfifo_cost_before = 0.0 AND r_invdetail.invfifo_qty_before > 0) THEN
+            PERFORM invfifo_fill_all(r_invdetail.invdetail_location_id, r_invdetail.invhist_itemsite_id);
+            SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+        
+        END IF;
+        
+        --SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+        --    v_invfifo_cost_before;
+        
+        SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
+            v_invfifo_cost_after;
+            
+         --RAISE NOTICE 'FROM COST@QTY v_invfifo_cost_before(%)=%, v_invfifo_cost_after(%)=%',
+         --         r_invdetail.invfifo_qty_before , v_invfifo_cost_before,
+           --        r_invdetail.invfifo_qty_after, v_invfifo_cost_after;    
+    
+        IF v_invfifo_cost_before < 0 THEN
+        
+            --- use last line value... and the stdcost..
+            SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
+                v_invfifo_cost_before;
+                
+            v_invfifo_cost_after = v_invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
+          
+        
+        ELSE
+            -- $0 value is actually ok..
+        
+            IF v_invfifo_cost_after <  0 OR v_invfifo_cost_after < v_invfifo_cost_before THEN
+                -- then we could not work out the cost after??
+                
+                SELECT invfifo_unitcost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
+                    v_est_unitcost;
+                
+                -- if we can not find a unit cost from this location..
+                -- then try last purchase
+                IF v_est_unitcost  =0.0 THEN 
+                    SELECT invfifo_unitcost_at_date(r_invdetail.invhist_itemsite_id,   r_invdetail.invhist_transdate::date) INTO
+                       v_est_unitcost;
+                END IF;
+                
+              --  RAISE NOTICE 'est unit cost is %',v_est_unitcost ;    
+                v_invfifo_cost_after = r_invdetail.invfifo_cost_before + ABS(r_invdetail.invdetail_qty) * v_est_unitcost;
+                
+                
+                
+                
+                
+            END IF;
+        END IF;
+     -- END IF;
+    
+    -- finally do a sanity test..
+    
+    
+    SELECT
+            ROUND(max(invfifo_landedunitcost),2)
+        INTO
+            v_maxcost
+        FROM
+            invdetailview
+        WHERE
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id
+            AND
+            invdetail_qty > 0
+            AND
+            invhist_transtype = 'RP' -- purchases only!
+            AND
+            invfifo_void = 0;
+    
+    IF ((v_invfifo_cost_after - v_invfifo_cost_before) / r_invdetail.invdetail_qty) > v_maxcost THEN
+        v_invfifo_cost_after = v_invfifo_cost_before + (v_maxcost * r_invdetail.invdetail_qty) ;
+    END IF;
+    --END IF;   
+   --RAISE NOTICE 'v_invfifo_cost_before=%, v_invfifo_cost_after=%', v_invfifo_cost_before, v_invfifo_cost_after;
+    
+    IF (
+        r_invdetail.invfifo_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty) AND 
+        r_invdetail.invfifo_landedunitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty) AND
+        r_invdetail.invfifo_cost_after = v_invfifo_cost_after
+        AND
+        r_invdetail.invfifo_cost_before = v_invfifo_cost_before
+    
+    ) THEN
+        return 0;
+    END IF;
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),
+            invfifo_landedunitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty),
+            invfifo_cost_after = v_invfifo_cost_after,
+            invfifo_cost_before = v_invfifo_cost_before,
+            invfifo_recalc_queued = false 
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
+    
+    IF (v_diff = 0.0) THEN
+        RETURN 0;
+    END IF;
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    -- update the values after this one..
+     -- FLAG The sales after this date as dirty.?? just in case?
+     
+    UPDATE invfifo
+        SET 
+            invfifo_cost_after = invfifo_cost_after + v_diff,
+            invfifo_cost_before = invfifo_cost_before + v_diff
+            --,
+     --       invfifo_recalc_queued = 1
+      
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+    
+    
+    -- trigger an update on the reverse..
+    
+    --SELECT
+    --        invdetail_id
+    --    INTO
+    --        v_rev
+    --    FROM
+    --        invdetail   
+    --    WHERE
+    --        invdetail_id    != i_invdetail_id
+    --        AND
+    --        invdetail_invhist_id = r_invdetail.invhist_id
+    --    LIMIT 1;
+    --
+    --
+    ---- update the reversed value...
+    --PERFORM invfifo_update_from_transfer_in(v_rev);
+    --
+    
+     
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_shipment(integer,boolean)
+  OWNER TO admin;
+    
+    
+    
+-- testing!!!?
+--select invfifo_update_from_invdetail(268120,true);
diff --git a/pgsql/x-fifo-invfifo-update-from-void.sql b/pgsql/x-fifo-invfifo-update-from-void.sql
new file mode 100644 (file)
index 0000000..d7d2cc7
--- /dev/null
@@ -0,0 +1,209 @@
+--- updates the invfifo values for voided records - zero's out qty and values.
+
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_void(integer, integer)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+i_invdetail_id  ALIAS FOR $1;
+i_invdetail_x  ALIAS FOR $2;
+BEGIN
+    RAISE EXCEPTION 'replaced with option version';
+END
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+
+-------------------------------------------
+
+CREATE OR REPLACE FUNCTION invfifo_update_from_void(integer, integer, boolean)
+    RETURNS   NUMERIC
+AS $BODY$
+DECLARE        
+           
+    i_invdetail_id  ALIAS FOR $1;
+    i_void_id  ALIAS FOR $2;
+    i_update_after ALIAS FOR $3;
+    
+    r_invdetail RECORD;
+    r_invdetail_out RECORD;
+   
+    v_unitcost  numeric(18, 6);
+    v_ret  numeric(18, 6);
+    v_new_after NUMERIC;
+    v_diff NUMERIC;
+    v_last_id INTEGER;
+    v_vend_id INTEGER;
+    v_cost_before NUMERIC;
+    v_qty_diff NUMERIC;
+    
+    
+    
+
+BEGIN
+    
+     SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invfifo
+        WHERE
+            invfifo_invdetail_id    = i_invdetail_id;
+    
+    IF NOT FOUND THEN
+        PERFORM invfifo_fill(i_invdetail_id);
+    END IF;
+    
+    
+    IF i_void_id = 0 THEN
+        i_void_id = -1;
+    END IF;
+    
+    SELECT
+            *
+        INTO
+            r_invdetail
+        FROM
+            invdetailview  
+        WHERE
+            invdetail_id    = i_invdetail_id;
+    
+    
+    IF NOT FOUND THEN
+        RAISE EXCEPTION ' invfifo_update_from_void -- need to add invfifo gen code';
+    END IF;
+    
+     
+     
+    
+    -- fetch the actual purchase price
+    -- it should be the reverse of this.
+    
+    
+    
+    -- previous cost after..
+    -- slight tweak on qty.. base it on base+1
+    
+     v_cost_before = 0;
+     
+    if (
+        (v_cost_before = r_invdetail.invfifo_cost_after)
+        AND
+        (v_cost_before = r_invdetail.invfifo_cost_before)
+       
+        AND
+        (r_invdetail.invfifo_qty_after = r_invdetail.invfifo_qty_before )
+       )
+    THEN
+    
+        IF r_invdetail.invfifo_void != 0 THEN
+    
+        -- already processed.
+            RETURN 0;
+        END IF;
+        -- just update the vooid flag
+        
+        UPDATE invfifo
+            SET 
+                invfifo_void = i_void_id
+        WHERE
+                invfifo_invdetail_id = r_invdetail.invdetail_id;
+                
+        RETURN 0;
+    END IF;
+    -- THERE FOR
+    -- update invfifo
+    
+    UPDATE invfifo
+        SET 
+            invfifo_unitcost = 0,
+            invfifo_landedunitcost = 0,
+            invfifo_cost_after = v_cost_before,
+            invfifo_cost_before = v_cost_before,
+            invfifo_qty_after = r_invdetail.invfifo_qty_before,
+            invfifo_void = i_void_id
+            
+        WHERE
+            invfifo_invdetail_id = r_invdetail.invdetail_id;
+    
+    v_diff = ROUND(v_cost_before- r_invdetail.invfifo_cost_after,2);
+    v_qty_diff = r_invdetail.invfifo_qty_before - r_invdetail.invfifo_qty_after;
+    
+    IF (v_diff = 0.0) AND (v_qty_diff = 0) THEN
+        RETURN 0;
+    END IF;
+    
+    
+    IF NOT i_update_after THEN
+        RETURN v_diff;
+    END IF;
+    
+    -- update the values after this one..
+    
+    UPDATE invfifo
+        SET 
+           invfifo_cost_after = invfifo_cost_after + v_diff,
+           invfifo_cost_before = invfifo_cost_before + v_diff,
+          invfifo_qty_after =invfifo_qty_after + v_qty_diff,
+          invfifo_qty_before = invfifo_qty_before + v_qty_diff
+        FROM
+            invdetail, invhist           
+           -- unit costs and landed does not change on after..
+        WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            invfifo_qty_after >  r_invdetail.invfifo_qty_after
+            AND
+            (
+                (r_invdetail.invdetail_qty > 0 AND  invdetail_qty > 0)
+                OR
+                (r_invdetail.invdetail_qty < 0 AND  invdetail_qty < 0)
+            )
+            AND
+            invfifo_void = 0;
+            
+    
+    
+    -- FLAG The sales after this date as dirty..
+    UPDATE invfifo
+        SET
+           invfifo_recalc_queued = true
+         
+        FROM
+            invdetail, invhist           
+         WHERE
+            invfifo_invdetail_id = invdetail_id
+            AND
+            invhist_id = invdetail_invhist_id
+            AND            
+            invdetail_location_id =  r_invdetail.invdetail_location_id 
+            AND
+            invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
+            AND
+            -- stock outbound is greater than we started with.
+            invfifo_qty_before >=  r_invdetail.invfifo_qty_before
+            AND
+            invdetail_qty < 0
+            AND
+            invfifo_void = 0;
+            
+            
+    return v_diff;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifo_update_from_void(integer,integer,boolean)
+  OWNER TO admin;
+    
\ No newline at end of file
diff --git a/pgsql/x-fifo-invfifo.sql b/pgsql/x-fifo-invfifo.sql
new file mode 100644 (file)
index 0000000..501d9a3
--- /dev/null
@@ -0,0 +1,133 @@
+-- invfifo is a shadow table to invdetail which contains the fifo data.
+
+
+
+
+create table invfifo (
+    invfifo_invdetail_id integer NOT NULL UNIQUE,
+    
+    -- unit is excluding shipping (it's mostly ignored now)
+    invfifo_unitcost   numeric(18, 6)  NOT NULL,
+    invfifo_landedunitcost NUMERIC(18,6) DEFAULT 0.0 NOT NULL,
+    
+    -- not used??
+    invfifo_totalcost  numeric(18, 6)  NOT NULL,
+    
+    -- key columns which the calculation is done on .
+    invfifo_qty_before  numeric(18, 6)  NOT NULL,
+    invfifo_qty_after  numeric(18, 6)  NOT NULL,
+    invfifo_cost_before  numeric(18, 6)  NOT NULL,
+    invfifo_cost_after  numeric(18, 6)  NOT NULL,
+    
+    -- flags .. not used at present.. may not be in futer
+    invfifo_is_estimate boolean  NOT NULL,
+    invfifo_recalc_queued boolean  NOT NULL,
+    
+    -- this is used to determine if update_from_invdetail has been run.
+     
+    
+    -- just stores cust/vend to save looking it up later.
+    invfifo_vend_id INT DEFAULT 0,
+    invfifo_cust_id INT DEFAULT 0,
+    invfifo_cohead_id INT NOT NULL DEFAULT 0,
+    -- FIXME - cohead_id might be a good idea here...
+    
+    
+    -- is the transaction a reversal of another one - so has $0 effect on FIFO.
+    -- should point to the invdetail_id of what it reverses, or -1 for random flagging...
+    invfifo_void           INTEGER NOT NULL DEFAULT 0,
+    
+    CONSTRAINT  invfifo_invdetail_fk FOREIGN KEY ( invfifo_invdetail_id) REFERENCES invdetail (invdetail_id) 
+   
+);
+alter table invfifo add column invfifo_landedunitcost NUMERIC(18,6) DEFAULT 0.0 NOT NULL;
+-- void of which record.
+alter table invfifo add column invfifo_void           INTEGER NOT NULL DEFAULT 0;
+alter table invfifo add column invfifo_cohead_id INT NOT NULL DEFAULT 0;
+
+GRANT ALL ON TABLE invfifo TO admin;
+GRANT ALL ON TABLE invfifo TO xtrole;
+
+
+CREATE INDEX invfifo_qty_before_indx
+  ON invfifo
+  USING btree
+  (invfifo_qty_before);
+
+CREATE INDEX invfifo_qty_after_indx
+  ON invfifo
+  USING btree
+  (invfifo_qty_after);
+
+CREATE INDEX invfifo_is_estimate_indx
+  ON invfifo
+  USING btree
+  (invfifo_is_estimate);
+  
+CREATE INDEX invfifo_recalc_queued_indx
+  ON invfifo
+  USING btree
+  (invfifo_recalc_queued);
+
+CREATE INDEX invfifo_cust_id_indx
+  ON invfifo
+  USING btree
+  (invfifo_cust_id);
+CREATE INDEX invfifo_vend_id_indx
+  ON invfifo
+  USING btree
+  (invfifo_vend_id); 
+   
+ CREATE INDEX invfifo_qty_before_indx
+  ON invfifo
+  USING btree
+  (invfifo_qty_before);
+
+CREATE INDEX invfifo_void_indx
+  ON invfifo
+  USING btree
+  (invfifo_void);
+
+CREATE INDEX invfifo_cohead_id_indx
+  ON invfifo
+  USING btree
+  (invfifo_cohead_id);
+
+alter table invfifo drop column invfifo_coitem_id;
+
+
+
+-- update /inserts tirgger invfifo_fill()
+
+CREATE OR REPLACE FUNCTION invdetailtriggerfifo() RETURNS trigger 
+AS $BODY$
+DECLARE
+     
+BEGIN
+    
+    PERFORM invfifo_fill(NEW.invdetail_id);
+      
+    RETURN NEW;   
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invdetailtriggerfifo()
+  OWNER TO admin;
+          
+
+
+
+
+
+CREATE TRIGGER _invdetailtriggerfifo 
+    AFTER INSERT ON invdetail
+        FOR EACH ROW EXECUTE PROCEDURE invdetailtriggerfifo();
+        
+
diff --git a/pgsql/x-fifo-invfifo_apply_gl_cmhead_fix_stock.sql b/pgsql/x-fifo-invfifo_apply_gl_cmhead_fix_stock.sql
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pgsql/x-fifo-invfifopos.sql b/pgsql/x-fifo-invfifopos.sql
new file mode 100644 (file)
index 0000000..48ee312
--- /dev/null
@@ -0,0 +1,98 @@
+
+
+-- used to determine if fifo adjustment is needed on the itemsite.
+
+create table invfifopos (
+    invfifopos_itemsite_id integer NOT NULL UNIQUE,
+    
+    -- how much did the last run adjust it by.
+    invfifopos_lastadjustment   numeric(18, 6)  NOT NULL,
+    
+    
+    -- what was the last id that was run.
+    invfifopos_last_invdetail_id INT DEFAULT 0,
+    
+    
+    CONSTRAINT  invfifopos_itemsite_id_fk FOREIGN KEY ( invfifopos_itemsite_id) REFERENCES itemsite (itemsite_id) 
+   
+);
+
+
+alter table invfifopos alter column invfifopos_lastadjustment type numeric(24,2);
+
+
+GRANT ALL ON TABLE invfifo TO admin;
+GRANT ALL ON TABLE invfifo TO xtrole;
+
+
+CREATE INDEX invfifopos_itemsite_id_indx
+  ON invfifopos
+  USING btree
+  (invfifopos_itemsite_id);
+
+
+CREATE INDEX invfifopos_last_invdetail_id_indx
+  ON invfifopos
+  USING btree
+  (invfifopos_last_invdetail_id);
+CREATE INDEX invfifopos_lastadjustment_indx
+  ON invfifopos
+  USING btree
+  (invfifopos_lastadjustment);
+
+CREATE OR REPLACE FUNCTION invfifopos_update(integer, integer, numeric)
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+    
+    i_itemsite_id  ALIAS FOR $1;
+    i_invdetail_id ALIAS FOR $2;
+    i_lastadjustment ALIAS FOR $3; 
+    v_id INTEGER;
+    
+ BEGIN   
+    
+    SELECT
+            invfifopos_last_invdetail_id
+        INTO
+            v_id
+        FROM
+             invfifopos
+        WHERE
+            invfifopos_itemsite_id = i_itemsite_id;
+    
+    IF FOUND THEN
+        
+        UPDATE 
+                invfifopos
+            SET
+                invfifopos_last_invdetail_id = i_invdetail_id,
+                invfifopos_lastadjustment = i_lastadjustment
+            WHERE
+                invfifopos_itemsite_id =  i_itemsite_id;
+                
+                
+        RETURN true;
+    END IF;
+    
+    INSERT INTO 
+           invfifopos
+        ( invfifopos_itemsite_id , invfifopos_lastadjustment  , invfifopos_last_invdetail_id )
+        VALUES
+            (i_itemsite_id, i_lastadjustment, i_invdetail_id);
+        
+    
+    
+    RETURN true;
+   END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  invfifopos_update(integer, integer, numeric)
+  OWNER TO admin;
+          
diff --git a/pgsql/x-fifo-set-metric.sql b/pgsql/x-fifo-set-metric.sql
new file mode 100644 (file)
index 0000000..79452a7
--- /dev/null
@@ -0,0 +1,3 @@
+-- just set up standard as fifo
+
+SELECT setmetric('UseStandardAsFIFO', 't');
\ No newline at end of file
diff --git a/pgsql/x-fix-cmhead-location-id.sql b/pgsql/x-fix-cmhead-location-id.sql
new file mode 100644 (file)
index 0000000..c4da2ad
--- /dev/null
@@ -0,0 +1,66 @@
+
+    
+--------------- Fix blank location id in stock 
+  
+
+CREATE OR REPLACE FUNCTION x_fix_cmhead_location_id()
+    RETURNS  TEXT
+    
+AS $BODY$
+DECLARE
+    v_location_id INTEGER;
+    v_count INTEGER;
+    _r RECORD;
+    
+BEGIN
+    
+    v_count := 0;
+    
+    FOR _r IN SELECT
+                        cmhead_id,
+                        cmhead_number
+              FROM
+                        cmhead
+              WHERE
+                        cmhead_location_id IS NULL LOOP
+
+        SELECT
+                invdetail_location_id
+        INTO
+                v_location_id
+        FROM
+                invdetail
+        LEFT JOIN
+                invhist
+        ON
+                invhist_id = invdetail_invhist_id
+        WHERE
+                invhist_ordnumber = _r.cmhead_number
+        LIMIT 1;
+
+        IF (NOT FOUND) THEN
+            RAISE EXCEPTION 'invhist not found. cmhead_number = %', _r.cmhead_number;
+        END IF;
+
+        UPDATE 
+                cmhead 
+        SET 
+                cmhead_location_id = v_location_id
+        WHERE 
+                cmhead_id = _r.cmhead_id;
+
+        v_count = v_count + 1;           
+
+    END LOOP;
+
+    RETURN 'FIXED: ' || v_count;
+            
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_fix_cmhead_location_id()
+  OWNER TO admin; 
+
+
diff --git a/pgsql/x-fix-cmhead-missing-inv-tx.sql b/pgsql/x-fix-cmhead-missing-inv-tx.sql
new file mode 100644 (file)
index 0000000..859973a
--- /dev/null
@@ -0,0 +1,272 @@
+
+
+
+
+
+
+
+CREATE OR REPLACE FUNCTION x_fix_chmead_missing_tx(integer)
+    RETURNS  NUMERIC
+    
+AS $BODY$
+DECLARE        
+    i_cmhead_id  ALIAS FOR $1;
+    v_number TEXT;
+    v_total NUMERIC;
+    v_fifo_qty NUMERIC;
+    v_fifo_total NUMERIC;
+    v_tmp INTEGER;
+    v_ret NUMERIC; 
+    v_itemlocSeries INTEGER;
+    v_invhistid   INTEGER;
+    v_btmp BOOLEAN;
+    
+    r_cmhead RECORD;
+    r_invlocdist RECORD;
+    r_tmp RECORD;
+    v_period_close_at_end INTEGER;
+    v_period_start DATE;
+    v_period_end DATE;
+    v_period_closed BOOLEAN;
+BEGIN
+
+    
+    SELECT
+        
+        cmhead_number
+    INTO
+        v_number
+    
+    FROM
+         
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id;
+    
+    
+    -- if customer has not been set, and records exist -- we do not deal with this.
+    
+    select
+            count(invdetail_id)
+        INTO
+            v_tmp
+        FROM
+            invdetailview
+         WHERE
+           
+            invhist_ordnumber = v_number 
+        AND
+            invfifo_cust_id = 0
+        AND
+            -- cm's are not voided.!?!?
+            invfifo_void = 0
+        AND
+           invhist_ordtype = 'CM';
+        
+    
+    IF FOUND AND v_tmp > 0 THEN
+        RETURN 0;
+    END IF;
+    
+    
+    
+    
+    -- cmitem qty..
+    
+    SELECT
+        -- factor in reserved for non-shpped?
+            SUM(cmitem_qtyreturned)
+        INTO
+            v_total 
+        FROM
+            cmitem
+             
+        LEFT JOIN
+            itemsite
+        ON
+            itemsite_id = cmitem_itemsite_id
+        LEFT JOIN 
+            cmhead
+        ON
+            cmhead_id = cmitem_cmhead_id
+        WHERE
+            cmitem_cmhead_id = i_cmhead_id
+        AND
+            NOT cmhead_void
+        AND
+            itemsite_stocked;
+        
+    IF NOT FOUND OR v_total IS NULL THEN
+        RETURN 0;
+    END IF;
+    
+    -- fifo qty..
+    
+    SELECT
+        COALESCE(SUM(invdetail_qty ),0) ,
+        COALESCE(SUM(invdetail_qty   * invfifo_landedunitcost),0)
+        INTO
+            v_fifo_qty,
+            v_fifo_total
+        FROM
+            invdetailview
+        WHERE
+           
+            invhist_ordnumber = v_number 
+             
+        AND
+            -- cm's are not voided.!?!?
+             invfifo_void = 0
+        AND
+           invhist_ordtype = 'CM';
+    
+    
+    IF   v_fifo_qty >= v_total THEN
+        RETURN 0;
+        
+    END IF;
+    RAISE NOTICE 'docnum=%, fifo qty for cmhead_id = %  does not match fifo = %, shipped = %',
+                v_number , i_cmhead_id, v_fifo_qty, v_total;
+    --return 0;
+     
+     
+     
+     
+    SELECT
+        *
+    INTO
+        r_cmhead
+    
+    FROM
+         
+            cmhead
+        WHERE
+            cmhead_id = i_cmhead_id;
+    
+    SELECT period_temp_open(COALESCE(r_cmhead.cmhead_gldistdate, r_cmhead.cmhead_docdate)) INTO v_period_close_at_end;
+      
+    -- create the initial itemlocdis
+     
+    
+    SELECT NEXTVAL('itemloc_series_seq') INTO v_itemlocSeries;
+    RAISE NOTICE 'got series';
+    PERFORM
+            postInvTrans(
+                itemsite_id,
+                'RS',
+                (cmitem_qtyreturned * cmitem_qty_invuomratio),
+                'S/O',
+                'CM',
+                cmhead_number,
+                '',
+                ('Credit Return ' || item_number),
+                costcat_asset_accnt_id,
+                getPrjAccntId(cmhead_prj_id, resolveCOSAccount(itemsite_id, cmhead_cust_id)), 
+                v_itemlocSeries,
+                COALESCE(cmhead_gldistdate, cmhead_docdate)
+            )
+           
+        FROM
+            cmitem
+        LEFT JOIN
+            cmhead
+        ON
+            cmhead_id = cmitem_cmhead_id
+        LEFT JOIN
+            itemsite
+        ON
+            itemsite_id = cmitem_itemsite_id
+        LEFT JOIN
+            item
+        ON
+            item_id = itemsite_item_id
+        LEFT JOIN 
+            costcat
+        ON
+            itemsite_costcat_id=costcat_id
+        WHERE
+                (cmitem_qtyreturned <> 0)
+            AND
+                (cmitem_updateinv)
+            AND
+                cmitem_cmhead_id = i_cmhead_id;
+        
+    RAISE NOTICE 'posted invtrans %', r_cmhead;            
+     
+     
+       --- next... insert all the  
+    RAISE NOTICE 'loop start itemlocdist_series=%',  v_itemlocSeries;
+    
+
+    FOR r_invlocdist IN SELECT itemlocdist_id,
+                itemlocdist_reqlotserial,
+                itemlocdist_distlotserial,
+                itemlocdist_qty,
+                itemsite_loccntrl,
+                itemsite_controlmethod,
+                itemsite_perishable,
+                itemsite_warrpurc,
+                COALESCE(itemsite_lsseq_id,-1) AS itemsite_lsseq_id,
+                COALESCE(itemlocdist_source_id,-1) AS itemlocdist_source_id
+                FROM itemlocdist, itemsite
+                WHERE ( (itemlocdist_itemsite_id=itemsite_id) 
+                        AND (itemlocdist_series  =  v_itemlocSeries ) ) 
+                ORDER BY itemlocdist_id LOOP
+        
+        SELECT * INTO r_tmp FROM itemlocdist WHERE itemlocdist_id = r_invlocdist.itemlocdist_id;
+    
+        RAISE NOTICE 'loop start %', r_tmp;
+        
+        
+        INSERT INTO itemlocdist (
+                        itemlocdist_itemlocdist_id,
+                        itemlocdist_source_type,
+                        itemlocdist_source_id,
+                        itemlocdist_qty,
+                        itemlocdist_ls_id, itemlocdist_expiration
+                )
+                SELECT itemlocdist_id, 
+                        'L', 
+                        r_cmhead.cmhead_location_id, 
+                        itemlocdist_qty, 
+                        itemlocdist_ls_id,
+                        endOfTime()
+                FROM itemlocdist
+                WHERE (itemlocdist_id=r_invlocdist.itemlocdist_id);
+    
+        SELECT * INTO r_tmp FROM itemlocdist WHERE itemlocdist_itemlocdist_id = r_invlocdist.itemlocdist_id;
+    
+        RAISE NOTICE 'inserted %' , r_tmp;            
+    
+        SELECT distributeToLocations(r_invlocdist.itemlocdist_id)  INTO v_btmp;
+        RAISE NOTICE 'distributed %' ,v_btmp;            
+        
+    END LOOP;
+  RAISE NOTICE 'about to post';   
+    SELECT  postItemlocseries(v_itemlocSeries) INTO v_btmp;
+    
+    RAISE NOTICE 'posted: %', v_btmp;
+    
+    
+    
+    IF v_period_close_at_end > 0 THEN
+        PERFORM period_temp_open(v_period_close_at_end);
+    END IF;
+    
+    
+    --RAISE EXCEPTION 'not tested';
+    RETURN 1;
+
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  x_fix_chmead_missing_tx(integer)
+  OWNER TO admin;    
+
+
+
+--SELECT x_fix_chmead_missing_tx(315);
+SELECT x_fix_chmead_missing_tx(cmhead_id) FROM cmhead WHERE cmhead_posted AND NOT cmhead_void ;
diff --git a/pgsql/x-netsuite-balances.sql b/pgsql/x-netsuite-balances.sql
new file mode 100644 (file)
index 0000000..0b173a2
--- /dev/null
@@ -0,0 +1,35 @@
+
+CREATE SEQUENCE netsuite_balance_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE netsuite_balance_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE netsuite_balance_id_seq TO admin;
+GRANT ALL ON TABLE netsuite_balance_id_seq TO xtrole;
+
+
+CREATE TABLE netsuite_balance
+(
+    id integer NOT NULL DEFAULT nextval(('netsuite_balance_id_seq'::text)::regclass),
+    period_id integer,
+    accnt_id integer,
+    beginning numeric(14,2),
+    ending numeric(14,2),
+    hkd_beginning numeric(14,2),
+    hkd_ending numeric(14,2),
+    curr_id integer,
+     CONSTRAINT netsuite_balance_id_pkey PRIMARY KEY (id )
+)
+WITH (
+  OIDS=FALSE
+); 
+
+GRANT ALL ON TABLE netsuite_balance TO admin;
+GRANT ALL ON TABLE netsuite_balance TO xtrole;
+
+ALTER TABLE          netsuite_balance ADD COLUMN base_beginning  numeric(14,2);
+ALTER TABLE          netsuite_balance ADD COLUMN base_ending numeric(14,2);
+ALTER TABLE          netsuite_balance ADD COLUMN base_close numeric(14,2);
diff --git a/pgsql/x-netsuite-mig-extra.sql b/pgsql/x-netsuite-mig-extra.sql
new file mode 100644 (file)
index 0000000..45c93df
--- /dev/null
@@ -0,0 +1,69 @@
+
+
+--  extra cols to help migration.
+  
+ALTER TABLE cobmisc ADD COLUMN cobmisc_oldid INT;
+
+CREATE INDEX cobmisc_oldid_ix
+  ON cobmisc
+  USING btree
+  (cobmisc_oldid);
+
+ALTER TABLE invchead ADD COLUMN invchead_oldid INT;
+
+CREATE INDEX invchead_oldid_ix
+  ON invchead
+  USING btree
+  (invchead_oldid);
+
+
+
+
+-- maps to VendorBill.  
+alter table vohead add column vohead_oldid INT DEFAULT 0;
+CREATE INDEX vodist_oldid_ix
+  ON vodist
+  USING btree
+  (vodist_orig_id);
+  
+    
+  
+ALTER TABLE recv ADD COLUMN recv_oldid TEXT;
+CREATE INDEX recv_oldid_ix
+  ON recv 
+  USING btree
+  (recv_oldid);
+
+
+
+-- not sure why we did not use oldid here..
+
+alter table vodist add column vodist_orig_id INT DEFAULT 0;
+CREATE INDEX vodist_orig_id_ix
+  ON vodist
+  USING btree
+  (vodist_orig_id);
+
+-- add _oldid column to poreject table
+ALTER TABLE poreject
+ADD COLUMN poreject_oldid INTEGER DEFAULT 0;
+CREATE INDEX poreject_oldid_ix
+  ON poreject
+  USING btree
+  (poreject_oldid);
+ ALTER TABLE checkhead
+ADD COLUMN checkhead_oldid INTEGER DEFAULT 0;
+CREATE INDEX checkhead_oldid_ix
+  ON checkhead
+  USING btree
+  (checkhead_oldid);
+  
+  ALTER TABLE apselect
+ADD COLUMN apselect_oldid INTEGER DEFAULT 0;
+CREATE INDEX apselect_oldid_ix
+  ON apselect
+  USING btree
+  (apselect_oldid);
\ No newline at end of file
diff --git a/pgsql/x-netsuite-stock.sql b/pgsql/x-netsuite-stock.sql
new file mode 100644 (file)
index 0000000..91c1d17
--- /dev/null
@@ -0,0 +1,51 @@
+
+CREATE SEQUENCE netsuite_stock_id_seq
+  INCREMENT 1
+  MINVALUE 1
+  MAXVALUE 2147483647
+  START 1
+  CACHE 1;
+ALTER TABLE netsuite_stock_id_seq
+  OWNER TO admin;
+GRANT ALL ON TABLE netsuite_stock_id_seq TO admin;
+GRANT ALL ON TABLE netsuite_stock_id_seq TO xtrole;
+
+
+CREATE TABLE netsuite_stock
+(
+    id integer NOT NULL DEFAULT nextval(('netsuite_stock_id_seq'::text)::regclass),
+    trans_date date,
+    curr_id integer,
+    location_id integer,
+    item_id integer,
+    qty integer,
+    txref text,
+    txtype text,
+
+    amount numeric(14,2),
+    amount_hkd numeric(14,2),
+    CONSTRAINT netsuite_stock_id_pkey PRIMARY KEY (id )
+)
+WITH (
+  OIDS=FALSE
+); 
+
+GRANT ALL ON TABLE netsuite_stock TO admin;
+GRANT ALL ON TABLE netsuite_stock TO xtrole;
+
+ALTER TABLE  netsuite_stock ADD COLUMN   txline INTEGER DEFAULT 0;
+
+CREATE INDEX netsuite_stock_trans_date_indx
+  ON netsuite_stock
+  USING btree
+  (trans_date);
+  
+CREATE INDEX netsuite_stock_location_id_indx
+  ON netsuite_stock
+  USING btree
+  (location_id);
+
+CREATE INDEX netsuite_stock_item_id_indx
+  ON netsuite_stock
+  USING btree
+  (item_id);  
diff --git a/pgsql/x-timewarp-period-fill.sql b/pgsql/x-timewarp-period-fill.sql
new file mode 100644 (file)
index 0000000..32df447
--- /dev/null
@@ -0,0 +1,109 @@
+CREATE SCHEMA timewarp;
+
+CREATE OR REPLACE FUNCTION timewarp.period_fill_all()
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+
+BEGIN   
+
+    PERFORM  timewarp.period_fill(period_id) FROM (
+                    SELECT
+                            period_id
+                        FROM
+                            public.period
+
+                    ) x;
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   timewarp.period_fill_all()
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION timewarp.period_fill(integer)
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE
+    i_period_id  ALIAS FOR $1;
+
+    r_period RECORD;
+    r_periodview RECORD;
+
+    v_is_update BOOLEAN;
+
+BEGIN
+    
+    SELECT
+            *
+    INTO
+        r_period
+    FROM
+        timewarp.period
+    WHERE
+        period_id = i_period_id;
+
+    v_is_update := false;
+    -- already there..
+    IF FOUND THEN
+        v_is_update := true;
+    END IF;
+
+    SELECT
+        *
+    INTO
+        r_periodview
+    FROM
+        timewarp.periodview
+    WHERE
+        period_id = i_period_id;
+    
+    IF v_is_update THEN
+
+        UPDATE
+            timewarp.period
+        SET 
+            period_start   = r_periodview.period_start,
+            period_end     = r_periodview.period_end,
+            period_closed  = r_periodview.period_closed,
+            period_freeze  = r_periodview.period_freeze,
+            period_initial = r_periodview.period_initial,
+            period_name    = r_periodview.period_name,
+            period_yearperiod_id = r_periodview.period_yearperiod_id,
+            period_quarter = r_periodview.period_quarter,
+            period_number  = r_periodview.period_number
+             
+        WHERE
+            period_id = i_period_id;
+    
+    ELSE
+
+        INSERT INTO  timewarp.period (
+            period_id, period_start, 
+            period_end, period_closed, 
+            period_freeze, period_initial, 
+            period_name, period_yearperiod_id, 
+            period_quarter, period_number
+        ) VALUES  (
+            r_periodview.period_id, r_periodview.period_start, 
+            r_periodview.period_end, r_periodview.period_closed, 
+            r_periodview.period_freeze, r_periodview.period_initial, 
+            r_periodview.period_name, r_periodview.period_yearperiod_id, 
+            r_periodview.period_quarter, r_periodview.period_number
+            
+        );
+    END IF;
+    
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.period_fill(integer)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-timewarp-trialbal-fill.sql b/pgsql/x-timewarp-trialbal-fill.sql
new file mode 100644 (file)
index 0000000..6f48e38
--- /dev/null
@@ -0,0 +1,106 @@
+CREATE SCHEMA timewarp;
+
+CREATE OR REPLACE FUNCTION timewarp.trialbal_fill_all()
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+
+BEGIN   
+
+    PERFORM  timewarp.trialbal_fill(trialbal_id) FROM (
+                    SELECT
+                            trialbal_id
+                        FROM
+                            public.trialbal
+
+                    ) x;
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   timewarp.trialbal_fill_all()
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION timewarp.trialbal_fill(integer)
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE
+    i_trialbal_id  ALIAS FOR $1;
+
+    r_trialbal RECORD;
+    r_trialbalview RECORD;
+
+    v_is_update BOOLEAN;
+
+BEGIN
+    
+    SELECT
+        *
+    INTO
+        r_trialbal
+    FROM
+        timewarp.trialbal
+    WHERE
+        trialbal_id = i_trialbal_id;
+
+    v_is_update := false;
+    -- already there..
+    IF FOUND THEN
+        v_is_update := true;
+    END IF;
+
+    SELECT
+        *
+    INTO
+        r_trialbalview
+    FROM
+        timewarp.trialbalview
+    WHERE
+        trialbal_id = i_trialbal_id;
+    
+    IF v_is_update THEN
+
+        UPDATE
+            timewarp.trialbal
+        SET 
+            trialbal_period_id  =  r_trialbalview.trialbal_period_id,
+            trialbal_accnt_id   =  r_trialbalview.trialbal_accnt_id,
+            trialbal_beginning  =  r_trialbalview.trialbal_beginning,
+            trialbal_ending     =  r_trialbalview.trialbal_ending,
+            trialbal_credits    =  r_trialbalview.trialbal_credits,
+            trialbal_debits     =  r_trialbalview.trialbal_debits,
+            trialbal_dirty      =  r_trialbalview.trialbal_dirty,
+            trialbal_yearend    =  r_trialbalview.trialbal_yearend
+             
+        WHERE
+            trialbal_id = i_trialbal_id;
+    
+    ELSE
+
+        INSERT INTO  timewarp.trialbal (
+            trialbal_id,trialbal_period_id, 
+            trialbal_accnt_id, trialbal_beginning, 
+            trialbal_ending, trialbal_credits, 
+            trialbal_debits, trialbal_dirty, 
+            trialbal_yearend
+        ) VALUES  (
+            r_trialbalview.trialbal_id, r_trialbalview.trialbal_period_id, 
+            r_trialbalview.trialbal_accnt_id, r_trialbalview.trialbal_beginning, 
+            r_trialbalview.trialbal_ending, r_trialbalview.trialbal_credits, 
+            r_trialbalview.trialbal_debits, r_trialbalview.trialbal_dirty, 
+            r_trialbalview.trialbal_yearend
+        );
+    END IF;
+    
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.trialbal_fill(integer)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-timewarp-triggers.sql b/pgsql/x-timewarp-triggers.sql
new file mode 100644 (file)
index 0000000..b27831a
--- /dev/null
@@ -0,0 +1,118 @@
+CREATE SCHEMA timewarp;
+
+
+CREATE OR REPLACE FUNCTION timewarp.trialbaltrigger() RETURNS trigger 
+AS $BODY$
+DECLARE
+     v_tmp_id INT;
+BEGIN
+    
+    SELECT period_id INTO v_tmp_id  FROM timewarp.period LIMIT 1;
+    IF NOT FOUND THEN
+        RETURN NEW;
+    END IF;
+    
+    -- if there is no change in the trailbalance values, do not update the
+    IF (
+        (TG_OP = 'UPDATE')
+        AND
+        (OLD IS NOT NULL)
+        AND
+        (OLD.trialbal_beginning = NEW.trialbal_beginning)
+        AND
+        (OLD.trialbal_ending = NEW.trialbal_ending)
+        AND
+        (OLD.trialbal_credits = NEW.trialbal_credits)
+        AND
+        (OLD.trialbal_debits = NEW.trialbal_debits)
+    ) THEN
+        RETURN NEW;
+    END IF;
+        
+    
+    PERFORM timewarp.trialbal_fill(NEW.trialbal_id);
+      
+    RETURN NEW;   
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.trialbaltrigger()
+  OWNER TO admin;
+
+GRANT ALL ON FUNCTION timewarp.trialbaltrigger() TO xtrole;
+
+CREATE TRIGGER _trialbaltrigger 
+    AFTER INSERT OR UPDATE ON public.trialbal
+        FOR EACH ROW EXECUTE PROCEDURE timewarp.trialbaltrigger();
+
+
+-------- yearperiod----------------
+
+
+
+
+CREATE OR REPLACE FUNCTION timewarp.yearperiodtrigger() RETURNS trigger 
+AS $BODY$
+DECLARE
+     v_tmp_id INT;
+BEGIN
+    
+      SELECT period_id INTO v_tmp_id  FROM timewarp.period LIMIT 1;
+    IF NOT FOUND THEN
+        RETURN NEW;
+    END IF;
+    
+    
+    PERFORM timewarp.yearperiod_fill(NEW.yearperiod_id);
+      
+    RETURN NEW;   
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.yearperiodtrigger()
+  OWNER TO admin;
+
+
+GRANT ALL ON FUNCTION timewarp.yearperiodtrigger() TO xtrole;
+
+CREATE TRIGGER _yearperiodtrigger 
+    AFTER INSERT OR UPDATE ON public.yearperiod
+        FOR EACH ROW EXECUTE PROCEDURE timewarp.yearperiodtrigger();
+        
+
+---------------------- period--------------------------------------
+
+
+
+CREATE OR REPLACE FUNCTION timewarp.periodtrigger() RETURNS trigger 
+AS $BODY$
+DECLARE
+     v_tmp_id INT;
+BEGIN
+     SELECT period_id INTO v_tmp_id FROM timewarp.period LIMIT 1;
+    IF NOT FOUND THEN
+        RETURN NEW;
+    END IF;
+    
+    PERFORM timewarp.period_fill(NEW.period_id);
+      
+    RETURN NEW;   
+        
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.periodtrigger()
+  OWNER TO admin;
+GRANT ALL ON FUNCTION timewarp.periodtrigger() TO xtrole;
+
+CREATE TRIGGER _periodtrigger 
+    AFTER INSERT OR UPDATE ON public.period
+        FOR EACH ROW EXECUTE PROCEDURE timewarp.periodtrigger();
\ No newline at end of file
diff --git a/pgsql/x-timewarp-yearperiod-fill.sql b/pgsql/x-timewarp-yearperiod-fill.sql
new file mode 100644 (file)
index 0000000..5d30f88
--- /dev/null
@@ -0,0 +1,96 @@
+CREATE SCHEMA timewarp;
+
+CREATE OR REPLACE FUNCTION timewarp.yearperiod_fill_all()
+    RETURNS  boolean
+AS $BODY$
+DECLARE    
+
+BEGIN   
+
+    PERFORM  timewarp.yearperiod_fill(yearperiod_id) FROM (
+                    SELECT
+                            yearperiod_id
+                        FROM
+                            public.yearperiod
+
+                    ) x;
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION   timewarp.yearperiod_fill_all()
+  OWNER TO admin;
+
+
+CREATE OR REPLACE FUNCTION timewarp.yearperiod_fill(integer)
+    RETURNS  boolean
+
+AS $BODY$
+DECLARE
+    i_yearperiod_id  ALIAS FOR $1;
+
+    r_yearperiod RECORD;
+    r_yearperiodview RECORD;
+
+    v_is_update BOOLEAN;
+
+BEGIN
+    
+    SELECT
+            *
+    INTO
+        r_yearperiod
+    FROM
+        timewarp.yearperiod
+    WHERE
+        yearperiod_id = i_yearperiod_id;
+
+    v_is_update := false;
+    -- already there..
+    IF FOUND THEN
+        v_is_update := true;
+    END IF;
+
+    SELECT
+        *
+    INTO
+        r_yearperiodview
+    FROM
+        timewarp.yearperiodview
+    WHERE
+        yearperiod_id = i_yearperiod_id;
+    
+    IF v_is_update THEN
+
+        UPDATE
+            timewarp.yearperiod
+        SET 
+            yearperiod_start   =  r_yearperiodview.yearperiod_start,
+            yearperiod_end     =  r_yearperiodview.yearperiod_end,
+            yearperiod_closed  =  r_yearperiodview.yearperiod_closed
+             
+        WHERE
+            yearperiod_id = i_yearperiod_id;
+    
+    ELSE
+
+        INSERT INTO  timewarp.yearperiod (
+            yearperiod_id, yearperiod_start, 
+            yearperiod_end, yearperiod_closed
+        ) VALUES  (
+            r_yearperiodview.yearperiod_id, r_yearperiodview.yearperiod_start,
+            r_yearperiodview.yearperiod_end, r_yearperiodview.yearperiod_closed
+        );
+    END IF;
+    
+    RETURN true;
+END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.yearperiod_fill(integer)
+  OWNER TO admin;
\ No newline at end of file
diff --git a/pgsql/x-timewarp.sql b/pgsql/x-timewarp.sql
new file mode 100644 (file)
index 0000000..a6053f6
--- /dev/null
@@ -0,0 +1,333 @@
+
+
+
+
+
+-- The time warp schema is for reporting - to make SG accounts look like HK...
+
+-- DROP SCHEMA timewarp;
+-- SELECT timewarp.yearperiod_fill_all();
+-- SELECT timewarp.period_fill_all();
+-- SELECT timewarp.trialbal_fill_all();
+
+CREATE SCHEMA timewarp;
+
+
+DROP VIEW   IF EXISTS  timewarp.trialbal ;
+DROP VIEW IF EXISTS timewarp.period;
+DROP VIEW  IF EXISTS   timewarp.yearperiod ;
+
+
+
+DROP VIEW   IF EXISTS  timewarp.trialbalview ;
+DROP VIEW  IF EXISTS   timewarp.periodview;
+DROP VIEW  IF EXISTS   timewarp.yearperiodview ;
+
+
+-- flat copies..
+--CREATE OR REPLACE VIEW timewarp.accnt AS SELECT * FROM public.accnt;
+
+-- DROP BOTH togetyer!
+
+
+
+CREATE  VIEW timewarp.yearperiodview AS
+
+    SELECT
+         yearperiod_id ,
+         to_char(yearperiod_start , 'YYYY-05-DD')::date as yearperiod_start,
+         to_char(yearperiod_end  , 'YYYY-04-DD')::date as yearperiod_end,
+         yearperiod_closed    
+        FROM public.yearperiod;
+
+CREATE  VIEW timewarp.periodview AS
+
+    SELECT
+        period_id,
+        period_start,
+        period_end,
+        period_closed,
+        period_freeze,
+        period_initial,
+        period_name,
+        
+        (SELECT yearperiod_id FROM
+            timewarp.yearperiodview
+            WHERE
+            period_start >= yearperiod_start AND
+            period_start < yearperiod_end
+        LIMIT 1) as  period_yearperiod_id,
+        
+        floor((((period_number + 4) % 12) ) / 3) +1 as period_quarter ,
+        ((period_number + 4) % 12) +1 as period_number
+        
+    FROM
+        public.period;
+        
+
+
+-- SELECT * from yearperiod  ORDER BY yearperiod_start ASC;
+    
+
+
+
+-- find the qty available.. 
+CREATE OR REPLACE FUNCTION timewarp.trailbal_getvalue(integer, text, text)
+    RETURNS  numeric(20, 2) 
+    
+AS $BODY$
+DECLARE
+    i_accnt_id ALIAS FOR $1;
+    i_date ALIAS FOR $2;
+    i_b_or_e ALIAS FOR $3;
+    v_ret  numeric(20,2);
+      
+BEGIN
+       
+    SELECT
+            CASE WHEN i_b_or_e = 'E'
+                THEN trialbal_ending
+            ELSE
+                trialbal_beginning
+            END
+        INTO 
+            v_ret
+    
+        FROM
+            public.trialbal
+        LEFT JOIN
+            public.period
+        ON
+            trialbal_period_id = period_id
+        where
+            trialbal_accnt_id = i_accnt_id
+        AND
+            period_start = i_date::date;
+            
+    RETURN COALESCE(v_ret,0.0);
+            
+            END;
+$BODY$
+  LANGUAGE plpgsql VOLATILE
+  COST 100;
+  
+ALTER FUNCTION  timewarp.trailbal_getvalue(integer, text, text)
+  OWNER TO admin;
+          
+       
+
+-- trailbal..
+
+
+CREATE  VIEW timewarp.trialbalview AS
+
+    SELECT 
+    
+        trialbal_id,
+        trialbal_period_id,
+        trialbal_accnt_id ,
+        
+        -- begining and ending -- are the same for ASSETS and LIABILITIES
+        CASE
+            WHEN
+                accnt_type IN ('A','L')
+            THEN
+        
+                trialbal_beginning
+            WHEN
+                -- 05...09
+                to_char(period_start,'MM')::integer > 4 AND to_char(period_start,'MM')::integer < 10
+            THEN
+                --is value - (value at start 05)
+                trialbal_beginning -  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-05-01'), 'S')
+                  
+            
+            WHEN
+               --.. 09..12    
+                to_char(period_start,'MM')::integer > 8
+            
+            THEN
+                --is value + (value_end at same year 09)
+               trialbal_beginning +  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-09-01'), 'E')
+                 -  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-04-01'), 'E')
+                
+            ELSE 
+               --.. 01 .. 05
+               --is value + (value_end at previous year 09)
+               trialbal_beginning + timewarp.trailbal_getvalue(
+                        accnt_id,
+                        ((to_char(period_start, 'YYYY')::integer -1)  ||  '-09-01'),
+                        'E')
+               -  timewarp.trailbal_getvalue( accnt_id, ((to_char(period_start, 'YYYY')::integer -1)  ||  '-04-01'), 'E')
+               
+        END as trialbal_beginning,
+        
+        
+        CASE
+            WHEN
+                accnt_type IN ('A','L')
+            THEN
+                trialbal_ending
+            
+            WHEN
+                -- 05...09
+                to_char(period_start,'MM')::integer > 4 AND to_char(period_start,'MM')::integer < 10
+            THEN
+                --is value - (value at start 05)
+                trialbal_ending -  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-05-01'), 'S')
+            
+               -- otherwise
+            
+             WHEN
+                --.. 09..12
+                to_char(period_start,'MM')::integer > 8
+            THEN
+                --is value + (value_end at same year 09)
+                trialbal_ending +  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-09-01'), 'E')
+                 -  timewarp.trailbal_getvalue( accnt_id, to_char(period_start,'YYYY-04-01'), 'E')
+                
+            ELSE 
+               --.. 01 .. 05
+               --is value + (value_end at previous year 09)
+               trialbal_ending + timewarp.trailbal_getvalue(
+                        accnt_id,
+                        ((to_char(period_start, 'YYYY')::integer -1)  ||  '-09-01'),
+                        'E')
+                -  timewarp.trailbal_getvalue( accnt_id, ((to_char(period_start, 'YYYY')::integer -1)  ||  '-04-01'), 'E')
+        END as trialbal_ending,
+         
+        trialbal_credits ,
+        trialbal_debits ,
+        trialbal_dirty ,
+        
+        -- only 208 ?
+        -- FIXME -- this might need some more thought...
+        trialbal_yearend
+    
+    FROM
+        public.trialbal
+    LEFT JOIN
+        public.accnt
+    ON
+        trialbal_accnt_id = accnt_id
+    LEFT JOIN
+        public.period
+    ON
+        trialbal_period_id = period_id ;
+         
+--  -- slase id = 135   - type ='R'      
+--selecT
+--    trialbal_beginning,trialbal_ending, period_start
+--    from timewarp.trialbal LEFT JOIN period ON trialbal_period_id = period_id where trialbal_accnt_id = 135 order by period_start ASC;
+--
+--
+--   
+--selecT
+--    trialbal_beginning,trialbal_ending, period_start, trialbal_yearend
+--    from  trialbal LEFT JOIN period ON trialbal_period_id = period_id where trialbal_accnt_id = 208 order by period_start ASC;
+--
+
+
+DROP TABLE IF EXISTS timewarp.period;
+CREATE TABLE timewarp.period
+(
+    period_id integer NOT NULL,
+    period_start date,
+    period_end date,
+    period_closed boolean,
+    period_freeze boolean,
+    period_initial boolean DEFAULT false,
+    period_name text,
+    period_yearperiod_id integer,
+    period_quarter integer,
+    period_number integer NOT NULL
+)
+WITH (
+  OIDS=FALSE
+);
+
+ALTER TABLE timewarp.period
+  OWNER TO admin;
+GRANT ALL ON TABLE timewarp.period TO admin;
+GRANT ALL ON TABLE timewarp.period TO xtrole;
+COMMENT ON TABLE timewarp.period
+  IS 'Store financial reports Accounting Periods information.';
+
+
+DROP TABLE IF EXISTS timewarp.yearperiod;
+CREATE TABLE timewarp.yearperiod
+(
+    yearperiod_id integer NOT NULL,
+    yearperiod_start date NOT NULL,
+    yearperiod_end date NOT NULL,
+    yearperiod_closed boolean NOT NULL DEFAULT false
+)
+WITH (
+  OIDS=FALSE
+);
+ALTER TABLE timewarp.yearperiod
+  OWNER TO admin;
+GRANT ALL ON TABLE timewarp.yearperiod TO admin;
+GRANT ALL ON TABLE timewarp.yearperiod TO xtrole;
+COMMENT ON TABLE timewarp.yearperiod
+  IS 'Store financial reports Accounting Year Periods information.';
+
+DROP TABLE IF EXISTS timewarp.trialbal;
+CREATE TABLE timewarp.trialbal
+(
+    trialbal_id integer NOT NULL,
+    trialbal_period_id integer,
+    trialbal_accnt_id integer,
+    trialbal_beginning numeric(20,2),
+    trialbal_ending numeric(20,2),
+    trialbal_credits numeric(20,2),
+    trialbal_debits numeric(20,2),
+    trialbal_dirty boolean,
+    trialbal_yearend numeric(20,2) NOT NULL DEFAULT 0.00
+)
+WITH (
+  OIDS=FALSE
+);
+ALTER TABLE timewarp.trialbal
+  OWNER TO admin;
+GRANT ALL ON TABLE timewarp.trialbal TO admin;
+GRANT ALL ON TABLE timewarp.trialbal TO xtrole;
+COMMENT ON TABLE timewarp.trialbal
+  IS 'Store financial reports Trial Balance information.';
+
+   -- testing..
+--SET search_path TO timewarp,public;
+--SELECT * FROM public.financialReport(14 , ARRAY[ 112] , 'Y' , true, NULL )
+--
+
+GRANT ALL ON SCHEMA timewarp TO admin;
+GRANT ALL ON SCHEMA timewarp TO xtrole;   
+GRANT ALL ON  timewarp.trialbalview TO admin;
+GRANT ALL ON   timewarp.trialbalview TO xtrole;
+GRANT ALL ON  timewarp.periodview TO admin;
+GRANT ALL ON   timewarp.periodview TO xtrole;
+GRANT ALL ON  timewarp.yearperiodview TO admin;
+GRANT ALL ON   timewarp.yearperiodview TO xtrole;
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
diff --git a/pgsql/xtuple.apply.sh b/pgsql/xtuple.apply.sh
new file mode 100755 (executable)
index 0000000..e71f5aa
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+
+psql -Uadmin xtuplehk -f $1;
+psql -Uadmin xtuplecn -f $1;
+psql -Uadmin xtupleau -f $1;
+psql -Uadmin xtuplemy -f $1;
+psql -Uadmin xtuplesg -f $1;
+psql -Uadmin xtuplezh -f $1;
\ No newline at end of file
diff --git a/sqlreports/costest.sql b/sqlreports/costest.sql
new file mode 100644 (file)
index 0000000..796dcb3
--- /dev/null
@@ -0,0 +1,170 @@
+-- cost of sales test data.
+
+-- we should be looking at around 2M from this (which is probably the wrong value.)
+
+SELECT
+
+    FROM
+        invdetailview
+    LEFT JOIN
+        
+    
+    ON
+    
+    
+    WHERE
+        invhist_transdate >=  '2012-10-01'
+        AND
+        invhist_transdate <  '2012-11-01'
+        AND
+        invhist_ordtype IN ('SO', 'IN')
+    
+    
+    SELECT
+        count(distinct(invhist_id)),
+        sum(invfifo_totalcost)
+    FROM
+        invdetailview
+    
+    
+    WHERE
+        invhist_transdate >=  '2012-10-01'
+        AND
+        invhist_transdate <  '2012-11-01'
+        AND
+        invhist_ordtype   = 'SO';
+    -- 7586 txs
+    
+    
+    SELECT
+        count(distinct(invhist_id))
+    FROM
+        invdetailview
+    
+    
+    WHERE
+        invhist_transdate >=  '2012-10-01'
+        AND
+        invhist_transdate <  '2012-11-01'
+        AND
+        invhist_ordtype   = 'IN';
+    -- 23..
+    
+    
+selecT
+    gltrans_date,
+    sum(gltrans_amount)
+
+    from
+    gltrans
+    where
+        gltrans_accnt_id IN (149, 135)
+        AND
+            gltrans_date >=  '2012-10-01'
+        AND
+            gltrans_date <  '2012-11-01'
+    
+    GROUP BY
+        gltrans_date
+    ORDER BY
+        gltrans_date ASC;
+
+
+SELECT 
+    gltrans_date,
+    total_sales,
+    total_cost,
+    (ROUND( total_sales - total_cost) / total_cost, 2)
+    FROM
+    
+    (selecT
+        gltrans_date,
+        sum(gltrans_amount)  as total_sales,
+        (SELECT sum(gltrans_amount) FROM gltrans glt WHERE glt.gltrans_accnt_id = 149  AND
+                gltrans_date  =  gltrans.gltrans_date
+        )  * -1 as total_cost 
+        
+        
+        from
+        gltrans
+        where
+            gltrans_accnt_id IN (135)
+            AND
+                gltrans_date >=  '2012-10-01'
+            AND
+                gltrans_date <  '2012-11-01'
+        
+        GROUP BY
+            gltrans_date
+        ORDER BY
+            gltrans_date ASC
+    ) d;
+
+
+-- conclusion - COGS is based on fullfillment, and sales on invoices - so they do not match.
+
+-- to get a valid number we need to work out at the end of day
+
+-- what is the total value of proffit at the end of each day.......
+
+
+SELECT
+    to_char(invhist_transdate, 'YYYY-mm') as mth,
+
+    ROUND(sum(invhist_unitcost * invhist_invqty),2) as month_cost,
+    ROUND(sum(coitem_custprice * invhist_invqty),2) as month_sale,
+    ROUND(sum(coitem_custprice * invhist_invqty),2)  - ROUND(sum(invhist_unitcost * invhist_invqty),2) as month_profit
+    FROM
+        invdetailview
+    LEFT JOIN
+        (SELECT * FROM
+            coitem
+            LEFT JOIN
+                cohead
+            ON
+            cohead_id = coitem_cohead_id
+            
+        ) coi
+    ON
+        coi.cohead_number || '-' || coi.coitem_linenumber = invhist_ordnumber
+          OR
+        coi.cohead_number || '-' || coi.coitem_linenumber || '.' || coi.coitem_subnumber   = invhist_ordnumber
+    
+    
+    WHERE
+        invhist_transdate >=  '2012-01-01'
+        AND
+        invhist_transdate <  '2012-12-01'
+        AND
+        invhist_ordtype IN ('SO' )
+    GROUP BY to_char(invhist_transdate, 'YYYY-mm')
+    ORDER BY to_char(invhist_transdate, 'YYYY-mm') ASC
+        ;
+     
+    
+
+SELECT
+    
+    invhist_id,
+    ROUND(invhist_unitcost * invhist_invqty,2)  as line_cost,
+    ROUND(coitem_custprice * invhist_invqty,2) as line_sale,
+    ROUND(coitem_custprice * invhist_invqty,2)  - ROUND(invhist_unitcost * invhist_invqty,2) as line_profit
+    FROM
+        invdetailview
+    LEFT JOIN
+        coitem
+    ON
+        invdetail_invcitem_id = coitem_id
+    WHERE
+        invhist_transdate >=  '2012-11-01'
+        AND
+        invhist_transdate <  '2012-12-01'
+        AND
+        invhist_ordtype IN ('SO' )
+       
+        
+        ;
+     
+    209831 -- zero sale  (transtype = RS) - return from shipping..
+    210028 -- no cohead?
+    203213 -- big negative.. -- return..
diff --git a/sqlreports/perbrand.sql b/sqlreports/perbrand.sql
new file mode 100644 (file)
index 0000000..9c6b7fc
--- /dev/null
@@ -0,0 +1,73 @@
+
+-- this is proffit
+SELECT
+         
+        itemcharvalue(invcitem_item_id, 'BRAND')  AS rkey,
+        itemcharvalue(invcitem_item_id, 'BRAND') AS rkid,
+         
+        ROUND(sum(invcitem_billed),0) as qtysold,
+        ROUND(sum(
+        
+                invcitem_billed *
+                    currtocurr(
+                        invchead_curr_id,
+                        getcurrid('HKD'),
+                        invcitem_custprice ,
+                        invchead_invcdate
+                    )
+        ),0) as rvalue 
+         
+        FROM
+         
+            invcitem
+      
+         
+        LEFT JOIN
+            invchead
+        ON
+            invchead_id = invcitem_invchead_id
+        
+        
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+        
+        WHERE
+            
+            invchead_invcdate >= '$dateFrom'
+            AND
+            invchead_invcdate  <= '$dateUpto'
+            AND
+            invchead_void = false
+            AND
+            
+            '$country' = CASE
+                WHEN '$country' = '' THEN
+                    '$country'
+                WHEN (addr_country IS NULL OR addr_country = '') THEN
+                    'UNKNOWN'
+                ELSE 
+                    addr_country    
+                END 
+            
+        GROUP BY
+            rkey, rkid 
+            
+          ORDER BY
+             rvalue DESC
+        LIMIT 10
+    
\ No newline at end of file
diff --git a/sqlreports/percountry.sql b/sqlreports/percountry.sql
new file mode 100644 (file)
index 0000000..3280929
--- /dev/null
@@ -0,0 +1,59 @@
+ -- simple qty by country
+ SELECT
+        CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+            'UNKNOWN'
+        ELSE 
+            addr_country
+        END AS rkey,
+         
+        ROUND(sum(invcitem_billed),0) as qtysold,
+        ROUND(sum(invcitem_billed * currtocurr(invchead_curr_id, getcurrid('HKD'), invcitem_custprice, invchead_invcdate)),0) as rvalue 
+         
+        FROM
+         
+        invcitem
+      
+         
+        LEFT JOIN
+            invchead
+        ON
+            invchead_id = invcitem_invchead_id
+        
+       
+        
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+        
+        WHERE
+            
+            invchead_invcdate >= '$dateFrom'
+            AND
+            invchead_invcdate  <= '$dateUpto'
+            AND
+            invchead_void = false
+             AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+        GROUP BY
+            rkey 
+            
+        ORDER BY
+             rvalue DESC   
+        
diff --git a/sqlreports/perproduct.sql b/sqlreports/perproduct.sql
new file mode 100644 (file)
index 0000000..cdfd741
--- /dev/null
@@ -0,0 +1,79 @@
+
+-- this is proffit
+SELECT
+         
+        item_descrip1   AS rkey,
+        item_number AS rkid,
+         
+        ROUND(sum(invcitem_billed),0) as qtysold,
+        ROUND(sum(
+        
+                invcitem_billed *
+                    currtocurr(
+                        invchead_curr_id,
+                        getcurrid('HKD'),
+                        invcitem_custprice ,
+                        invchead_invcdate
+                    )
+        ),0) as rvalue 
+         
+        FROM
+         
+            invcitem
+      
+         
+        LEFT JOIN
+            invchead
+        ON
+            invchead_id = invcitem_invchead_id
+        
+         LEFT JOIN
+            item
+        ON
+            item_id = invcitem_item_id
+        
+       
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+        
+        WHERE
+            
+            invchead_invcdate >= '$dateFrom'
+            AND
+            invchead_invcdate  <= '$dateUpto'
+            AND
+            invchead_void = false
+            AND
+            
+            '$country' = CASE
+                WHEN '$country' = '' THEN
+                    '$country'
+                WHEN (addr_country IS NULL OR addr_country = '') THEN
+                    'UNKNOWN'
+                ELSE 
+                    addr_country    
+                END 
+             AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+        GROUP BY
+            rkey, rkid 
+            
+          ORDER BY
+             rvalue DESC
+        LIMIT 10
+    
\ No newline at end of file
diff --git a/sqlreports/profitbycustomer.sql b/sqlreports/profitbycustomer.sql
new file mode 100644 (file)
index 0000000..a607d9d
--- /dev/null
@@ -0,0 +1,79 @@
+ SELECT
+         
+        cust_name AS rkey,
+        cust_id AS rkid,
+         
+        ROUND(sum(invcitem_billed),0) as qtysold,
+        ROUND(sum(
+        
+                invcitem_billed * (
+                    currtocurr(
+                        invchead_curr_id,
+                        getcurrid('HKD'),
+                        invcitem_custprice ,
+                        invchead_invcdate
+                    ) -
+                    currtocurr(
+                        invchead_curr_id,
+                        basecurrid(),
+                        stdcost(invcitem_item_id) ,
+                        invchead_invcdate
+                    ) 
+                )
+        ),0) as rvalue 
+         
+        FROM
+         
+        invcitem
+      
+         
+        LEFT JOIN
+            invchead
+        ON
+            invchead_id = invcitem_invchead_id
+        
+       
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+        
+        WHERE
+            
+            invchead_invcdate >= '$dateFrom'
+            AND
+            invchead_invcdate  <= '$dateUpto'
+            AND
+            invchead_void = false
+            AND
+            
+            '$country' = CASE
+                WHEN '$country' = '' THEN
+                    '$country'
+                WHEN (addr_country IS NULL OR addr_country = '') THEN
+                    'UNKNOWN'
+                ELSE 
+                    addr_country    
+                END 
+             AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+        GROUP BY
+            rkey, rkid 
+            
+          ORDER BY
+             rvalue DESC
+        LIMIT 10
+    
\ No newline at end of file
diff --git a/sqlreports/revenuebycustomer.sql b/sqlreports/revenuebycustomer.sql
new file mode 100644 (file)
index 0000000..f87bdf8
--- /dev/null
@@ -0,0 +1,73 @@
+ SELECT
+         
+        cust_name AS rkey,
+        cust_id AS rkid,
+         
+        ROUND(sum(invcitem_billed),0) as qtysold,
+        ROUND(sum(
+        
+                invcitem_billed *
+                    currtocurr(
+                        invchead_curr_id,
+                        getcurrid('HKD'),
+                        invcitem_custprice,
+                        invchead_invcdate
+                    )
+        ),0) as rvalue 
+         
+        FROM
+         
+        invcitem
+      
+         
+        LEFT JOIN
+            invchead
+        ON
+            invchead_id = invcitem_invchead_id
+        
+      
+        
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+        
+        WHERE
+            
+            invchead_invcdate >= '$dateFrom'
+            AND
+            invchead_invcdate  <= '$dateUpto'
+            AND
+            invchead_void = false
+            AND
+            
+            '$country' = CASE
+                WHEN '$country' = '' THEN
+                    '$country'
+                WHEN (addr_country IS NULL OR addr_country = '') THEN
+                    'UNKNOWN'
+                ELSE 
+                    addr_country    
+                END 
+             AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+        GROUP BY
+            rkey, rkid 
+            
+          ORDER BY
+             rvalue DESC
+        LIMIT 10
+    
\ No newline at end of file
diff --git a/sqlreports/salescompare.sql b/sqlreports/salescompare.sql
new file mode 100644 (file)
index 0000000..93b85f6
--- /dev/null
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+-- there must be a better way to do this.......
+
+
+    
+    SELECT
+            itemcharvalue(item_id, 'BRAND') as item_brand,
+            itemcharvalue(item_id, 'PRODUCTCATEGORY') as item_productcategory,
+            item_number,
+            item_descrip1,
+            CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+                'UNKNOWN'
+            ELSE 
+                addr_country
+            END AS  cohist_country,
+            
+            ROUND( COALESCE(SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitprice, cohist_shipdate)),0),2) as ship_value,
+            ROUND(COALESCE(SUM(cohist_qtyshipped),0),0) as ship_qty
+            
+        FROM
+            cohist
+        LEFT JOIN
+            custinfo
+        ON
+            cust_id = cohist_cust_id
+            
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        LEFT JOIN
+            itemsite
+        ON
+            itemsite_id = cohist_itemsite_id
+        LEFT JOIN
+            item
+        ON
+            itemsite_item_id = item_id
+        WHERE
+            item_type = 'P' 
+        AND
+ --           (cohist_invcdate BETWEEN '$cStartDate' AND '$cEndDate')
+           (cohist_invcdate BETWEEN '2011-01-01' AND '2012-01-01') 
+       
+        GROUP BY
+            item_id,item_number,item_descrip1,addr_country
+          ORDER BY
+            item_number ASC;
+
+
+SELECT
+
+  
+    itemcharvalue(item_id, 'BRAND') as item_brand,
+    itemcharvalue(item_id, 'PRODUCTCATEGORY') as item_productcategory,
+    item_number,
+    item_descrip1,
+    
+    -- previous year qty sales
+    (SELECT
+            COALESCE(SUM(cohist_qtyshipped),0) 
+        FROM
+            cohist
+        WHERE
+             (cohist_itemsite_id = itemsite__id)
+        AND
+            (cohist_invcdate BETWEEN '$pStartDate' AND '$pEndDate')
+    )    as prev_totalship
+    
+    -- value
+    (SELECT
+        SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitprice, cohist_shipdate)) 
+    
+        FROM
+            cohist
+        WHERE
+             (cohist_itemsite_id = itemsite__id)
+        AND
+            (cohist_invcdate BETWEEN '$pStartDate' AND '$pEndDate')
+    )    as prev_totalsale
+    
+    -- countries
+    (SELECT
+            COALESCE(SUM(cohist_qtyshipped),0) 
+        FROM
+            cohist
+        LEFT JOIN
+            custinfo
+        ON
+            cust_id = cohist_cust_id
+            
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+           
+        
+         
+            
+        WHERE
+            (cohist_itemsite_id = itemsite__id)
+        AND
+            (cohist_invcdate BETWEEN '$cStartDate' AND '$cEndDate')
+        AND
+            CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+                'UNKNOWN'
+            ELSE 
+                addr_country
+            END = '$country'
+         
+    )    as cur_ship_{$country}
+   
+   (SELECT
+            SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitprice, cohist_shipdate)) 
+        FROM
+            cohist
+        LEFT JOIN
+            custinfo
+        ON
+            cust_id = cohist_cust_id
+            
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+           
+          
+            
+        WHERE
+            (cohist_itemsite_id = itemsite__id)
+        AND
+            (cohist_invcdate BETWEEN '$cStartDate' AND '$cEndDate')
+        AND
+            CASE WHEN (addr_country IS NULL OR addr_country = '') THEN
+                'UNKNOWN'
+            ELSE 
+                addr_country
+            END = '$country'
+         
+    )    as cur_total_{$country}
+   
+   
+   
+    
+    FROM
+        item
+    LEFT JOIN
+        itemsite
+    ON
+        itemsite_item_id = item_id
+    WHERE
+        item_type = 'P';
+     ORDER BY
+        item_number
+     
+        
+        
+
+  
\ No newline at end of file
diff --git a/sqlreports/salestrend.sql b/sqlreports/salestrend.sql
new file mode 100644 (file)
index 0000000..3e90464
--- /dev/null
@@ -0,0 +1,271 @@
+
+SELECT
+
+    period_start as rkey,
+    period_id as rid,
+    '$currency' as currency,
+      
+    
+     COALESCE((SELECT
+        
+         -- total invoiced value
+                   
+           ROUND(sum(invcitem_billed),0) as soldat_hkd  
+           
+          FROM
+           
+              invcitem
+         
+          LEFT JOIN
+              invchead
+          ON
+              invchead_id = invcitem_invchead_id
+          
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+           WHERE
+               
+            invchead_invcdate >= period_start
+              AND
+            invchead_invcdate <=  period_end
+            AND
+            invchead_void = false
+             AND
+                 '$country' = CASE
+                    WHEN '$country' = '' THEN
+                        '$country'
+                        
+                    WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        'UNKNOWN'
+                    ELSE 
+                        addr_country    
+                    END 
+            AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+                
+    ),0) as rvalue,
+    
+    
+    
+    COALESCE((SELECT
+        
+         -- total invoiced value
+                   
+           ROUND(sum(invcitem_billed *
+              currtocurr(
+                      invchead_curr_id,
+                      getcurrid('$currency'),
+                      invcitem_custprice,
+                      invchead_invcdate
+              )),0) as soldat_hkd  
+           
+          FROM
+           
+              invcitem
+         
+          LEFT JOIN
+              invchead
+          ON
+              invchead_id = invcitem_invchead_id
+          
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+           WHERE
+               
+              invchead_invcdate >= period_start
+              AND
+            invchead_invcdate <=  period_end
+            AND
+            invchead_void = false
+             AND
+                 '$country' = CASE
+                    WHEN '$country' = '' THEN
+                        '$country'
+                        
+                    WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        'UNKNOWN'
+                    ELSE 
+                        addr_country    
+                    END
+            AND
+             charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''   
+    ),0) as sales,
+    
+    COALESCE((SELECT
+        
+         -- total invoiced value
+                   
+           ROUND(sum(invcitem_billed *
+              currtocurr(
+                      invchead_curr_id,
+                      getcurrid('$currency'),
+                      invcitem_custprice,
+                      invchead_invcdate
+              )),0) as soldat_hkd  
+           
+          FROM
+           
+              invcitem
+         
+          LEFT JOIN
+              invchead
+          ON
+              invchead_id = invcitem_invchead_id
+          
+        
+        LEFT JOIN
+            custinfo
+        ON
+            invchead_cust_id = cust_id
+        
+        LEFT JOIN
+            cntct
+        ON
+            cntct_id = cust_cntct_id 
+        
+        LEFT JOIN
+            addr
+        ON
+            addr_id = cntct_addr_id 
+        
+        
+           WHERE
+               
+              invchead_invcdate >= period_start - INTERVAL '1 YEAR'
+              AND
+            invchead_invcdate <=  period_end - INTERVAL '1 YEAR'
+            AND
+            invchead_void = false
+             AND
+                 '$country' = CASE
+                    WHEN '$country' = '' THEN
+                        '$country'
+                        
+                    WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        'UNKNOWN'
+                    ELSE 
+                        addr_country    
+                    END 
+              AND
+             charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''     
+    ),0) as salespy,
+    
+    
+    
+    
+     COALESCE((SELECT
+        
+         -- total invoiced value
+                   
+           ROUND(sum(
+        
+                invcitem_billed *
+                    (
+                        currtocurr(
+                            invchead_curr_id,
+                            getcurrid('HKD'),
+                            invcitem_custprice ,
+                            invchead_invcdate
+                        ) -
+                        currtocurr(
+                            basecurrid(),
+                            getcurrid('HKD'),
+                            stdcost(invcitem_item_id) ,
+                            invchead_invcdate
+                        )
+                    
+                    )
+        ),0) as rvalue 
+         
+           
+          FROM
+           
+              invcitem
+         
+          LEFT JOIN
+              invchead
+          ON
+              invchead_id = invcitem_invchead_id
+          
+        
+            LEFT JOIN
+                custinfo
+            ON
+                invchead_cust_id = cust_id
+            
+            LEFT JOIN
+                cntct
+            ON
+                cntct_id = cust_cntct_id 
+            
+            LEFT JOIN
+                addr
+            ON
+                addr_id = cntct_addr_id 
+            
+            
+           WHERE
+               
+              invchead_invcdate >= period_start
+              AND
+            invchead_invcdate <=  period_end
+            AND
+            invchead_void = false
+             AND
+                 '$country' = CASE
+                    WHEN '$country' = '' THEN
+                        '$country'
+                        
+                    WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        'UNKNOWN'
+                    ELSE 
+                        addr_country    
+                    END 
+               AND
+             charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''    
+    ),0) as profit
+    
+        
+    
+    
+    FROM
+        period
+    WHERE
+        period_start >= '$dateFrom'
+        AND
+        period_start  <  '$dateUpto'
+    ORDER BY
+        period_start ASC
+        
+        
+        
\ No newline at end of file
diff --git a/sqlreports/slowmoving.sql b/sqlreports/slowmoving.sql
new file mode 100644 (file)
index 0000000..efa25ba
--- /dev/null
@@ -0,0 +1,126 @@
+
+--- concept is to find the slow moving stock.
+
+
+-- a find the average product sales for the last 3 months.
+
+SELECT
+    rkey,
+    rkid,
+    rvalue,
+    cstock,
+    avsales
+FROM
+    (SELECT
+
+            item_descrip1   AS rkey,
+            item_number AS rkid,
+
+            --(SELECT
+            --            COALESCE(SUM(loccurbal_ending),0)
+            --        FROM
+            --            loccurbal
+            --        LEFT JOIN
+            --            location
+            --        ON
+            --            location_id = loccurbal_location_id
+            --        WHERE
+            --            loccurbal_itemsite_id = itemsite_id
+            --            and
+            --            location_name NOT LIKE 'Import Goods%'
+            --)
+              (SELECT
+                         COALESCE(SUM(itemloc_qty),0)
+                     FROM
+                         itemloc
+                     LEFT JOIN
+                         location
+                     ON
+                         location_id = itemloc_location_id
+
+                     WHERE
+                         itemloc_itemsite_id = itemsite_id
+                         and
+                         location_name NOT LIKE 'Import Goods%'
+                         AND
+                        '' =  charass_getvalue('C', location_cust_id,'INTERNALCOMPANY')
+             )
+
+
+                /
+            (
+                CASE WHEN ( sum(invcitem_billed) / 3  ) > 0 THEN
+                    ( sum(invcitem_billed) / 3  ) 
+                ELSE
+                    0.01
+                END
+            )
+                as rvalue,
+            (SELECT
+                         COALESCE(SUM(itemloc_qty),0)
+                     FROM
+                         itemloc
+                     LEFT JOIN
+                         location
+                     ON
+                         location_id = itemloc_location_id
+                     WHERE
+                         itemloc_itemsite_id = itemsite_id
+                         and
+                         location_name NOT LIKE 'Import Goods%'
+                            AND
+                        '' =  charass_getvalue('C', location_cust_id,'INTERNALCOMPANY')
+             ) as cstock,
+
+             (
+                CASE WHEN ( sum(invcitem_billed) / 3  ) > 0 THEN
+                    ( sum(invcitem_billed) / 3  ) 
+                ELSE
+                    0.01
+                END
+            )
+                as avsales
+            FROM
+
+                invcitem
+
+
+            LEFT JOIN
+                invchead
+            ON
+                invchead_id = invcitem_invchead_id
+
+             LEFT JOIN
+                item
+            ON
+                item_id = invcitem_item_id
+
+            LEFT JOIN
+                itemsite
+            ON
+                itemsite_item_id = invcitem_item_id
+
+
+
+
+            WHERE
+
+                invchead_invcdate >= NOW() - INTERVAL '3 MONTHS'
+                AND
+                invchead_invcdate  <= NOW()
+                AND
+                invchead_void = false
+
+            GROUP BY
+                rkey, rkid ,itemsite_id
+
+           ORDER BY
+                rvalue DESC
+    ) AS data
+
+WHERE 
+    rvalue >=0
+    AND
+    cstock > 0
+LIMIT 30
+;
\ No newline at end of file
diff --git a/sqlreports/summary.sql b/sqlreports/summary.sql
new file mode 100644 (file)
index 0000000..46388f6
--- /dev/null
@@ -0,0 +1,52 @@
+-- general summary..
+-- a) total sales in this period.
+-- IN HK we probalby need to ignore sales to SG??
+  
+      SELECT
+          
+                     
+            ROUND(sum(invcitem_billed),0) as qtysold,
+            ROUND(sum(invcitem_billed * currtocurr(invchead_curr_id, getcurrid('HKD'), invcitem_custprice, invchead_invcdate)),0) as soldat_hkd 
+             
+            FROM
+             
+            invcitem
+          
+             
+            LEFT JOIN
+                invchead
+            ON
+                invchead_id = invcitem_invchead_id
+            
+           
+            
+            
+            LEFT JOIN
+                custinfo
+            ON
+                invchead_cust_id = cust_id
+            
+            LEFT JOIN
+                cntct
+            ON
+                cntct_id = cust_cntct_id 
+            
+            LEFT JOIN
+                addr
+            ON
+                addr_id = cntct_addr_id 
+            
+            
+            
+            WHERE
+                 
+                invchead_invcdate >= '$dateFrom'
+                AND
+                invchead_invcdate  <= '$dateUpto'
+                AND
+                invchead_void = false
+                AND
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+                 
\ No newline at end of file
diff --git a/sqlreports/totals.sql b/sqlreports/totals.sql
new file mode 100644 (file)
index 0000000..197c408
--- /dev/null
@@ -0,0 +1,258 @@
+-- general summary..
+-- a) total sales in this period.
+-- IN HK we probalby need to ignore sales to SG??
+  
+      SELECT
+           -- total invoiced value
+            CASE WHEN '$showExtra' = 0 THEN
+                ''
+            ELSE
+                CASE WHEN '$notmg' = 0 THEN
+                    ' - Online'
+                ELSE
+                    ' - Trade'
+                END
+            END AS total_type,
+            ROUND(sum(invcitem_billed),0) as qtysold,
+            ROUND(sum(invcitem_billed *
+                currtocurr(
+                        invchead_curr_id,
+                        getcurrid('$currency'),
+                        invcitem_custprice,
+                        invchead_invcdate
+                )),0) as soldat_hkd ,
+            
+            
+            -- ideally we need uninvoiced value.
+            --(SELECT 
+            --        ROUND(sum(
+            --            currtocurr(
+            --                cohead_curr_id,
+            --                getcurrid('$currency'),
+            --                calcsalesordersubtotal(cohead_id)  - calcsalesordershipped(cohead_id)     - calcsalesorderunshipable(cohead_id),
+            --                (select max(invchead_invcdate) FROM invchead WHERE invchead_ordernumber = cohead_number AND  invchead_void = false)
+            --            )
+            --        ),2)
+            --    FROM
+            --        cohead
+            --    WHERE
+            --        cohead_status = 'O'
+            --        AND
+            --        cohead_number IN (SELECT
+            --                invchead_ordernumber
+            --            FROM 
+            --                invchead
+            --    
+            --            WHERE    
+            --                invchead_invcdate >= '$dateFrom'
+            --                AND
+            --                invchead_invcdate  <  '$dateUpto'
+            --                AND
+            --                invchead_void = false
+            --        )
+            --        
+            --) as unshipped,
+            --
+            --(SELECT 
+            --        ROUND(sum(
+            --            currtocurr(
+            --                cohead_curr_id,
+            --                getcurrid('$currency'),
+            --                calcsalesordersubtotal(cohead_id::integer)  - calcsalesorderinvoiced(cohead_id::integer) ,
+            --                (select max(shiphead_shipdate) FROM shiphead WHERE shiphead_order_id = cohead_id)
+            --            )
+            --        ),2)
+            --    FROM
+            --        cohead
+            --    WHERE
+            --        cohead_status = 'O'
+            --        AND
+            --        cohead_id IN (
+            --            SELECT  shiphead_order_id  FROM  shiphead WHERE    
+            --                shiphead_shipdate >= '$dateFrom'
+            --                AND
+            --                shiphead_shipdate  <  '$dateUpto'
+            --        )
+            --        
+            --) as uninvoiced,
+            
+            
+            
+            --    
+            --(SELECT      
+            --        ROUND(SUM(currtocurr(
+            --            baseCurrId(),
+            --            getcurrid('$currency'),
+            --            ( CASE WHEN accnt_type IN ( 'A') THEN  
+            --                       (trialbal_ending -  trialbal_beginning)   * -1
+            --                ELSE 
+            --                       trialbal_ending -  trialbal_beginning 
+            --                END ),
+            --            period_end
+            --        )),0)
+            --     
+            --    FROM
+            --        trialbal
+            --    LEFT JOIN
+            --        period
+            --    ON
+            --        period_id = trialbal_period_id
+            --    LEFT JOIN
+            --        accnt
+            --    ON
+            --        accnt_id = trialbal_accnt_id
+            --    
+            --    WHERE
+            --        accnt_type = 'E'
+            --    AND 
+            --            
+            --            period_start >= '$dateFrom'
+            --        AND
+            --            period_end  < '$dateUpto'
+            --             
+            --    
+            --) * -1 as expenses_hkd,
+            --
+            --
+            --
+            -- (SELECT      
+            --        ROUND(SUM(currtocurr(
+            --            baseCurrId(),
+            --            getcurrid('$currency' ),
+            --            ( CASE WHEN accnt_type IN ( 'A') THEN  
+            --                       (trialbal_ending -  trialbal_beginning)   * -1
+            --                ELSE 
+            --                       trialbal_ending -  trialbal_beginning 
+            --                END ),
+            --            period_end
+            --        )),0)
+            --     
+            --    FROM
+            --        trialbal
+            --    LEFT JOIN
+            --        period
+            --    ON
+            --        period_id = trialbal_period_id
+            --    LEFT JOIN
+            --        accnt
+            --    ON
+            --        accnt_id = trialbal_accnt_id
+            --    
+            --    WHERE
+            --        accnt_type = 'R'
+            --    AND 
+            --            
+            --            period_start >= '$dateFrom'
+            --        AND
+            --            period_end  < '$dateUpto'
+            --            
+            --
+            --                   
+            --    
+            --) as revenue_hkd,
+            --
+            
+            
+            
+            
+             (SELECT      
+                    ROUND(SUM(currtocurr(
+                        baseCurrId(),
+                        getcurrid('$currency' ),
+                        ( CASE WHEN accnt_type IN ( 'A') THEN  
+                                   (trialbal_ending -  trialbal_beginning)   * -1
+                            ELSE 
+                                   trialbal_ending -  trialbal_beginning 
+                            END ),
+                        period_end
+                    )),0)
+                 
+                FROM
+                    trialbal
+                LEFT JOIN
+                    period
+                ON
+                    period_id = trialbal_period_id
+                LEFT JOIN
+                    accnt
+                ON
+                    accnt_id = trialbal_accnt_id
+                
+                WHERE
+                    accnt_type IN ('R', 'E')
+                AND 
+                        
+                        period_start >= '$dateFrom'
+                    AND
+                        period_end  <= '$dateUpto'
+                        
+            
+                               
+                
+            ) as net_profit_hkd,
+            '$currency' as currency
+            
+            
+             
+            FROM
+             
+                invcitem
+          
+             
+            LEFT JOIN
+                invchead
+            ON
+                invchead_id = invcitem_invchead_id
+            
+            
+            LEFT JOIN
+                custinfo
+            ON
+                invchead_cust_id = cust_id
+            
+            LEFT JOIN
+                cntct
+            ON
+                cntct_id = cust_cntct_id 
+            
+            LEFT JOIN
+                addr
+            ON
+                addr_id = cntct_addr_id 
+            
+            
+            
+            WHERE   
+                CASE WHEN '$showExtra' = 0 THEN
+                    TRUE
+                ELSE
+                    CASE WHEN '$notmg' = 0 THEN
+                        invchead_ordernumber LIKE 'MG%'
+                    ELSE
+                        invchead_ordernumber NOT LIKE 'MG%'
+                    END
+                END
+                AND
+                invchead_invcdate >= '$dateFrom'
+                AND
+                invchead_invcdate  <  '$dateUpto'
+                AND
+                invchead_void = false
+                AND
+                '$country' = CASE
+                    WHEN '$country' = '' THEN
+                        '$country'
+                        
+                    WHEN (addr_country IS NULL OR addr_country = '') THEN
+                        'UNKNOWN'
+                    ELSE 
+                        addr_country    
+                    END 
+                 AND
+                
+                charass_getvalue('C', cust_id, 'INTERNALCOMPANY') = ''
+                
+                
+                 
\ No newline at end of file
diff --git a/templates/images/logo.gif b/templates/images/logo.gif
new file mode 100644 (file)
index 0000000..a9ea153
Binary files /dev/null and b/templates/images/logo.gif differ
diff --git a/templates/images/logo_small.gif b/templates/images/logo_small.gif
new file mode 100644 (file)
index 0000000..f9bfc6a
Binary files /dev/null and b/templates/images/logo_small.gif differ
diff --git a/templates/mail/AccountCheckEmail.txt b/templates/mail/AccountCheckEmail.txt
new file mode 100644 (file)
index 0000000..449f28f
--- /dev/null
@@ -0,0 +1,172 @@
+From: "Dragon" <dragon@bloomandgrowdirect.com>
+To: {t.person}
+Subject: {t.data.subject}
+Content-Type: text/html; charset="utf-8"
+
+<table border="1" style="width:500px;">
+<tr>
+<td colspan="3">AR Comparison ( Date : {t.date} , Currency : {t.data.baseCurr} )</td>
+<tr/>
+<tr>
+<td colspan="3">GL = (AR - Customer Deposits)</td>
+<tr/>
+<tr align="center">
+<td>GL</td><td>AR</td><td>DIFF</td>
+<tr/>
+<tr align="right">
+<td>{t.data.aropen.gltrans_total_val}</td><td>{t.data.aropen.araging_total_val}</td><td>{t.data.aropen.ar_diff}</td>
+<tr/>
+</table>
+
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="3">AP Comparison ( Date : {t.date} , Currency : {t.data.baseCurr} )</td>
+<tr/>
+<tr align="center">
+<td>GL</td><td>AP</td><td>DIFF</td>
+<tr/>
+<tr align="right">
+<td>{t.data.apopen.gltrans_total_val}</td><td>{t.data.apopen.apaging_total_val}</td><td>{t.data.apopen.ap_diff}</td>
+<tr/>
+</table>
+
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="3">Stock Comparison ( Date : {t.date} , Currency : {t.data.baseCurr} )</td>
+<tr/>
+<tr align="center">
+<td>GL</td><td>Inventory</td><td>DIFF</td>
+<tr/>
+<tr align="right">
+<td>{t.data.stock.gltrans_total_val}</td><td>{t.data.stock.stock_total_val}</td><td>{t.data.stock.stock_diff}</td>
+<tr/>
+</table>
+
+
+{if:t.data.fifoVoidCheck}
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="3">Stock miscalucation Problems ( Date : {t.date} )</td>
+<tr/>
+<tr align="center">
+<td>Item</td><td>qty (with void)</td><td>qty</td>
+<tr/>
+
+{foreach:t.data.fifoVoidCheck,co}
+<tr  align="right">
+    <td>{co.item_number}</td>
+    <td>{co.stock_with_void}</td>
+    <td>{co.stock_all}</td>
+<tr/>
+{end:}
+</table>
+{end:}
+
+{if:t.data.fifoCohead}
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="3">FIFO Problems ( Date : {t.date} )</td>
+<tr/>
+<tr align="center">
+<td>Doc</td><td>order date</td><td>Value</td>
+<tr/>
+
+{foreach:t.data.fifoCohead,co}
+<tr  align="right">
+    <td>{co.cohead_number}</td>
+    <td>{co.cohead_orderdate}</td>
+    <td>{co.cohead_total}</td>
+<tr/>
+{end:}
+</table>
+{end:} 
+  
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="4">Top 10 profitable sales in last 3 months ( Currency : {t.data.baseCurr} )</td>
+<tr/>
+<tr align="center">
+<td>Docnumber</td><td>Profit</td><td>Sale</td><td>COGS</td>
+<tr/>
+{foreach:t.data.highProfit,a}
+<tr align="left">
+<td>{a.docnumber}</td><td align="right">{a.profit}%</td><td align="right">{a.sale_value}</td><td align="right">{a.sale_cost}</td>
+</tr>
+{end:}
+</table>
+
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="4">List top 10 Worst Profit Sales in last 3 months ( Currency : {t.data.baseCurr} )</td>
+<tr/>
+<tr align="center">
+<td>Docnumber</td><td>Profit</td><td>Sale</td><td>COGS</td>
+<tr/>
+{foreach:t.data.lowProfit,a}
+<tr align="left">
+<td>{a.docnumber}</td><td align="right">{a.profit}%</td><td align="right">{a.sale_value}</td><td align="right">{a.sale_cost}</td>
+</tr>
+{end:}
+</table>
+
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="2">Top 10 Sales where Sold price is $0 in last 3 months ( Currency : {t.data.baseCurr} )</td>
+<tr/>
+
+<tr align="center">
+<td>Docnumber</td><td>COGS</td>
+<tr/>
+{foreach:t.data.zeroProfit,a}
+<tr align="left">
+<td>{a.docnumber}</td>
+<td align="right">{a.sale_cost}</td>
+</tr>
+{end:}
+</table>
+
+
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="6">Highest landed cost in last year ( Currency : {t.data.baseCurr} )</td>
+<tr/>
+
+<tr align="center">
+    <td>Ordered</td>
+    <td>Docnumber</td>
+    <td>Value</td>
+    <td>Landed cost</td>
+    <td>Percentage</td>
+    <td>Vouchers applied</td>
+<tr/>
+{foreach:t.data.landedCost,a}
+<tr align="left">
+    <td>{a.pohead_orderdate}</td>
+    <td>{a.pohead_number}</td>
+    <td align="right">{a.pohead_val}</td>
+    <td align="right">{a.landed_cost}</td>
+    <td align="right">{a.expense}%</td>
+    <td align="left">{a.voucher_numbers}</td>
+</tr>
+{end:}
+</table>
+
+{if:t.data.neverBought}
+<table border="1" style = "margin-top:50px;width:500px;">
+<tr>
+<td colspan="2">List of product that have been sold, but never have been bought in the last month</td>
+<tr/>
+<tr align="center">
+<td>Item Number</td>
+<td>Sales Orders</td>
+<tr/>
+{foreach:t.data.neverBought,a}
+<tr align="left">
+<td>{a.item_number}</td>
+<td>{a.order_numbers}</td>
+</tr>
+{end:}
+</table>
+{end:}
+
diff --git a/templates/master.html b/templates/master.html
new file mode 100644 (file)
index 0000000..fb9ccfb
--- /dev/null
@@ -0,0 +1,180 @@
+<!DOCTYPE html 
+      PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
+<html xmlns="http://www.w3.org/1999/xhtml" 
+      xmlns:html="http://www.w3.org/1999/xhtml" 
+      xmlns:svg="http://www.w3.org/2000/svg"
+      xmlns:xlink="http://www.w3.org/1999/xlink"> 
+    <head>
+        <title>{appName}</title>
+        <meta name="google" value="notranslate">
+        <link rel="shortcut icon" href="./Pman.ico" type="image/vnd.microsoft.icon"/>
+        
+        
+        <link rel="stylesheet" type="text/css" href="{rootURL}/roojs1/css/roojs.css" />  
+        <link rel="stylesheet" type="text/css" href="{rootURL}/roojs1/css/xtheme-slate.css" />  
+        
+        {outputCSSIncludes()}
+                     
+   
+    <style>
+     #loading-logo-bottom,
+     #loading-logo-center,
+     #loading-logo-tile,
+     #loading-logo-tile-top
+     {
+        width:100%;
+        height:100%;
+        position:absolute;
+       
+        left:0;
+        top:0;
+        background-position:50% 50%;
+    }
+    
+    /* background-tile.jpg */
+    #loading-logo-tile {
+         z-index:1000;
+    }
+    
+    /* background.jpg */
+    #loading-logo-center
+    {
+        background-position:50% 0;
+        background-repeat:no-repeat; 
+        z-index:1001;
+    }
+    /* background-tile-top.jpg */
+    #loading-logo-tile-top
+    {
+        background-position:50% 0;
+        z-index:1002;
+        background-repeat:repeat-x; 
+        
+    }
+    /* background_bottom_logo.gif */
+    #loading-logo-bottom
+    {
+        background-position:50% 100%;
+        background-repeat:no-repeat; 
+        z-index:1003;
+    }
+    </style>
+     </head>
+    <body class="ytheme-gray">  
+         <!--background:#F8ECB2;-->   
+        <div flexy:if="hasBg(#background-tile.jpg#)" 
+            id="loading-logo-tile"
+            style="background-image:url({rootURL}/Pman/{appNameShort}/templates/images/background-tile.jpg);"></div>
+        
+        <div flexy:if="hasBg(#background-tile-top.jpg#)"  
+            id="loading-logo-tile-top"
+            style="background-image:url({rootURL}/Pman/{appNameShort}/templates/images/background-tile-top.jpg);"></div>
+        
+        <div flexy:if="hasBg(#background.jpg#)" 
+            id="loading-logo-center"
+            style="background-image:url({rootURL}/Pman/{appNameShort}/templates/images/background.jpg);"></div>
+        
+        <div flexy:if="hasBg(#background_bottom_logo.gif#)" 
+            id="loading-logo-bottom"
+            style="background-image:url({rootURL}/Pman/{appNameShort}/templates/images/background_bottom_logo.gif);"></div>
+        
+        
+        <div id="loading-mask"
+            style="width:1;height:1;position:absolute;z-index:1000;left:0;top:0;">&#160;</div>
+        <div id="loading">
+            <div class="loading-indicator" id="loading-text">&#160;Loading...(This may take a few seconds)</div>
+        </div>
+       
+        
+{if:bootLoader.Pman[roo_debug]}                  
+        <script type="text/javascript" src="{rootURL}/roojs1/roojs-debug.js?ts={version}"></script>
+        <!-- <script type="text/javascript" src="{rootURL}/roojs1/ux/Iscroll.js"></script>  -->
+         
+{else:}                  
+        <script type="text/javascript" src="{rootURL}/roojs1/roojs-all.js?ts={version}"></script>
+                 
+{end:}
+
+    <script type="text/javascript" src="{rootURL}/raphael/raphael.js"></script>
+    <script type="text/javascript" src="{rootURL}/raphael/plugins/raphael.export.js"></script> 
+    <script type="text/javascript" src="{rootURL}/g.raphael/g.raphael.js"></script>
+    <script type="text/javascript" src="{rootURL}/g.raphael/g.pie.js"></script>
+    <script type="text/javascript" src="{rootURL}/g.raphael/g.bar.js"></script>
+    <script type="text/javascript" src="{rootURL}/g.raphael/g.line.js"></script>
+     <!-- testing password bug only -->
+    <script type="text/javascript" src="{rootURL}/roojs1/Roo/form/TextField.js"></script>
+
+
+
+        <flexy:toJSON 
+            baseURL="baseURL" 
+            rootURL="rootURL" 
+            isDev="isDev"
+            serverName="serverName" 
+            appLang="lang"
+            appName="appName"
+            appNameShort="appNameShort"
+            appLogo="appLogo"
+            appOwnerCompanyId="company.id"
+             
+            AppLinkError="linkFail"
+            AppTrackOnLoad="onloadTrack"
+            
+            showNewPass="showNewPass"
+            allowSignup="allowSignup"
+            
+            logoPrefix="logoPrefix"
+            
+            AppModules="appModules"
+            AppVersion="appVersion"
+            appDisabled="appDisabled"
+            uiConfig="uiConfig"
+          
+        ></flexy:toJSON>
+        
+        
+        <script type="text/javascript">
+            Ext=Roo; // bc
+            Roo.BLANK_IMAGE_URL =  rootURL + "/roojs1/images/gray/s.gif";
+            Roo.rootURL = rootURL +'/roojs1/';
+        </script>
+        
+        {outputJavascriptIncludes()}
+             
+        <!-- used by App.php in Builder - to enable loading of code/applicaiton on the fly -->
+        {foreach:builderJs,js}
+            <script type="text/javascript" src="{baseURL}/Builder/Code/{js}.js"></script>    
+        {end:} 
+           
+           
+           
+           
+        <!-- finally language.. -->   
+        <script type="text/javascript" src="{baseURL}/Core/I18n.js"></script>
+               
+               
+        <script type="text/javascript">
+            Pman.debug = true;
+        </script>
+               
+               
+        <div id="title" class="x-layout-inactive-content logoblock">
+            <img id="headerInformation-company-logo" 
+                src="{rootURL}/Pman/{appNameShort}/templates/images/logo_small.gif" height="25"/>
+            <div id="headerInformation">Some other details</div>
+            <img id="headerInformation-applogo" 
+                src="{rootURL}/Pman/{appNameShort}/templates/images/logo_small.gif" height="25"/>
+            
+        </div>
+         
+          
+           
+        <div id="mainlist" class="x-layout-inactive-content">
+            <p>main body</p>
+                
+        </div>
+          
+    </body>
+</html>
+        
\ No newline at end of file