protected ContractProcessing(int? contractID) { if (contractID > 0) { this.graph = PXGraph.CreateInstance<ARInvoiceEntry>(); graph.FieldVerifying.AddHandler<ARInvoice.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); this.contract = PXSelect<Contract, Where<Contract.contractID, Equal<Required<Contract.contractID>>>>.Select(graph, contractID); this.insetup = PXSelect<INSetup>.Select(graph); this.template = PXSelect<Contract, Where<Contract.contractID, Equal<Required<Contract.contractID>>>>.Select(graph, contract.TemplateID); this.schedule = PXSelect<ContractBillingSchedule>.Search<ContractBillingSchedule.contractID>(graph, contract.ContractID); if (contract.CustomerID != null) { if (schedule != null && schedule.AccountID != null) { customer = PXSelect<Customer, Where<Customer.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>>>.Select(graph, schedule.AccountID); if (schedule.LocationID != null) { location = PXSelect<Location, Where<Location.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>, And<Location.locationID, Equal<Required<ContractBillingSchedule.locationID>>>>>.Select(graph, customer.BAccountID, schedule.LocationID); } else { location = PXSelect<Location, Where<Location.locationID, Equal<Required<Customer.defLocationID>>>>.Select(graph, customer.DefLocationID); } } else { customer = PXSelect<Customer, Where<Customer.bAccountID, Equal<Required<Customer.bAccountID>>>>.Select(graph, contract.CustomerID); if (contract.LocationID != null) { location = PXSelect<Location, Where<Location.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>, And<Location.locationID, Equal<Required<ContractBillingSchedule.locationID>>>>>.Select(graph, customer.BAccountID, contract.LocationID); } else { location = PXSelect<Location, Where<Location.locationID, Equal<Required<Customer.defLocationID>>>>.Select(graph, customer.DefLocationID); } } } SetupGraph(); } }
public virtual void InvoiceOrder(DateTime invoiceDate, PXResult<SOOrderShipment, SOOrder, CurrencyInfo, SOAddress, SOContact, SOOrderType> order, PXResultset<SOShipLine, SOLine> details, Customer customer, DocumentList<ARInvoice, SOInvoice> list) { ARInvoice newdoc; SOOrder soOrder = order; SOOrderType ordertype = order; decimal ApprovedBalance = 0; decimal PrevDocBal = 0; PXRowUpdated ApprovedBalanceCollector = delegate(PXCache sender, PXRowUpdatedEventArgs e) { ARInvoice ARDoc = (ARInvoice)e.Row; if ((decimal)ARDoc.DocBal > (decimal)ARDoc.ApprovedCreditAmt) { if ((bool)((SOOrder)order).ApprovedCredit && (decimal)ARDoc.DocBal > PrevDocBal) { ApprovedBalance += (decimal)ARDoc.DocBal - PrevDocBal; ARDoc.ApprovedCreditAmt = ApprovedBalance; } ARDoc.ApprovedCredit = (ApprovedBalance == (decimal)ARDoc.DocBal ? true : false); PrevDocBal = (decimal)ARDoc.DocBal; } }; this.RowUpdated.AddHandler(typeof(ARInvoice), ApprovedBalanceCollector); if (list != null) { bool iscc = false; DateTime? orderInvoiceDate = (sosetup.Current.UseShipDateForInvoiceDate == true ? ((SOOrderShipment)order).ShipDate : soOrder.InvoiceDate); if (soOrder.BillSeparately == false) { iscc = PXSelectReadonly<CCProcTran, Where<CCProcTran.origDocType, Equal<Required<CCProcTran.origDocType>>, And<CCProcTran.origRefNbr, Equal<Required<CCProcTran.origRefNbr>>, And<CCProcTran.refNbr, IsNull>>>>.Select(this, soOrder.OrderType, soOrder.OrderNbr).Count > 0; } if (soOrder.PaymentCntr == 0 && soOrder.BillSeparately == false && iscc == false) { if(soOrder.PaymentMethodID == null && soOrder.CashAccountID == null) newdoc = list.Find<ARInvoice.docType, ARInvoice.docDate, ARInvoice.branchID, ARInvoice.customerID, ARInvoice.customerLocationID, SOInvoice.billAddressID, SOInvoice.billContactID, SOInvoice.extRefNbr, ARInvoice.curyID, ARInvoice.termsID, ARInvoice.hidden>(((SOOrderType)order).ARDocType, orderInvoiceDate ?? invoiceDate, soOrder.BranchID, soOrder.CustomerID, soOrder.CustomerLocationID, soOrder.BillAddressID, soOrder.BillContactID, soOrder.ExtRefNbr, soOrder.CuryID, soOrder.TermsID, false) ?? (ARInvoice)new ARInvoice(); else if (soOrder.CashAccountID == null) newdoc = list.Find<ARInvoice.docType, ARInvoice.docDate, ARInvoice.branchID, ARInvoice.customerID, ARInvoice.customerLocationID, SOInvoice.billAddressID, SOInvoice.billContactID, SOInvoice.pMInstanceID, SOInvoice.extRefNbr, ARInvoice.curyID, ARInvoice.termsID, ARInvoice.hidden>(((SOOrderType)order).ARDocType, orderInvoiceDate ?? invoiceDate, soOrder.BranchID, soOrder.CustomerID, soOrder.CustomerLocationID, soOrder.BillAddressID, soOrder.BillContactID, soOrder.PMInstanceID, soOrder.ExtRefNbr, soOrder.CuryID, soOrder.TermsID, false) ?? (ARInvoice)new ARInvoice(); else newdoc = list.Find<ARInvoice.docType, ARInvoice.docDate, ARInvoice.branchID, ARInvoice.customerID, ARInvoice.customerLocationID, SOInvoice.billAddressID, SOInvoice.billContactID, SOInvoice.pMInstanceID, SOInvoice.cashAccountID, SOInvoice.extRefNbr, ARInvoice.curyID, ARInvoice.termsID, ARInvoice.hidden>(((SOOrderType)order).ARDocType, orderInvoiceDate ?? invoiceDate, soOrder.BranchID, soOrder.CustomerID, soOrder.CustomerLocationID, soOrder.BillAddressID, soOrder.BillContactID, soOrder.PMInstanceID, soOrder.CashAccountID, soOrder.ExtRefNbr, soOrder.CuryID, soOrder.TermsID, false) ?? (ARInvoice)new ARInvoice(); } else { newdoc = list.Find<ARInvoice.hidden, ARInvoice.hiddenOrderType, ARInvoice.hiddenOrderNbr>(true, soOrder.OrderType, soOrder.OrderNbr); if (newdoc == null) { newdoc = new ARInvoice(); newdoc.HiddenOrderType = soOrder.OrderType; newdoc.HiddenOrderNbr = soOrder.OrderNbr; newdoc.Hidden = true; } } if (newdoc.RefNbr != null) { Document.Current = this.Document.Search<ARInvoice.refNbr>(newdoc.RefNbr, newdoc.DocType); } else { this.Clear(); string docType = ((SOOrderType)order).ARDocType; if (((SOOrderShipment)order).Operation == ((SOOrderType)order).DefaultOperation) { newdoc.DocType = docType; } else { //for RMA switch document type if previous shipment was not invoiced previously in the current run, i.e. list.Find() returned null newdoc.DocType = docType == ARDocType.Invoice ? ARDocType.CreditMemo : docType == ARDocType.DebitMemo ? ARDocType.CreditMemo : docType == ARDocType.CreditMemo ? ARDocType.Invoice : docType == ARDocType.CashSale ? ARDocType.CashReturn : docType == ARDocType.CashReturn ? ARDocType.CashSale : null; } newdoc.DocDate = orderInvoiceDate ?? invoiceDate; if (string.IsNullOrEmpty(soOrder.FinPeriodID) == false) { newdoc.FinPeriodID = soOrder.FinPeriodID; } if (soOrder.InvoiceNbr != null) { newdoc.RefNbr = soOrder.InvoiceNbr; newdoc.RefNoteID = soOrder.NoteID; } if (((SOOrderType)order).UserInvoiceNumbering == true && string.IsNullOrEmpty(newdoc.RefNbr)) { throw new PXException(ErrorMessages.FieldIsEmpty, PXUIFieldAttribute.GetDisplayName<SOOrder.invoiceNbr>(soorder.Cache)); } AutoNumberAttribute.SetNumberingId<ARInvoice.refNbr>(Document.Cache, ((SOOrderType)order).ARDocType, ((SOOrderType)order).InvoiceNumberingID); newdoc = (ARInvoice)Document.Cache.CreateCopy(this.Document.Insert(newdoc)); newdoc.BranchID = soOrder.BranchID; newdoc.CustomerID = ((SOOrder)order).CustomerID; newdoc.CustomerLocationID = ((SOOrder)order).CustomerLocationID; newdoc.TermsID = ((SOOrder)order).TermsID; newdoc.DiscDate = ((SOOrder)order).DiscDate; newdoc.DueDate = ((SOOrder)order).DueDate; newdoc.TaxZoneID = ((SOOrder)order).TaxZoneID; newdoc.AvalaraCustomerUsageType = ((SOOrder)order).AvalaraCustomerUsageType; newdoc.SalesPersonID = ((SOOrder)order).SalesPersonID; newdoc.DocDesc = ((SOOrder)order).OrderDesc; newdoc.InvoiceNbr = ((SOOrder)order).CustomerOrderNbr; newdoc.CuryID = ((SOOrder)order).CuryID; newdoc.ProjectID = ((SOOrder)order).ProjectID ?? PM.ProjectDefaultAttribute.NonProject(this); newdoc.Hold = ordertype.InvoiceHoldEntry; if (((SOOrderType)order).MarkInvoicePrinted == true) { newdoc.Printed = true; } if (((SOOrderType)order).MarkInvoiceEmailed == true) { newdoc.Emailed = true; } if (soOrder.PMInstanceID != null || string.IsNullOrEmpty(soOrder.PaymentMethodID) == false) { newdoc.PMInstanceID = soOrder.PMInstanceID; newdoc.PaymentMethodID = soOrder.PaymentMethodID; newdoc.CashAccountID = soOrder.CashAccountID; } newdoc = this.Document.Update(newdoc); if (soOrder.PMInstanceID != null || string.IsNullOrEmpty(soOrder.PaymentMethodID) == false) { SODocument.Current.PMInstanceID = soOrder.PMInstanceID; SODocument.Current.PaymentMethodID = soOrder.PaymentMethodID; SODocument.Current.CashAccountID = soOrder.CashAccountID; if(SODocument.Current.CashAccountID == null) SODocument.Cache.SetDefaultExt<SOInvoice.cashAccountID>(SODocument.Current); SODocument.Current.ExtRefNbr = soOrder.ExtRefNbr; //clear error in case invoice currency different from default cash account for customer SODocument.Cache.RaiseExceptionHandling<SOInvoice.cashAccountID>(SODocument.Current, null, null); } foreach (CurrencyInfo info in this.currencyinfo.Select()) { if (((SOOrder)order).InvoiceDate != null) { PXCache<CurrencyInfo>.RestoreCopy(info, (CurrencyInfo)order); info.CuryInfoID = newdoc.CuryInfoID; } } AddressAttribute.CopyRecord<ARInvoice.billAddressID>(this.Document.Cache, newdoc, (SOAddress)order, true); ContactAttribute.CopyRecord<ARInvoice.billContactID>(this.Document.Cache, newdoc, (SOContact)order, true); } } else { newdoc = (ARInvoice)Document.Cache.CreateCopy(Document.Current); if (Transactions.SelectSingle() == null) { newdoc.CustomerID = ((SOOrder)order).CustomerID; newdoc.ProjectID = ((SOOrder)order).ProjectID; newdoc.CustomerLocationID = ((SOOrder)order).CustomerLocationID; newdoc.SalesPersonID = ((SOOrder)order).SalesPersonID; newdoc.TaxZoneID = ((SOOrder)order).TaxZoneID; newdoc.AvalaraCustomerUsageType = ((SOOrder)order).AvalaraCustomerUsageType; newdoc.DocDesc = ((SOOrder)order).OrderDesc; newdoc.InvoiceNbr = ((SOOrder)order).CustomerOrderNbr; newdoc.TermsID = ((SOOrder)order).TermsID; foreach (CurrencyInfo info in this.currencyinfo.Select()) { PXCache<CurrencyInfo>.RestoreCopy(info, (CurrencyInfo)order); info.CuryInfoID = newdoc.CuryInfoID; newdoc.CuryID = info.CuryID; } } newdoc = this.Document.Update(newdoc); AddressAttribute.CopyRecord<ARInvoice.billAddressID>(this.Document.Cache, newdoc, (SOAddress)order, true); ContactAttribute.CopyRecord<ARInvoice.billContactID>(this.Document.Cache, newdoc, (SOContact)order, true); } PXSelectBase<SOInvoiceDiscountDetail> selectInvoiceDiscounts = new PXSelect<SOInvoiceDiscountDetail, Where<SOInvoiceDiscountDetail.tranType, Equal<Current<SOInvoice.docType>>, And<SOInvoiceDiscountDetail.refNbr, Equal<Current<SOInvoice.refNbr>>, And<SOInvoiceDiscountDetail.orderType, Equal<Required<SOInvoiceDiscountDetail.orderType>>, And<SOInvoiceDiscountDetail.orderNbr, Equal<Required<SOInvoiceDiscountDetail.orderNbr>>>>>>>(this); foreach (SOInvoiceDiscountDetail detail in selectInvoiceDiscounts.Select(((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { DiscountDetails.Delete(detail); } TaxAttribute.SetTaxCalc<ARTran.taxCategoryID>(this.Transactions.Cache, null, TaxCalc.ManualCalc); if (details != null) { foreach (SOShipLine shipline in details) { this.Caches[typeof(SOShipLine)].Insert(shipline); } } DateTime? origInvoiceDate = null; foreach (PXResult<SOShipLine, SOLine, SOOrderTypeOperation, ARTran> res in PXSelectJoin<SOShipLine, InnerJoin<SOLine, On<SOLine.orderType, Equal<SOShipLine.origOrderType>, And<SOLine.orderNbr, Equal<SOShipLine.origOrderNbr>, And<SOLine.lineNbr, Equal<SOShipLine.origLineNbr>>>>, InnerJoin<SOOrderTypeOperation, On<SOOrderTypeOperation.orderType, Equal<SOLine.orderType>, And<SOOrderTypeOperation.operation, Equal<SOLine.operation>>>, LeftJoin<ARTran, On<ARTran.sOShipmentNbr, Equal<SOShipLine.shipmentNbr>, And<ARTran.sOShipmentType, Equal<SOShipLine.shipmentType>, And<ARTran.sOShipmentLineNbr, Equal<SOShipLine.lineNbr>, And<ARTran.sOOrderType, Equal<SOShipLine.origOrderType>, And<ARTran.sOOrderNbr, Equal<SOShipLine.origOrderNbr>, And<ARTran.sOOrderLineNbr, Equal<SOShipLine.origLineNbr>>>>>>>>>>, Where<SOShipLine.shipmentNbr, Equal<Required<SOShipLine.shipmentNbr>>, And<SOShipLine.origOrderType, Equal<Required<SOShipLine.origOrderType>>, And<SOShipLine.origOrderNbr, Equal<Required<SOShipLine.origOrderNbr>>, And<ARTran.refNbr, IsNull>>>>>.Select(this, ((SOOrderShipment)order).ShipmentNbr, ((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { SOLine orderline = (SOLine)res; SOShipLine shipline = (SOShipLine)res; if (Math.Abs((decimal)shipline.BaseShippedQty) < 0.0000005m) { continue; } if (origInvoiceDate == null && orderline.InvoiceDate != null) origInvoiceDate = orderline.InvoiceDate; ARTran newtran = new ARTran(); newtran.BranchID = orderline.BranchID; newtran.AccountID = orderline.SalesAcctID; newtran.SubID = orderline.SalesSubID; newtran.SOOrderType = shipline.OrigOrderType; newtran.SOOrderNbr = shipline.OrigOrderNbr; newtran.SOOrderLineNbr = shipline.OrigLineNbr; newtran.SOShipmentNbr = shipline.ShipmentNbr; newtran.SOShipmentType = shipline.ShipmentType; newtran.SOShipmentLineNbr = shipline.LineNbr; newtran.LineType = orderline.LineType; newtran.InventoryID = shipline.InventoryID; newtran.SiteID = orderline.SiteID; newtran.UOM = shipline.UOM; newtran.Qty = shipline.ShippedQty; newtran.BaseQty = shipline.BaseShippedQty; newtran.Commissionable = orderline.Commissionable; newtran.GroupDiscountRate = orderline.GroupDiscountRate; decimal shippedQtyInBaseUnits = INUnitAttribute.ConvertToBase(Transactions.Cache, newtran.InventoryID, shipline.UOM, shipline.ShippedQty.Value, INPrecision.QUANTITY); decimal shippedQtyInOrderUnits = INUnitAttribute.ConvertFromBase(Transactions.Cache, newtran.InventoryID, orderline.UOM, shippedQtyInBaseUnits, INPrecision.QUANTITY); if (shippedQtyInOrderUnits != orderline.OrderQty || shipline.UOM != orderline.UOM) { decimal curyUnitPriceInBaseUnits = INUnitAttribute.ConvertFromBase(Transactions.Cache, newtran.InventoryID, orderline.UOM, orderline.CuryUnitPrice.Value, INPrecision.UNITCOST); decimal curyUnitPriceInShippedUnits = INUnitAttribute.ConvertToBase(Transactions.Cache, newtran.InventoryID, shipline.UOM, curyUnitPriceInBaseUnits, INPrecision.UNITCOST); if (arsetup.Current.LineDiscountTarget == LineDiscountTargetType.SalesPrice) { decimal? salesPriceAfterDiscount = curyUnitPriceInShippedUnits * (1m - orderline.DiscPct / 100m); newtran.CuryTranAmt = shipline.ShippedQty * PXCurrencyAttribute.Round(Transactions.Cache, newtran, salesPriceAfterDiscount ?? 0, CMPrecision.TRANCURY); } else { decimal? curyTranAmt = shipline.ShippedQty * curyUnitPriceInShippedUnits * (1m - orderline.DiscPct / 100m); newtran.CuryTranAmt = PXCurrencyAttribute.Round(Transactions.Cache, newtran, curyTranAmt ?? 0, CMPrecision.TRANCURY); } newtran.CuryUnitPrice = curyUnitPriceInShippedUnits; newtran.CuryDiscAmt = (shipline.ShippedQty * curyUnitPriceInShippedUnits) - newtran.CuryTranAmt; } else { newtran.CuryUnitPrice = orderline.CuryUnitPrice; newtran.CuryTranAmt = orderline.CuryLineAmt; newtran.CuryDiscAmt = orderline.CuryDiscAmt; } if (newdoc.DocType == ((SOOrderType)order).ARDocType && ((SOOrderType)order).DefaultOperation != ((SOOrderTypeOperation)res).Operation) { //keep BaseQty positive for PXFormula newtran.Qty = -newtran.Qty; newtran.CuryDiscAmt = -newtran.CuryDiscAmt; newtran.CuryTranAmt = -newtran.CuryTranAmt; } newtran.ProjectID = orderline.ProjectID; newtran.TaskID = orderline.TaskID; newtran.TranDesc = orderline.TranDesc; newtran.SalesPersonID = orderline.SalesPersonID; newtran.TaxCategoryID = orderline.TaxCategoryID; newtran.DiscPct = orderline.DiscPct; newtran.ManualDisc = orderline.ManualDisc == true || orderline.IsFree == true; newtran.FreezeManualDisc = true; newtran.DiscountID = orderline.DiscountID; newtran.DiscountSequenceID = orderline.DiscountSequenceID; newtran.DetDiscIDC1 = orderline.DetDiscIDC1; newtran.DetDiscIDC2 = orderline.DetDiscIDC2; newtran.DetDiscSeqIDC1 = orderline.DetDiscSeqIDC1; newtran.DetDiscSeqIDC2 = orderline.DetDiscSeqIDC2; newtran.DetDiscApp = orderline.DetDiscApp; newtran.DocDiscIDC1 = orderline.DocDiscIDC1; newtran.DocDiscIDC2 = orderline.DocDiscIDC2; newtran.DocDiscSeqIDC1 = orderline.DocDiscSeqIDC1; newtran.DocDiscSeqIDC2 = orderline.DocDiscSeqIDC2; foreach (ARTran existing in Transactions.Cache.Inserted) { if (Transactions.Cache.ObjectsEqual<ARTran.sOShipmentNbr, ARTran.sOShipmentType, ARTran.sOShipmentLineNbr, ARTran.sOOrderType, ARTran.sOOrderNbr, ARTran.sOOrderLineNbr>(newtran, existing)) { Transactions.Cache.RestoreCopy(newtran, existing); break; } } if (newtran.LineNbr == null) { newtran = this.Transactions.Insert(newtran); if (((SOOrderType)order).CopyLineNotesToInvoice == true) { if (((SOOrderType)order).CopyLineNotesToInvoiceOnlyNS == false || orderline.LineType == SOLineType.NonInventory) { PXNoteAttribute.SetNote(Caches[typeof(ARTran)], newtran, PXNoteAttribute.GetNote(Caches[typeof(SOLine)], orderline)); } } if (((SOOrderType)order).CopyLineFilesToInvoice == true) { if (((SOOrderType)order).CopyLineFilesToInvoiceOnlyNS == false || orderline.LineType == SOLineType.NonInventory) { PXNoteAttribute.SetFileNotes(Caches[typeof(ARTran)], newtran, PXNoteAttribute.GetFileNotes(Caches[typeof(SOLine)], orderline)); } } } else { newtran = this.Transactions.Update(newtran); TaxAttribute.Calculate<ARTran.taxCategoryID>(Transactions.Cache, new PXRowUpdatedEventArgs(newtran, null, true)); } } PXSelectBase<ARTran> cmd = new PXSelect<ARTran, Where<ARTran.tranType, Equal<Current<ARInvoice.docType>>, And<ARTran.refNbr, Equal<Current<ARInvoice.refNbr>>, And<ARTran.sOOrderType, Equal<Current<SOMiscLine2.orderType>>, And<ARTran.sOOrderNbr, Equal<Current<SOMiscLine2.orderNbr>>, And<ARTran.sOOrderLineNbr, Equal<Current<SOMiscLine2.lineNbr>>>>>>>>(this); foreach (SOMiscLine2 orderline in PXSelect<SOMiscLine2, Where<SOMiscLine2.orderType, Equal<Required<SOMiscLine2.orderType>>, And<SOMiscLine2.orderNbr, Equal<Required<SOMiscLine2.orderNbr>>, And<Where<SOMiscLine2.curyUnbilledAmt, Greater<decimal0>, Or<SOMiscLine2.curyLineAmt, LessEqual<decimal0>>>>>>>.Select(this, ((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { if (cmd.View.SelectSingleBound(new object[] { Document.Current, orderline }) == null) { ARTran newtran = new ARTran(); newtran.BranchID = orderline.BranchID; newtran.AccountID = orderline.SalesAcctID; newtran.SubID = orderline.SalesSubID; newtran.SOOrderType = orderline.OrderType; newtran.SOOrderNbr = orderline.OrderNbr; newtran.SOOrderLineNbr = orderline.LineNbr; newtran.SOShipmentNbr = ((SOOrderShipment)order).ShipmentNbr; newtran.SOShipmentType = ((SOOrderShipment)order).ShipmentType; newtran.SOShipmentLineNbr = null; newtran.LineType = SOLineType.MiscCharge; newtran.InventoryID = orderline.InventoryID; newtran.TaskID = orderline.TaskID; newtran.SalesPersonID = orderline.SalesPersonID; newtran.Commissionable = orderline.Commissionable; newtran.UOM = orderline.UOM; newtran.Qty = orderline.UnbilledQty; newtran.BaseQty = orderline.BaseUnbilledQty; newtran.CuryUnitPrice = orderline.CuryUnitPrice; newtran.CuryDiscAmt = orderline.CuryDiscAmt; newtran.CuryTranAmt = orderline.CuryUnbilledAmt; newtran.TranDesc = orderline.TranDesc; newtran.TaxCategoryID = orderline.TaxCategoryID; newtran.DiscPct = orderline.DiscPct; newtran.ManualDisc = orderline.ManualDisc == true || orderline.IsFree == true; newtran.FreezeManualDisc = true; newtran.DiscountID = orderline.DiscountID; newtran.DiscountSequenceID = orderline.DiscountSequenceID; newtran.DetDiscIDC1 = orderline.DetDiscIDC1; newtran.DetDiscIDC2 = orderline.DetDiscIDC2; newtran.DetDiscSeqIDC1 = orderline.DetDiscSeqIDC1; newtran.DetDiscSeqIDC2 = orderline.DetDiscSeqIDC2; newtran.DetDiscApp = orderline.DetDiscApp; newtran.DocDiscIDC1 = orderline.DocDiscIDC1; newtran.DocDiscIDC2 = orderline.DocDiscIDC2; newtran.DocDiscSeqIDC1 = orderline.DocDiscSeqIDC1; newtran.DocDiscSeqIDC2 = orderline.DocDiscSeqIDC2; newtran = this.Transactions.Insert(newtran); if (((SOOrderType)order).CopyLineNotesToInvoice == true) { PXNoteAttribute.SetNote(Caches[typeof(ARTran)], newtran, PXNoteAttribute.GetNote(Caches[typeof(SOMiscLine2)], orderline)); } if (((SOOrderType)order).CopyLineFilesToInvoice == true) { PXNoteAttribute.SetFileNotes(Caches[typeof(ARTran)], newtran, PXNoteAttribute.GetFileNotes(Caches[typeof(SOMiscLine2)], orderline)); } } } SODocument.Current = (SOInvoice)SODocument.Select() ?? (SOInvoice)SODocument.Cache.Insert(); SODocument.Current.BillAddressID = soOrder.BillAddressID; SODocument.Current.BillContactID = soOrder.BillContactID; SODocument.Current.ShipAddressID = soOrder.ShipAddressID; SODocument.Current.ShipContactID = soOrder.ShipContactID; SODocument.Current.IsCCCaptured = soOrder.IsCCCaptured; SODocument.Current.IsCCCaptureFailed = soOrder.IsCCCaptureFailed; SODocument.Current.PaymentProjectID = PM.ProjectDefaultAttribute.NonProject(this); if (soOrder.IsCCCaptured == true) { SODocument.Current.CuryCCCapturedAmt = soOrder.CuryCCCapturedAmt; SODocument.Current.CCCapturedAmt = soOrder.CCCapturedAmt; } SODocument.Current.RefTranExtNbr = soOrder.RefTranExtNbr; SOOrderShipment shipment = PXCache<SOOrderShipment>.CreateCopy((SOOrderShipment)order); shipment.InvoiceType = SODocument.Current.DocType; shipment.InvoiceNbr = SODocument.Current.RefNbr; shipmentlist.Cache.Update(shipment); FillFreightDetails((SOOrder)order, shipment); /*In case Discounts were not recalculated add prorated Doc discounts */ if (ordertype.RecalculateDiscOnPartialShipment != true) { //add prorated document discount details from invoice: PXSelectBase<SOOrderDiscountDetail> selectOrderDocGroupDiscounts = new PXSelect<SOOrderDiscountDetail, Where<SOOrderDiscountDetail.orderType, Equal<Required<SOOrderDiscountDetail.orderType>>, And<SOOrderDiscountDetail.orderNbr, Equal<Required<SOOrderDiscountDetail.orderNbr>>>>>(this); decimal? rate = 1m; if (soOrder.LineTotal > 0m) rate = shipment.LineTotal / soOrder.LineTotal; foreach (SOOrderDiscountDetail docGroupDisc in selectOrderDocGroupDiscounts.Select(((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { SOInvoiceDiscountDetail dd = new SOInvoiceDiscountDetail(); dd.Type = docGroupDisc.Type; dd.DiscountID = docGroupDisc.DiscountID; dd.DiscountSequenceID = docGroupDisc.DiscountSequenceID; dd.OrderType = docGroupDisc.OrderType; dd.OrderNbr = docGroupDisc.OrderNbr; dd.TranType = newdoc.DocType; dd.RefNbr = newdoc.RefNbr; dd.DiscountPct = docGroupDisc.DiscountPct; dd.FreeItemID = docGroupDisc.FreeItemID; dd.FreeItemQty = docGroupDisc.FreeItemQty; if (docGroupDisc.Type == DiscountType.Group) { SOOrderEntry soOrderQ = (SOOrderEntry)PXGraph.CreateInstance(typeof(SOOrderEntry)); soOrderQ.Document.Current = order; Dictionary<DiscountSequenceKey, DiscountEngine<SOLine>.DiscountDetailToLineCorrelation<SOOrderDiscountDetail>> grLinesOrderCorrelation = DiscountEngine<SOLine>.CollectGroupDiscountToLineCorrelation(soOrderQ.Transactions.Cache, soOrderQ.Transactions, soOrderQ.DiscountDetails, soOrder.CustomerLocationID, (DateTime)soOrder.OrderDate, false); foreach (KeyValuePair<DiscountSequenceKey, DiscountEngine<SOLine>.DiscountDetailToLineCorrelation<SOOrderDiscountDetail>> dsGroup in grLinesOrderCorrelation) { if (dsGroup.Key.DiscountID == docGroupDisc.DiscountID && dsGroup.Key.DiscountSequenceID == docGroupDisc.DiscountSequenceID) { decimal invoicedGroupAmt = 0m; foreach (SOLine soLine in dsGroup.Value.listOfApplicableLines) { foreach (ARTran tran in Transactions.Select()) { if (soLine.LineNbr == tran.SOOrderLineNbr) invoicedGroupAmt += (tran.CuryLineAmt ?? 0m); } } rate = (invoicedGroupAmt / (decimal)dsGroup.Value.discountDetailLine.CuryDiscountableAmt); } } } SOInvoiceDiscountDetail located = DiscountDetails.Locate(dd); if (located != null) { located.DiscountAmt += docGroupDisc.DiscountAmt * rate; located.CuryDiscountAmt += docGroupDisc.CuryDiscountAmt * rate; located.DiscountableAmt += docGroupDisc.DiscountableAmt * rate; located.CuryDiscountableAmt += docGroupDisc.CuryDiscountableAmt * rate; located.DiscountableQty += docGroupDisc.DiscountableQty * rate; DiscountDetails.Update(located); } else { dd.DiscountAmt = docGroupDisc.DiscountAmt * rate; dd.CuryDiscountAmt = docGroupDisc.CuryDiscountAmt * rate; dd.DiscountableAmt = docGroupDisc.DiscountableAmt * rate; dd.CuryDiscountableAmt = docGroupDisc.CuryDiscountableAmt * rate; dd.DiscountableQty = docGroupDisc.DiscountableQty * rate; DiscountDetails.Insert(dd); } } } else { //Recalculate all discounts foreach (ARTran tran in Transactions.Select()) { RecalculateDiscounts(this.Transactions.Cache, tran); } } RecalculateTotalDiscount(); foreach (PXResult<SOTaxTran, Tax> res in PXSelectJoin<SOTaxTran, InnerJoin<Tax, On<SOTaxTran.taxID, Equal<Tax.taxID>>>, Where<SOTaxTran.orderType, Equal<Required<SOTaxTran.orderType>>, And<SOTaxTran.orderNbr, Equal<Required<SOTaxTran.orderNbr>>>>>.Select(this, ((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { SOTaxTran tax = (SOTaxTran)res; ARTaxTran newtax = new ARTaxTran(); newtax.Module = BatchModule.AR; Taxes.Cache.SetDefaultExt<ARTaxTran.origTranType>(newtax); Taxes.Cache.SetDefaultExt<ARTaxTran.origRefNbr>(newtax); Taxes.Cache.SetDefaultExt<ARTaxTran.lineRefNbr>(newtax); newtax.TranType = Document.Current.DocType; newtax.RefNbr = Document.Current.RefNbr; newtax.TaxID = tax.TaxID; newtax.TaxRate = 0m; this.Taxes.Delete(newtax); newtax = this.Taxes.Insert(newtax); } decimal? CuryApplAmt = 0m; bool Calculated = false; foreach (SOAdjust soadj in PXSelectJoin<SOAdjust, InnerJoin<AR.ARPayment, On<AR.ARPayment.docType, Equal<SOAdjust.adjgDocType>, And<AR.ARPayment.refNbr, Equal<SOAdjust.adjgRefNbr>>>>, Where<SOAdjust.adjdOrderType, Equal<Required<SOAdjust.adjdOrderType>>, And<SOAdjust.adjdOrderNbr, Equal<Required<SOAdjust.adjdOrderNbr>>, And<AR.ARPayment.openDoc, Equal<True>>>>>.Select(this, ((SOOrderShipment)order).OrderType, ((SOOrderShipment)order).OrderNbr)) { ARAdjust prev_adj = null; bool found = false; foreach (ARAdjust adj in Adjustments.Select()) { if (Calculated) { CuryApplAmt -= adj.CuryAdjdAmt; } if (string.Equals(adj.AdjgDocType, soadj.AdjgDocType) && string.Equals(adj.AdjgRefNbr, soadj.AdjgRefNbr)) { if (soadj.CuryAdjdAmt > 0m) { ARAdjust copy = PXCache<ARAdjust>.CreateCopy(adj); copy.CuryAdjdAmt += (soadj.CuryAdjdAmt > adj.CuryDocBal) ? adj.CuryDocBal : soadj.CuryAdjdAmt; copy.AdjdOrderType = soadj.AdjdOrderType; copy.AdjdOrderNbr = soadj.AdjdOrderNbr; prev_adj = Adjustments.Update(copy); } found = true; if (Calculated) { CuryApplAmt += adj.CuryAdjdAmt; break; } } CuryApplAmt += adj.CuryAdjdAmt; } //if soadjust is not available in adjustments mark as billed if (!found) { /* soadj.Billed = true; soadjustments.Cache.SetStatus(soadj, PXEntryStatus.Updated); */ } Calculated = true; if (!IsExternalTax) { if (CuryApplAmt > Document.Current.CuryDocBal - Document.Current.CuryOrigDiscAmt && prev_adj != null) { prev_adj = PXCache<ARAdjust>.CreateCopy(prev_adj); if (prev_adj.CuryAdjdAmt > (CuryApplAmt - (Document.Current.CuryDocBal - Document.Current.CuryOrigDiscAmt))) { prev_adj.CuryAdjdAmt -= (CuryApplAmt - (Document.Current.CuryDocBal - Document.Current.CuryOrigDiscAmt)); CuryApplAmt = Document.Current.CuryDocBal - Document.Current.CuryOrigDiscAmt; } else { CuryApplAmt -= prev_adj.CuryAdjdAmt; prev_adj.CuryAdjdAmt = 0m; } prev_adj = Adjustments.Update(prev_adj); } } } newdoc = (ARInvoice)Document.Cache.CreateCopy(Document.Current); newdoc.OrigDocDate = origInvoiceDate; SOInvoice socopy = (SOInvoice)SODocument.Cache.CreateCopy(SODocument.Current); PXFormulaAttribute.CalcAggregate<ARAdjust.curyAdjdAmt>(Adjustments.Cache, SODocument.Current, false); Document.Cache.RaiseFieldUpdated<SOInvoice.curyPaymentTotal>(SODocument.Current, null); PXDBCurrencyAttribute.CalcBaseValues<SOInvoice.curyPaymentTotal>(SODocument.Cache, SODocument.Current); SODocument.Cache.RaiseRowUpdated(SODocument.Current, socopy); List<string> ordersdistinct = new List<string>(); foreach (SOOrderShipment shipments in PXSelect<SOOrderShipment, Where<SOOrderShipment.invoiceType, Equal<Current<ARInvoice.docType>>, And<SOOrderShipment.invoiceNbr, Equal<Current<ARInvoice.refNbr>>>>>.Select(this)) { string key = string.Format("{0}|{1}", shipments.OrderType, shipments.OrderNbr); if (!ordersdistinct.Contains(key)) { ordersdistinct.Add(key); } if (ordersdistinct.Count > 1) { newdoc.InvoiceNbr = null; newdoc.SalesPersonID = null; newdoc.DocDesc = null; break; } #region Update FreeItemQty for DiscountDetails based on shipments PXSelectBase<SOShipmentDiscountDetail> selectShipmentDiscounts = new PXSelect<SOShipmentDiscountDetail, Where<SOShipmentDiscountDetail.orderType, Equal<Required<SOShipmentDiscountDetail.orderType>>, And<SOShipmentDiscountDetail.orderNbr, Equal<Required<SOShipmentDiscountDetail.orderNbr>>, And<SOShipmentDiscountDetail.shipmentNbr, Equal<Required<SOShipmentDiscountDetail.shipmentNbr>>>>>>(this); foreach (SOShipmentDiscountDetail sdd in selectShipmentDiscounts.Select(shipments.OrderType, shipments.OrderNbr, shipments.ShipmentNbr)) { SOInvoiceDiscountDetail idd = PXSelect<SOInvoiceDiscountDetail, Where<SOInvoiceDiscountDetail.tranType, Equal<Current<ARInvoice.docType>>, And<SOInvoiceDiscountDetail.refNbr, Equal<Current<ARInvoice.refNbr>>, And<SOInvoiceDiscountDetail.orderType, Equal<Required<SOInvoiceDiscountDetail.orderType>>, And<SOInvoiceDiscountDetail.orderNbr, Equal<Required<SOInvoiceDiscountDetail.orderNbr>>, And<SOInvoiceDiscountDetail.discountID, Equal<Required<SOInvoiceDiscountDetail.discountID>>, And<SOInvoiceDiscountDetail.discountSequenceID, Equal<Required<SOInvoiceDiscountDetail.discountSequenceID>>>>>>>>>.Select(this, shipments.OrderType, shipments.OrderNbr, sdd.DiscountID, sdd.DiscountSequenceID); if (idd != null) { if (idd.FreeItemID == null) { idd.FreeItemID = sdd.FreeItemID; idd.FreeItemQty = sdd.FreeItemQty; } else idd.FreeItemQty = sdd.FreeItemQty; DiscountDetails.Update(idd); } else { idd = new SOInvoiceDiscountDetail(); idd.Type = DiscountType.Line; idd.TranType = newdoc.DocType; idd.RefNbr = newdoc.RefNbr; idd.OrderType = sdd.OrderType; idd.OrderNbr = sdd.OrderNbr; idd.DiscountID = sdd.DiscountID; idd.DiscountSequenceID = sdd.DiscountSequenceID; idd.FreeItemID = sdd.FreeItemID; idd.FreeItemQty = sdd.FreeItemQty; DiscountDetails.Insert(idd); } } #endregion } this.Document.Update(newdoc); if (list != null) { if (Transactions.Search<ARTran.sOOrderType, ARTran.sOOrderNbr, ARTran.sOShipmentType, ARTran.sOShipmentNbr>(shipment.OrderType, shipment.OrderNbr, shipment.ShipmentType, shipment.ShipmentNbr).Count > 0) { try { this.Document.Current.ApplyPaymentWhenTaxAvailable = true; this.Save.Press(); } finally { this.Document.Current.ApplyPaymentWhenTaxAvailable = false; } if (list.Find(this.Document.Current) == null) { list.Add(this.Document.Current, this.SODocument.Current); } } else { this.Clear(); } } this.RowUpdated.RemoveHandler(typeof(ARInvoice), ApprovedBalanceCollector); }
public virtual void InvoiceOrder(DateTime invoiceDate, PXResult<SOOrderShipment, SOOrder, CurrencyInfo, SOAddress, SOContact, SOOrderType> order, Customer customer, DocumentList<ARInvoice, SOInvoice> list) { InvoiceOrder(invoiceDate, order, null, customer, list); }