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);
        }