public virtual APInvoice ReleaseRetainageProc(APInvoice doc, RetainageOptions retainageOpts, bool isAutoRelease = false) { Base.Clear(PXClearOption.PreserveTimeStamp); if (retainageOpts.CuryRetainageAmt <= 0 || retainageOpts.CuryRetainageAmt > doc.CuryRetainageUnreleasedAmt) { throw new PXException(Messages.IncorrectRetainageAmount); } // Magic. We need to prevent rewriting of CurrencyInfo.IsReadOnly // by true in CurrencyInfoView // Base.CurrentDocument.Cache.AllowUpdate = true; PXResult <APInvoice, CurrencyInfo, Terms, Vendor> resultDoc = APInvoice_CurrencyInfo_Terms_Vendor .SelectSingleBound(Base, null, doc.DocType, doc.RefNbr, doc.VendorID) .Cast <PXResult <APInvoice, CurrencyInfo, Terms, Vendor> >() .First(); CurrencyInfo info = resultDoc; APInvoice origInvoice = resultDoc; Vendor vendor = resultDoc; CurrencyInfo new_info = PXCache <CurrencyInfo> .CreateCopy(info); new_info.CuryInfoID = null; new_info.IsReadOnly = false; new_info = PXCache <CurrencyInfo> .CreateCopy(Base.currencyinfo.Insert(new_info)); APInvoice invoice = PXCache <APInvoice> .CreateCopy(origInvoice); invoice.CuryInfoID = new_info.CuryInfoID; invoice.DocType = APDocType.Invoice; invoice.RefNbr = null; invoice.LineCntr = null; invoice.InvoiceNbr = retainageOpts.InvoiceNbr; // Must be set for _RowSelected event handler // invoice.OpenDoc = true; invoice.Released = false; Base.Document.Cache.SetDefaultExt <APInvoice.isMigratedRecord>(invoice); invoice.BatchNbr = null; invoice.PrebookBatchNbr = null; invoice.Prebooked = false; invoice.ScheduleID = null; invoice.Scheduled = false; invoice.NoteID = null; invoice.DueDate = null; invoice.DiscDate = null; invoice.CuryOrigDiscAmt = 0m; invoice.OrigDocType = origInvoice.DocType; invoice.OrigRefNbr = origInvoice.RefNbr; invoice.OrigDocDate = origInvoice.DocDate; invoice.PaySel = false; invoice.CuryLineTotal = 0m; invoice.IsTaxPosted = false; invoice.IsTaxValid = false; invoice.CuryVatTaxableTotal = 0m; invoice.CuryVatExemptTotal = 0m; invoice.CuryDocBal = 0m; invoice.CuryOrigDocAmt = retainageOpts.CuryRetainageAmt; invoice.Hold = !isAutoRelease && Base.apsetup.Current.HoldEntry == true || Base.IsApprovalRequired(invoice, Base.Document.Cache); invoice.DocDate = retainageOpts.DocDate; invoice.FinPeriodID = retainageOpts.FinPeriodID; Base.ClearRetainageSummary(invoice); invoice.RetainageApply = false; invoice.IsRetainageDocument = true; invoice = Base.Document.Insert(invoice); if (new_info != null) { CurrencyInfo b_info = (CurrencyInfo)PXSelect <CurrencyInfo, Where <CurrencyInfo.curyInfoID, Equal <Current <APInvoice.curyInfoID> > > > .Select(Base); b_info.CuryID = new_info.CuryID; b_info.CuryEffDate = new_info.CuryEffDate; b_info.CuryRateTypeID = new_info.CuryRateTypeID; b_info.CuryRate = new_info.CuryRate; b_info.RecipRate = new_info.RecipRate; b_info.CuryMultDiv = new_info.CuryMultDiv; Base.currencyinfo.Update(b_info); } decimal retainagePercent = (decimal)(retainageOpts.CuryRetainageAmt / doc.CuryRetainageTotal); PXResultset <APTran> details = PXSelectGroupBy <APTran, Where <APTran.tranType, Equal <Required <APTran.tranType> >, And <APTran.refNbr, Equal <Required <APTran.refNbr> >, And <APTran.curyRetainageAmt, NotEqual <decimal0> > > >, Aggregate < GroupBy <APTran.taxCategoryID, Sum <APTran.curyRetainageAmt> > > > .Select(Base, doc.DocType, doc.RefNbr); APTran tranNew = null; decimal prevCuryTotal = 0m; TaxCalc oldTaxCalc = TaxBaseAttribute.GetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null); TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null, TaxCalc.ManualCalc); foreach (APTran detail in details) { // Create APTran record for chosen retainage amount, // clear all required fields to prevent tax calculation, // discount calculation and retainage calculation. // CuryUnitCost = 0m and CuryLineAmt = 0m here to prevent their // FieldDefaulting events, because in our case default value // should be equal to zero. // tranNew = Base.Transactions.Insert(new APTran { CuryUnitCost = 0m, CuryLineAmt = 0m }); tranNew.BranchID = origInvoice.BranchID; tranNew.TaxCategoryID = detail.TaxCategoryID; tranNew.AccountID = origInvoice.RetainageAcctID; tranNew.SubID = origInvoice.RetainageSubID; tranNew.ProjectID = ProjectDefaultAttribute.NonProject(); tranNew.Qty = 0m; tranNew.CuryUnitCost = 0m; tranNew.ManualDisc = true; tranNew.DiscPct = 0m; tranNew.CuryDiscAmt = 0m; tranNew.RetainagePct = 0m; tranNew.CuryRetainageAmt = 0m; tranNew.CuryTaxableAmt = 0m; tranNew.CuryTaxAmt = 0; tranNew.CuryExpenseAmt = 0m; tranNew.GroupDiscountRate = 1m; tranNew.DocumentDiscountRate = 1m; using (new PXLocaleScope(vendor.LocaleName)) { tranNew.TranDesc = PXMessages.LocalizeFormatNoPrefix( Messages.RetainageForTransactionDescription, APDocTypeDict[origInvoice.DocType], origInvoice.RefNbr); } prevCuryTotal = (retainageOpts.CuryRetainageAmt ?? 0m) - (invoice.CuryDocBal ?? 0m); tranNew.CuryLineAmt = PXCurrencyAttribute.RoundCury(Base.Transactions.Cache, tranNew, (detail.CuryRetainageAmt ?? 0m) * retainagePercent); tranNew = Base.Transactions.Update(tranNew); } ClearCurrentDocumentDiscountDetails(); // We should copy all taxes from the original document // because it is possible to add or delete them. // foreach (APTaxTran aptaxtran in PXSelect <APTaxTran, Where <APTaxTran.module, Equal <BatchModule.moduleAP>, And <APTaxTran.tranType, Equal <Required <APTaxTran.tranType> >, And <APTaxTran.refNbr, Equal <Required <APTaxTran.refNbr> > > > > > .Select(Base, origInvoice.DocType, origInvoice.RefNbr) .RowCast <APTaxTran>() .Where(row => row.CuryRetainedTaxAmt != 0m)) { APTaxTran new_aptaxtran = Base.Taxes.Insert(new APTaxTran { TaxID = aptaxtran.TaxID }); if (new_aptaxtran != null) { new_aptaxtran = PXCache <APTaxTran> .CreateCopy(new_aptaxtran); new_aptaxtran.TaxRate = aptaxtran.TaxRate; new_aptaxtran = Base.Taxes.Update(new_aptaxtran); } } TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null, oldTaxCalc); decimal diff = (retainageOpts.CuryRetainageAmt ?? 0m) - (invoice.CuryDocBal ?? 0m); if (tranNew != null && diff != 0m) { HashSet <string> taxList = PXSelectJoin <APTax, InnerJoin <Tax, On <Tax.taxID, Equal <APTax.taxID> > >, Where <APTax.tranType, Equal <Required <APTax.tranType> >, And <APTax.refNbr, Equal <Required <APTax.refNbr> >, And <APTax.lineNbr, Equal <Required <APTax.lineNbr> >, And <Tax.taxType, NotEqual <CSTaxType.use> > > > > > .Select(Base, tranNew.TranType, tranNew.RefNbr, tranNew.LineNbr) .RowCast <APTax>() .Select(row => row.TaxID) .ToHashSet(); // To guarantee correct document total amount // we should calculate last line total, // including its taxes. // TaxAttribute.CalcTaxable calcClass = new TaxAttribute.CalcTaxable(false, TaxAttribute.TaxCalcLevelEnforcing.None); decimal curyLineAmt = calcClass.CalcTaxableFromTotalAmount( Base.Transactions.Cache, tranNew, taxList, invoice.DocDate.Value, prevCuryTotal); tranNew.CuryLineAmt = curyLineAmt; tranNew = Base.Transactions.Update(tranNew); } APVendorRefNbrAttribute aPVendorRefNbrAttribute = Base.Document.Cache.GetAttributesReadonly <APInvoice.invoiceNbr>() .OfType <APVendorRefNbrAttribute>().FirstOrDefault(); if (aPVendorRefNbrAttribute != null) { var args = new PXFieldVerifyingEventArgs(invoice, invoice.InvoiceNbr, true); aPVendorRefNbrAttribute.FieldVerifying(Base.Document.Cache, args); } return(invoice); }
protected virtual IEnumerable history() { APHistoryFilter header = Filter.Current; if (header == null) { yield break; } if (header.Period == null) { PXSelectBase <Vendor> sel = new PXSelectJoinGroupBy <Vendor, LeftJoin <APHistory, On <APHistory.vendorID, Equal <Vendor.bAccountID> > >, Aggregate < Sum <APHistory.finPtdCrAdjustments, Sum <APHistory.finPtdDiscTaken, Sum <APHistory.finPtdDrAdjustments, Sum <APHistory.finPtdPayments, Sum <APHistory.finPtdPurchases, Sum <APHistory.finPtdRGOL, Sum <APHistory.tranPtdCrAdjustments, Sum <APHistory.tranPtdDiscTaken, Sum <APHistory.tranPtdDrAdjustments, Sum <APHistory.tranPtdPayments, Sum <APHistory.tranPtdPurchases, Sum <APHistory.tranPtdRGOL, GroupBy <Vendor.bAccountID> > > > > > > > > > > > > > >(this); if (header.APAcctID != null) { sel.WhereAnd <Where <Vendor.aPAcctID, Equal <Current <APHistoryFilter.aPAcctID> > > >(); } if (header.APSubID != null) { sel.WhereAnd <Where <Vendor.aPSubID, Equal <Current <APHistoryFilter.aPSubID> > > >(); } bool foreign = false; if (header.CuryID != null) { sel.WhereAnd <Where <Vendor.curyID, Equal <Current <APHistoryFilter.curyID> > > >(); GL.Company company = PXSelect <GL.Company> .Select(this); foreign = (company == null || company.BaseCuryID != header.CuryID); if (foreign) { PXUIFieldAttribute.SetVisible <APHistoryResult.rGOL>(History.Cache, null, false); } } if (header.CashAcctID != null) { sel.WhereAnd <Where <Vendor.cashAcctID, Equal <Current <APHistoryFilter.cashAcctID> > > >(); } if (header.PaymentTypeID != null) { sel.WhereAnd <Where <Vendor.paymentTypeID, Equal <Current <APHistoryFilter.paymentTypeID> > > >(); } if (header.VendorClassID != null) { sel.WhereAnd <Where <Vendor.vendorClassID, Equal <Current <APHistoryFilter.vendorClassID> > > >(); } if (header.Status != null) { sel.WhereAnd <Where <Vendor.status, Equal <Current <APHistoryFilter.status> > > >(); } foreach (PXResult <Vendor, APHistory> record in sel.Select()) { Vendor vendor = record; APHistory history = record; APHistoryResult res = new APHistoryResult(); res.AcctCD = vendor.AcctCD; res.AcctName = vendor.AcctName; if (header.ByFinancialPeriod != true) { if (!foreign) { res.Purchases = history.TranPtdPurchases ?? 0m; res.Payments = history.TranPtdPayments ?? 0m; res.Discount = history.TranPtdDiscTaken ?? 0m; res.RGOL = history.TranPtdRGOL ?? 0m; res.CrAdjustments = history.TranPtdCrAdjustments ?? 0m; res.DrAdjustments = history.TranPtdDrAdjustments ?? 0m; res.Balance = res.Purchases - res.Payments - res.Discount + res.RGOL - res.DrAdjustments + res.CrAdjustments; } else { res.Purchases = history.TranPtdPurchases ?? 0m; res.Payments = history.TranPtdPayments ?? 0m; res.Discount = history.TranPtdDiscTaken ?? 0m; res.RGOL = 0m; res.CrAdjustments = history.TranPtdCrAdjustments ?? 0m; res.DrAdjustments = history.TranPtdDrAdjustments ?? 0m; res.Balance = res.Purchases - res.Payments - res.Discount - res.DrAdjustments + res.CrAdjustments; } } else { if (!foreign) { res.Purchases = history.FinPtdPurchases ?? 0m; res.Payments = history.FinPtdPayments ?? 0m; res.Discount = history.FinPtdDiscTaken ?? 0m; res.RGOL = history.FinPtdRGOL ?? 0m; res.CrAdjustments = history.FinPtdCrAdjustments ?? 0m; res.DrAdjustments = history.FinPtdDrAdjustments ?? 0m; res.Balance = res.Purchases - res.Payments - res.Discount + res.RGOL - res.DrAdjustments + res.CrAdjustments; } else { res.Purchases = history.FinPtdPurchases ?? 0m; res.Payments = history.FinPtdPayments ?? 0m; res.Discount = history.FinPtdDiscTaken ?? 0m; res.RGOL = 0m; res.CrAdjustments = history.FinPtdCrAdjustments ?? 0m; res.DrAdjustments = history.FinPtdDrAdjustments ?? 0m; res.Balance = res.Purchases - res.Payments - res.Discount - res.DrAdjustments + res.CrAdjustments; } } if (res.Balance != 0m || header.ShowWithBalanceOnly != true) { yield return(res); } } } else { PXSelectBase <Vendor> sel = new PXSelectJoinGroupBy <Vendor, LeftJoin <APHistory, On <APHistory.vendorID, Equal <Vendor.bAccountID>, And <APHistory.finPeriodID, Equal <Current <APHistoryFilter.period> > > > >, Aggregate < Sum <APHistory.finBegBalance, Sum <APHistory.finYtdBalance, Sum <APHistory.finPtdCrAdjustments, Sum <APHistory.finPtdDiscTaken, Sum <APHistory.finPtdDrAdjustments, Sum <APHistory.finPtdPayments, Sum <APHistory.finPtdPurchases, Sum <APHistory.finPtdRGOL, Sum <APHistory.tranBegBalance, Sum <APHistory.tranYtdBalance, Sum <APHistory.tranPtdCrAdjustments, Sum <APHistory.tranPtdDiscTaken, Sum <APHistory.tranPtdDrAdjustments, Sum <APHistory.tranPtdPayments, Sum <APHistory.tranPtdPurchases, Sum <APHistory.tranPtdRGOL, GroupBy <Vendor.bAccountID> > > > > > > > > > > > > > > > > > >(this); PXUIFieldAttribute.SetVisible <APHistoryResult.balance>(History.Cache, null, false); PXUIFieldAttribute.SetVisible <APHistoryResult.begBalance>(History.Cache, null); PXUIFieldAttribute.SetVisible <APHistoryResult.endBalance>(History.Cache, null); if (header.APAcctID != null) { sel.WhereAnd <Where <Vendor.aPAcctID, Equal <Current <APHistoryFilter.aPAcctID> > > >(); } if (header.APSubID != null) { sel.WhereAnd <Where <Vendor.aPSubID, Equal <Current <APHistoryFilter.aPSubID> > > >(); } bool foreign = false; if (header.CuryID != null) { sel.WhereAnd <Where <Vendor.curyID, Equal <Current <APHistoryFilter.curyID> > > >(); GL.Company company = PXSelect <GL.Company> .Select(this); foreign = (company == null || company.BaseCuryID != header.CuryID); if (foreign) { PXUIFieldAttribute.SetVisible <APHistoryResult.rGOL>(History.Cache, null, false); } } if (header.CashAcctID != null) { sel.WhereAnd <Where <Vendor.cashAcctID, Equal <Current <APHistoryFilter.cashAcctID> > > >(); } if (header.PaymentTypeID != null) { sel.WhereAnd <Where <Vendor.paymentTypeID, Equal <Current <APHistoryFilter.paymentTypeID> > > >(); } if (header.VendorClassID != null) { sel.WhereAnd <Where <Vendor.vendorClassID, Equal <Current <APHistoryFilter.vendorClassID> > > >(); } if (header.Status != null) { sel.WhereAnd <Where <Vendor.status, Equal <Current <APHistoryFilter.status> > > >(); } foreach (PXResult <Vendor, APHistory> record in sel.Select()) { Vendor vendor = record; APHistory history = record; APHistoryResult res = new APHistoryResult(); res.AcctCD = vendor.AcctCD; res.AcctName = vendor.AcctName; if (header.ByFinancialPeriod != true) { if (!foreign) { res.Purchases = history.TranPtdPurchases ?? 0m; res.Payments = history.TranPtdPayments ?? 0m; res.Discount = history.TranPtdDiscTaken ?? 0m; res.RGOL = history.TranPtdRGOL ?? 0m; res.CrAdjustments = history.TranPtdCrAdjustments ?? 0m; res.DrAdjustments = history.TranPtdDrAdjustments ?? 0m; res.BegBalance = history.TranBegBalance ?? 0m; res.EndBalance = res.BegBalance + res.Purchases - res.Payments - res.Discount + res.RGOL - res.DrAdjustments + res.CrAdjustments; } else { res.Purchases = history.TranPtdPurchases ?? 0m; res.Payments = history.TranPtdPayments ?? 0m; res.Discount = history.TranPtdDiscTaken ?? 0m; res.RGOL = 0m; res.CrAdjustments = history.TranPtdCrAdjustments ?? 0m; res.DrAdjustments = history.TranPtdDrAdjustments ?? 0m; res.BegBalance = history.TranBegBalance ?? 0m; res.EndBalance = res.BegBalance + res.Purchases - res.Payments - res.Discount - res.DrAdjustments + res.CrAdjustments; } } else { if (!foreign) { res.Purchases = history.FinPtdPurchases ?? 0m; res.Payments = history.FinPtdPayments ?? 0m; res.Discount = history.FinPtdDiscTaken ?? 0m; res.RGOL = history.FinPtdRGOL ?? 0m; res.CrAdjustments = history.FinPtdCrAdjustments ?? 0m; res.DrAdjustments = history.FinPtdDrAdjustments ?? 0m; res.BegBalance = history.FinBegBalance ?? 0m; res.EndBalance = res.BegBalance + res.Purchases - res.Payments - res.Discount + res.RGOL - res.DrAdjustments + res.CrAdjustments; } else { res.Purchases = history.FinPtdPurchases ?? 0m; res.Payments = history.FinPtdPayments ?? 0m; res.Discount = history.FinPtdDiscTaken ?? 0m; res.RGOL = 0m; res.CrAdjustments = history.FinPtdCrAdjustments ?? 0m; res.DrAdjustments = history.FinPtdDrAdjustments ?? 0m; res.BegBalance = history.FinBegBalance ?? 0m; res.EndBalance = res.BegBalance + res.Purchases - res.Payments - res.Discount - res.DrAdjustments + res.CrAdjustments; } } if (res.Balance != 0m || header.ShowWithBalanceOnly != true) { yield return(res); } } } }
protected virtual GetTaxRequest BuildTaxRequest(APInvoice invoice) { if (invoice == null) { throw new PXArgumentException(nameof(invoice), ErrorMessages.ArgumentNullException); } Vendor vend = (Vendor)Base.vendor.View.SelectSingleBound(new object[] { invoice }); var request = new PX.TaxProvider.GetTaxRequest(); request.CompanyCode = CompanyCodeFromBranch(invoice.TaxZoneID, invoice.BranchID); request.CurrencyCode = invoice.CuryID; request.CustomerCode = vend.AcctCD; IAddressBase fromAddress = GetFromAddress(invoice); IAddressBase toAddress = GetToAddress(invoice); if (fromAddress == null) { throw new PXException(Messages.FailedGetFrom); } if (toAddress == null) { throw new PXException(Messages.FailedGetTo); } request.OriginAddress = AddressConverter.ConvertTaxAddress(fromAddress); request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress); request.DocCode = $"AP.{invoice.DocType}.{invoice.RefNbr}"; request.DocDate = invoice.DocDate.GetValueOrDefault(); request.LocationCode = GetExternalTaxProviderLocationCode(invoice); Location branchLoc = GetBranchLocation(invoice); if (branchLoc != null) { request.CustomerUsageType = branchLoc.CAvalaraCustomerUsageType; request.ExemptionNo = branchLoc.CAvalaraExemptionNumber; } request.DocType = GetTaxDocumentType(invoice); Sign sign = GetDocumentSign(invoice); PXSelectBase <APTran> select = new PXSelectJoin <APTran, LeftJoin <InventoryItem, On <InventoryItem.inventoryID, Equal <APTran.inventoryID> >, LeftJoin <Account, On <Account.accountID, Equal <APTran.accountID> > > >, Where <APTran.tranType, Equal <Current <APInvoice.docType> >, And <APTran.refNbr, Equal <Current <APInvoice.refNbr> >, And <APTran.lineType, NotEqual <SOLineType.discount> > > >, OrderBy <Asc <APTran.tranType, Asc <APTran.refNbr, Asc <APTran.lineNbr> > > > >(Base); request.Discount = GetDocDiscount().GetValueOrDefault(); foreach (PXResult <APTran, InventoryItem, Account> res in select.View.SelectMultiBound(new object[] { invoice })) { APTran tran = (APTran)res; InventoryItem item = (InventoryItem)res; Account salesAccount = (Account)res; var line = new TaxCartItem(); line.Index = tran.LineNbr.GetValueOrDefault(); line.Amount = sign * tran.CuryTranAmt.GetValueOrDefault(); line.Description = tran.TranDesc; line.OriginAddress = AddressConverter.ConvertTaxAddress(GetFromAddress(invoice, tran)); line.DestinationAddress = AddressConverter.ConvertTaxAddress(GetToAddress(invoice, tran)); line.ItemCode = item.InventoryCD; line.Quantity = Math.Abs(tran.Qty.GetValueOrDefault()); line.Discounted = request.Discount > 0; line.RevAcct = salesAccount.AccountCD; line.TaxCode = tran.TaxCategoryID; request.CartItems.Add(line); } if (invoice.DocType == APDocType.DebitAdj && (invoice.OrigDocDate != null)) { request.TaxOverride.Reason = Messages.DebitAdjustmentReason; request.TaxOverride.TaxDate = invoice.OrigDocDate.Value; request.TaxOverride.TaxOverrideType = PX.TaxProvider.TaxOverrideType.TaxDate; } return(request); }