Beispiel #1
0
        public void NavigateToResult(int bacctId)
        {
            BAccount acct = SWSelect <BAccount, Where <BAccount.bAccountID, Equal <Required <BAccount.bAccountID> > > > .SelectWindowed(graph, 0, 1, bacctId);

            if (acct == null)
            {
                return;
            }

            if (acct.Type == "CU")
            {
                AR.Customer cust = SWSelect <AR.Customer, Where <AR.Customer.bAccountID, Equal <Required <BAccount.bAccountID> > > > .SelectWindowed(this.graph, 0, 1, acct.BAccountID);

                SWRedirectHelper.TryRedirect(graph.Caches[typeof(SW.Objects.AR.Customer)], cust, "");
            }
            else
            {
                AP.Vendor vend = SWSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <BAccount.bAccountID> > > > .SelectWindowed(this.graph, 0, 1, acct.BAccountID);

                SWRedirectHelper.TryRedirect(graph.Caches[typeof(SW.Objects.AP.Vendor)], vend, "");
            }
        }
Beispiel #2
0
        public static string GetLineDiscountTarget(PXCache sender, LineEntitiesFields efields)
        {
            string LineDiscountTarget = LineDiscountTargetType.ExtendedPrice;

            if (efields != null && efields.VendorID != null)
            {
                AP.Vendor vendor = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .SelectSingleBound(sender.Graph, null, efields.VendorID);

                if (vendor != null)
                {
                    LineDiscountTarget = vendor.LineDiscountTarget;
                }
            }
            else
            {
                ARSetup arsetup = PXSelect <ARSetup> .Select(sender.Graph);

                if (arsetup != null)
                {
                    LineDiscountTarget = arsetup.LineDiscountTarget;
                }
            }
            return(LineDiscountTarget);
        }
        protected virtual void ApplyTax(POOrder order, GetTaxResult result, GetTaxResult resultUnbilled)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;
            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)Base.taxzone.View.SelectSingleBound(new object[] { order });
                vendor  = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(Messages.ExternalTaxVendorNotFound);
                }
            }
            //Clear all existing Tax transactions:
            foreach (PXResult <POTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { order }))
            {
                POTaxTran taxTran = (POTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                CreateTax(Base, taxZone, vendor, result.TaxSummary[i], taxID);

                POTaxTran tax = new POTaxTran();
                tax.OrderType      = order.OrderType;
                tax.OrderNbr       = order.OrderNbr;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].TaxAmount);
                tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].TaxableAmount);
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;
                tax.JurisType      = result.TaxSummary[i].JurisType;
                tax.JurisName      = result.TaxSummary[i].JurisName;

                Base.Taxes.Insert(tax);
            }

            bool requireBlanketControlTotal  = Base.POSetup.Current.RequireBlanketControlTotal == true;
            bool requireDropShipControlTotal = Base.POSetup.Current.RequireDropShipControlTotal == true;
            bool requireOrderControlTotal    = Base.POSetup.Current.RequireOrderControlTotal == true;

            if (order.Hold != true)
            {
                Base.POSetup.Current.RequireBlanketControlTotal  = false;
                Base.POSetup.Current.RequireDropShipControlTotal = false;
                Base.POSetup.Current.RequireOrderControlTotal    = false;
            }

            try
            {
                Base.Document.SetValueExt <POOrder.curyTaxTotal>(order, Math.Abs(result.TotalTaxAmount));
                if (resultUnbilled != null)
                {
                    Base.Document.SetValueExt <POOrder.curyUnbilledTaxTotal>(order, Math.Abs(resultUnbilled.TotalTaxAmount));
                }
                Base.Document.Update(order);
            }
            finally
            {
                Base.POSetup.Current.RequireBlanketControlTotal  = requireBlanketControlTotal;
                Base.POSetup.Current.RequireDropShipControlTotal = requireDropShipControlTotal;
                Base.POSetup.Current.RequireOrderControlTotal    = requireOrderControlTotal;
            }

            SkipTaxCalcAndSave();
        }
        protected virtual void ApplyTax(CROpportunity order, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;

            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)PXSetup <TaxZone, Where <TaxZone.taxZoneID, Equal <Required <CROpportunity.taxZoneID> > > > .Select(Base, order.TaxZoneID);

                vendor = (AP.Vendor) PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(Messages.ExternalTaxVendorNotFound);
                }
            }

            //Clear all existing Tax transactions:
            foreach (PXResult <CRTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { order }))
            {
                CRTaxTran taxTran = (CRTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                CreateTax(Base, taxZone, vendor, result.TaxSummary[i], taxID);

                CRTaxTran tax = new CRTaxTran();
                tax.QuoteID        = order.QuoteNoteID;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].TaxAmount);
                tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].TaxableAmount);
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;

                Base.Taxes.Insert(tax);
            }

            Base.Opportunity.SetValueExt <CROpportunity.curyTaxTotal>(order, Math.Abs(result.TotalTaxAmount));

            decimal?СuryProductsAmount =
                order.ManualTotalEntry == true
                                ? order.CuryAmount - order.CuryDiscTot
                                : order.CuryLineTotal - order.CuryDiscTot + order.CuryTaxTotal;

            CalcCuryProductsAmount(order, ref СuryProductsAmount);

            Base.Opportunity.SetValueExt <CROpportunity.curyProductsAmount>(order, СuryProductsAmount ?? 0m);
        }
        protected virtual void ApplyTax(CAAdj invoice, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;
            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)Base.taxzone.View.SelectSingleBound(new object[] { invoice });
                vendor  = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(Messages.ExternalTaxVendorNotFound);
                }
            }
            //Clear all existing Tax transactions:
            foreach (PXResult <CATaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { invoice }))
            {
                CATaxTran taxTran = (CATaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(Base, taxID);

                if (tx == null)
                {
                    tx = new Tax
                    {
                        TaxID             = taxID,
                        Descr             = PXMessages.LocalizeFormatNoPrefixNLA(TX.Messages.ExternalTaxProviderTaxId, taxID),
                        TaxType           = CSTaxType.Sales,
                        TaxCalcType       = CSTaxCalcType.Doc,
                        TaxCalcLevel      = result.TaxSummary[i].TaxCalculationLevel.ToCSTaxCalcLevel(),
                        TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount,
                        SalesTaxAcctID    = vendor.SalesTaxAcctID,
                        SalesTaxSubID     = vendor.SalesTaxSubID,
                        ExpenseAccountID  = vendor.TaxExpenseAcctID,
                        ExpenseSubID      = vendor.TaxExpenseSubID,
                        TaxVendorID       = taxZone.TaxVendorID,
                        IsExternal        = true
                    };

                    Base.Caches[typeof(Tax)].Insert(tx);
                }

                CATaxTran tax = new CATaxTran
                {
                    Module         = BatchModule.CA,
                    TranType       = invoice.DocType,
                    RefNbr         = invoice.RefNbr,
                    TaxID          = taxID,
                    CuryTaxAmt     = Math.Abs(result.TaxSummary[i].TaxAmount),
                    CuryTaxableAmt = Math.Abs(result.TaxSummary[i].TaxableAmount),
                    TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100,
                    TaxType        = "S",
                    TaxBucketID    = 0,
                    AccountID      = vendor.SalesTaxAcctID,
                    SubID          = vendor.SalesTaxSubID,
                    JurisType      = result.TaxSummary[i].JurisType,
                    JurisName      = result.TaxSummary[i].JurisName
                };

                Base.Taxes.Insert(tax);
            }

            bool requireControlTotal = Base.casetup.Current.RequireControlTotal == true;

            if (invoice.Hold != true)
            {
                Base.casetup.Current.RequireControlTotal = false;
            }

            try
            {
                invoice.CuryTaxTotal = Math.Abs(result.TotalTaxAmount);
                Base.CAAdjRecords.Cache.SetValueExt <CAAdj.isTaxSaved>(invoice, true);
                Base.CAAdjRecords.Update(invoice);
            }
            finally
            {
                Base.casetup.Current.RequireControlTotal = requireControlTotal;
            }
        }
        protected virtual void ApplyTax(ARCashSale invoice, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;
            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)Base.taxzone.View.SelectSingleBound(new object[] { invoice });
                vendor  = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(TX.Messages.ExternalTaxVendorNotFound);
                }

                if (vendor.SalesTaxAcctID == null)
                {
                    throw new PXException(TX.Messages.TaxPayableAccountNotSpecified, vendor.AcctCD);
                }

                if (vendor.SalesTaxSubID == null)
                {
                    throw new PXException(TX.Messages.TaxPayableSubNotSpecified, vendor.AcctCD);
                }
            }
            //Clear all existing Tax transactions:
            foreach (PXResult <ARTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { invoice }))
            {
                ARTaxTran taxTran = (ARTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                CreateTax(Base, taxZone, vendor, result.TaxSummary[i], taxID);

                ARTaxTran tax = new ARTaxTran();
                tax.Module         = BatchModule.AR;
                tax.TranType       = invoice.DocType;
                tax.RefNbr         = invoice.RefNbr;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].TaxAmount);
                tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].TaxableAmount);
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;
                tax.TaxType        = "S";
                tax.TaxBucketID    = 0;
                tax.AccountID      = vendor.SalesTaxAcctID;
                tax.SubID          = vendor.SalesTaxSubID;
                tax.JurisType      = result.TaxSummary[i].JurisType;
                tax.JurisName      = result.TaxSummary[i].JurisName;

                Base.Taxes.Insert(tax);
            }

            bool requireControlTotal = Base.arsetup.Current.RequireControlTotal == true;

            if (invoice.Hold != true)
            {
                Base.arsetup.Current.RequireControlTotal = false;
            }


            try
            {
                invoice.CuryTaxTotal = Math.Abs(result.TotalTaxAmount);
                Base.Document.Cache.SetValueExt <ARCashSale.isTaxSaved>(invoice, true);
            }
            finally
            {
                Base.arsetup.Current.RequireControlTotal = requireControlTotal;
            }
        }
        protected void ApplyTax(FSServiceOrder order, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;

            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)PXSetup <TaxZone, Where <TaxZone.taxZoneID, Equal <Required <FSServiceOrder.taxZoneID> > > > .Select(Base, order.TaxZoneID);

                vendor = (AP.Vendor) PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(PX.Objects.CR.Messages.ExternalTaxVendorNotFound);
                }
            }

            //Clear all existing Tax transactions:
            foreach (PXResult <FSServiceOrderTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { order }))
            {
                FSServiceOrderTaxTran taxTran = (FSServiceOrderTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = GetTaxID(result.TaxSummary[i]);

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(Base, taxID);

                if (tx == null)
                {
                    tx                   = new Tax();
                    tx.TaxID             = taxID;
                    tx.Descr             = PXMessages.LocalizeFormatNoPrefixNLA(PX.Objects.TX.Messages.ExternalTaxProviderTaxId, taxID);
                    tx.TaxType           = CSTaxType.Sales;
                    tx.TaxCalcType       = CSTaxCalcType.Doc;
                    tx.TaxCalcLevel      = result.TaxSummary[i].TaxCalculationLevel.ToCSTaxCalcLevel();
                    tx.TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount;
                    tx.SalesTaxAcctID    = vendor.SalesTaxAcctID;
                    tx.SalesTaxSubID     = vendor.SalesTaxSubID;
                    tx.ExpenseAccountID  = vendor.TaxExpenseAcctID;
                    tx.ExpenseSubID      = vendor.TaxExpenseSubID;
                    tx.TaxVendorID       = taxZone.TaxVendorID;
                    tx.IsExternal        = true;

                    Base.Caches[typeof(Tax)].Insert(tx);
                }

                FSServiceOrderTaxTran tax = new FSServiceOrderTaxTran();
                tax.EntityType     = ID.PostDoc_EntityType.SERVICE_ORDER;
                tax.EntityID       = order.SOID;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].TaxAmount);
                tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].TaxableAmount);
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;

                Base.Taxes.Insert(tax);
            }

            Base.CurrentServiceOrder.SetValueExt <FSServiceOrder.curyTaxTotal>(order, Math.Abs(result.TotalTaxAmount));

            decimal?СuryDocTotal = ServiceOrderEntry.GetCuryDocTotal(order.CuryBillableOrderTotal, order.CuryDiscTot, order.CuryTaxTotal, 0);

            Base.CurrentServiceOrder.SetValueExt <FSServiceOrder.curyDocTotal>(order, СuryDocTotal ?? 0m);
        }
        protected void ApplyTax(PMQuote quote, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;

            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)PXSetup <TaxZone, Where <TaxZone.taxZoneID, Equal <Required <PMQuote.taxZoneID> > > > .Select(Base, quote.TaxZoneID);

                vendor = (VendorMaster)PXSelectReadonly <VendorMaster, Where <VendorMaster.bAccountID, Equal <Required <VendorMaster.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(CR.Messages.ExternalTaxVendorNotFound);
                }
            }

            //Clear all existing Tax transactions:
            foreach (PXResult <CRTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { quote }))
            {
                CRTaxTran taxTran = (CRTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = GetTaxID(result.TaxSummary[i]);

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(Base, taxID);

                if (tx == null)
                {
                    tx                   = new Tax();
                    tx.TaxID             = taxID;
                    tx.Descr             = PXMessages.LocalizeFormatNoPrefixNLA(TX.Messages.ExternalTaxProviderTaxId, taxID);
                    tx.TaxType           = CSTaxType.Sales;
                    tx.TaxCalcType       = CSTaxCalcType.Doc;
                    tx.TaxCalcLevel      = result.TaxSummary[i].TaxCalculationLevel.ToCSTaxCalcLevel();
                    tx.TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount;
                    tx.SalesTaxAcctID    = vendor.SalesTaxAcctID;
                    tx.SalesTaxSubID     = vendor.SalesTaxSubID;
                    tx.ExpenseAccountID  = vendor.TaxExpenseAcctID;
                    tx.ExpenseSubID      = vendor.TaxExpenseSubID;
                    tx.TaxVendorID       = taxZone.TaxVendorID;
                    tx.IsExternal        = true;

                    Base.Caches[typeof(Tax)].Insert(tx);
                }

                CRTaxTran tax = new CRTaxTran();
                tax.QuoteID        = quote.QuoteID;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = result.TaxSummary[i].TaxAmount;
                tax.CuryTaxableAmt = result.TaxSummary[i].TaxableAmount;
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;

                Base.Taxes.Insert(tax);
            }

            Base.Quote.SetValueExt <PMQuote.curyTaxTotal>(quote, result.TotalTaxAmount);

            decimal?СuryProductsAmount =
                quote.ManualTotalEntry == true
                                ? quote.CuryAmount - quote.CuryDiscTot
                                : quote.CuryLineTotal - quote.CuryDiscTot + quote.CuryTaxTotal;

            Base.Quote.SetValueExt <PMQuote.curyProductsAmount>(quote, СuryProductsAmount ?? 0m);
        }
Beispiel #9
0
        protected static void ApplyAvalaraTax(OpportunityMaint rg, CROpportunity order, GetTaxResult result)
        {
            var avalaraSetup = (TXAvalaraSetup)PXSetupOptional <TXAvalaraSetup> .Select(rg);

            TaxZone taxZone = (TaxZone)PXSetup <TaxZone, Where <TaxZone.taxZoneID, Equal <Required <CROpportunity.taxZoneID> > > > .Select(rg, order.TaxZoneID);

            AP.Vendor vendor = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(rg, taxZone.TaxVendorID);

            if (vendor == null)
            {
                throw new PXException(Messages.ExternalTaxVendorNotFound);
            }

            //Clear all existing Tax transactions:
            foreach (PXResult <CRTaxTran, Tax> res in rg.Taxes.View.SelectMultiBound(new object[] { order }))
            {
                CRTaxTran taxTran = (CRTaxTran)res;
                rg.Taxes.Delete(taxTran);
            }

            rg.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Count; i++)
            {
                string taxID = AvalaraMaint.GetTaxID(result.TaxSummary[i]);

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(rg, taxID);

                if (tx == null)
                {
                    tx       = new Tax();
                    tx.TaxID = taxID;
                    //tx.Descr = string.Format("Avalara {0} {1}%", taxID, Convert.ToDecimal(result.TaxSummary[i].Rate)*100);
                    tx.Descr             = PXMessages.LocalizeFormatNoPrefixNLA(TX.Messages.AvalaraTaxId, taxID);
                    tx.TaxType           = CSTaxType.Sales;
                    tx.TaxCalcType       = CSTaxCalcType.Doc;
                    tx.TaxCalcLevel      = avalaraSetup.IsInclusiveTax == true ? CSTaxCalcLevel.Inclusive : CSTaxCalcLevel.CalcOnItemAmt;
                    tx.TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount;
                    tx.SalesTaxAcctID    = vendor.SalesTaxAcctID;
                    tx.SalesTaxSubID     = vendor.SalesTaxSubID;
                    tx.ExpenseAccountID  = vendor.TaxExpenseAcctID;
                    tx.ExpenseSubID      = vendor.TaxExpenseSubID;
                    tx.TaxVendorID       = taxZone.TaxVendorID;
                    tx.IsExternal        = true;

                    rg.Caches[typeof(Tax)].Insert(tx);
                }

                CRTaxTran tax = new CRTaxTran();
                tax.OpportunityID  = order.OpportunityID;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].Tax);
                tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].Taxable);
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;

                rg.Taxes.Insert(tax);
            }

            rg.Opportunity.SetValueExt <CROpportunity.curyTaxTotal>(order, Math.Abs(result.TotalTax));

            try
            {
                rg.SkipAvalaraTaxProcessing = true;
                rg.Save.Press();
            }
            finally
            {
                rg.SkipAvalaraTaxProcessing = false;
            }
        }
Beispiel #10
0
        public virtual void ApplyTax(PMProforma doc, GetTaxResult result)
        {
            TaxZone taxZone = (TaxZone)Base.taxzone.View.SelectSingleBound(new object[] { doc });

            if (taxZone == null)
            {
                throw new PXException(SO.Messages.TaxZoneIsNotSet);
            }

            AP.Vendor vendor = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

            if (vendor == null)
            {
                throw new PXException(TX.Messages.ExternalTaxVendorNotFound);
            }

            if (result != null)
            {
                //Clear all existing Tax transactions:
                PXSelectBase <PMTaxTran> TaxesSelect =
                    new PXSelectJoin <PMTaxTran, InnerJoin <Tax, On <Tax.taxID, Equal <PMTaxTran.taxID> > >,
                                      Where <PMTaxTran.refNbr, Equal <Current <PMProforma.refNbr> > > >(Base);
                foreach (PXResult <PMTaxTran, Tax> res in TaxesSelect.View.SelectMultiBound(new object[] { doc }))
                {
                    PMTaxTran taxTran = (PMTaxTran)res;
                    Base.Taxes.Delete(taxTran);
                }

                Base.Views.Caches.Add(typeof(Tax));

                var taxDetails = new List <PX.TaxProvider.TaxDetail>();
                for (int i = 0; i < result.TaxSummary.Length; i++)
                {
                    taxDetails.Add(result.TaxSummary[i]);
                }

                foreach (var taxDetail in taxDetails)
                {
                    string taxID = taxDetail.TaxName;
                    if (string.IsNullOrEmpty(taxID))
                    {
                        taxID = taxDetail.JurisCode;
                    }

                    if (string.IsNullOrEmpty(taxID))
                    {
                        PXTrace.WriteInformation(SO.Messages.EmptyValuesFromExternalTaxProvider);
                        continue;
                    }

                    //Insert Tax if not exists - just for the selectors sake
                    Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(Base, taxID);

                    if (tx == null)
                    {
                        tx                   = new Tax();
                        tx.TaxID             = taxID;
                        tx.Descr             = PXMessages.LocalizeFormatNoPrefixNLA(TX.Messages.ExternalTaxProviderTaxFor, taxDetail.JurisType, taxDetail.JurisName);
                        tx.TaxType           = CSTaxType.Sales;
                        tx.TaxCalcType       = CSTaxCalcType.Doc;
                        tx.TaxCalcLevel      = CSTaxCalcLevel.CalcOnItemAmt;
                        tx.TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount;
                        tx.SalesTaxAcctID    = vendor.SalesTaxAcctID;
                        tx.SalesTaxSubID     = vendor.SalesTaxSubID;
                        tx.ExpenseAccountID  = vendor.TaxExpenseAcctID;
                        tx.ExpenseSubID      = vendor.TaxExpenseSubID;
                        tx.TaxVendorID       = taxZone.TaxVendorID;
                        tx.IsExternal        = true;

                        Base.Caches[typeof(Tax)].Insert(tx);
                    }

                    PMTaxTran tax = new PMTaxTran();
                    tax.RefNbr         = doc.RefNbr;
                    tax.TaxID          = taxID;
                    tax.CuryTaxAmt     = taxDetail.TaxAmount;
                    tax.CuryTaxableAmt = taxDetail.TaxableAmount;
                    tax.TaxRate        = Convert.ToDecimal(taxDetail.Rate) * 100;
                    tax.JurisType      = taxDetail.JurisType;
                    tax.JurisName      = taxDetail.JurisName;

                    Base.Taxes.Insert(tax);
                }

                Base.Document.SetValueExt <PMProforma.curyTaxTotal>(doc, result.TotalTaxAmount);
            }

            Base.Document.Update(doc);
            SkipTaxCalcAndSave();
        }
        protected static void ApplyAvalaraTax(OpportunityMaint rg, CROpportunity order, GetTaxResult result)
        {
            var avalaraSetup = (TXAvalaraSetup)PXSetupOptional <TXAvalaraSetup> .Select(rg);

            TaxZone taxZone = (TaxZone)PXSetup <TaxZone, Where <TaxZone.taxZoneID, Equal <Required <CROpportunity.taxZoneID> > > > .Select(rg, order.TaxZoneID);

            AP.Vendor vendor = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(rg, taxZone.TaxVendorID);

            if (vendor == null)
            {
                throw new PXException("Tax Vendor is required but not found for the External TaxZone.");
            }

            Dictionary <string, CRTaxTran> existingRows = new Dictionary <string, CRTaxTran>();

            foreach (PXResult <CRTaxTran, Tax> res in rg.Taxes.View.SelectMultiBound(new object[] { order }))
            {
                CRTaxTran taxTran = (CRTaxTran)res;
                existingRows.Add(taxTran.TaxID.Trim().ToUpperInvariant(), taxTran);
            }

            rg.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Count; i++)
            {
                string taxID = result.TaxSummary[i].TaxName.ToUpperInvariant();

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(rg, taxID);

                if (tx == null)
                {
                    tx       = new Tax();
                    tx.TaxID = taxID;
                    //tx.Descr = string.Format("Avalara {0} {1}%", taxID, Convert.ToDecimal(result.TaxSummary[i].Rate)*100);
                    tx.Descr             = string.Format("Avalara {0}", taxID);
                    tx.TaxType           = CSTaxType.Sales;
                    tx.TaxCalcType       = CSTaxCalcType.Doc;
                    tx.TaxCalcLevel      = avalaraSetup.IsInclusiveTax == true ? CSTaxCalcLevel.Inclusive : CSTaxCalcLevel.CalcOnItemAmt;
                    tx.TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount;
                    tx.SalesTaxAcctID    = vendor.SalesTaxAcctID;
                    tx.SalesTaxSubID     = vendor.SalesTaxSubID;
                    tx.ExpenseAccountID  = vendor.TaxExpenseAcctID;
                    tx.ExpenseSubID      = vendor.TaxExpenseSubID;
                    tx.TaxVendorID       = taxZone.TaxVendorID;

                    rg.Caches[typeof(Tax)].Insert(tx);
                }

                CRTaxTran existing = null;
                existingRows.TryGetValue(taxID, out existing);

                if (existing != null)
                {
                    existing.TaxAmt         = Math.Abs(result.TaxSummary[i].Tax);
                    existing.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].Tax);
                    existing.TaxableAmt     = Math.Abs(result.TaxSummary[i].Taxable);
                    existing.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].Taxable);
                    existing.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate);

                    rg.Taxes.Update(existing);
                    existingRows.Remove(existing.TaxID.Trim().ToUpperInvariant());
                }
                else
                {
                    CRTaxTran tax = new CRTaxTran();
                    tax.OpportunityID  = order.OpportunityID;
                    tax.TaxID          = taxID;
                    tax.TaxAmt         = Math.Abs(result.TaxSummary[i].Tax);
                    tax.CuryTaxAmt     = Math.Abs(result.TaxSummary[i].Tax);
                    tax.TaxableAmt     = Math.Abs(result.TaxSummary[i].Taxable);
                    tax.CuryTaxableAmt = Math.Abs(result.TaxSummary[i].Taxable);
                    tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate);

                    rg.Taxes.Insert(tax);
                }
            }

            foreach (CRTaxTran taxTran in existingRows.Values)
            {
                rg.Taxes.Delete(taxTran);
            }

            rg.Opportunity.SetValueExt <CROpportunity.curyTaxTotal>(order, Math.Abs(result.TotalTax));

            try
            {
                rg.SkipAvalaraTaxProcessing = true;
                rg.Save.Press();
            }
            finally
            {
                rg.SkipAvalaraTaxProcessing = false;
            }
        }
        public virtual void ApplyTax(ARInvoice invoice, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;
            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)Base.taxzone.View.SelectSingleBound(new object[] { invoice });
                vendor  = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(TX.Messages.ExternalTaxVendorNotFound);
                }

                if (vendor.SalesTaxAcctID == null)
                {
                    throw new PXException(TX.Messages.TaxPayableAccountNotSpecified, vendor.AcctCD);
                }

                if (vendor.SalesTaxSubID == null)
                {
                    throw new PXException(TX.Messages.TaxPayableSubNotSpecified, vendor.AcctCD);
                }
            }
            Sign sign = invoice.DocType == ARDocType.CreditMemo ? Sign.Minus : Sign.Plus;

            //Clear all existing Tax transactions:
            foreach (PXResult <ARTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { invoice }))
            {
                ARTaxTran taxTran = res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                //Insert Tax if not exists - just for the selectors sake
                Tax tx = PXSelect <Tax, Where <Tax.taxID, Equal <Required <Tax.taxID> > > > .Select(Base, taxID);

                if (tx == null)
                {
                    tx = new Tax
                    {
                        TaxID             = taxID,
                        Descr             = PXMessages.LocalizeFormatNoPrefixNLA(TX.Messages.ExternalTaxProviderTaxId, taxID),
                        TaxType           = CSTaxType.Sales,
                        TaxCalcType       = CSTaxCalcType.Doc,
                        TaxCalcLevel      = result.TaxSummary[i].TaxCalculationLevel.ToCSTaxCalcLevel(),
                        TaxApplyTermsDisc = CSTaxTermsDiscount.ToTaxableAmount,
                        SalesTaxAcctID    = vendor.SalesTaxAcctID,
                        SalesTaxSubID     = vendor.SalesTaxSubID,
                        ExpenseAccountID  = vendor.TaxExpenseAcctID,
                        ExpenseSubID      = vendor.TaxExpenseSubID,
                        TaxVendorID       = taxZone.TaxVendorID,
                        IsExternal        = true
                    };

                    Base.Caches[typeof(Tax)].Insert(tx);
                }

                var tax = new ARTaxTran
                {
                    Module         = BatchModule.AR,
                    TranType       = invoice.DocType,
                    RefNbr         = invoice.RefNbr,
                    TaxID          = taxID,
                    CuryTaxAmt     = sign * result.TaxSummary[i].TaxAmount,
                    CuryTaxableAmt = sign * result.TaxSummary[i].TaxableAmount,
                    TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100,
                    JurisType      = result.TaxSummary[i].JurisType,
                    JurisName      = result.TaxSummary[i].JurisName,
                    TaxType        = CSTaxType.Sales,
                    TaxBucketID    = 0,
                    AccountID      = vendor.SalesTaxAcctID,
                    SubID          = vendor.SalesTaxSubID
                };

                Base.Taxes.Insert(tax);
            }

            bool requireControlTotal = Base.ARSetup.Current.RequireControlTotal == true;

            if (invoice.Hold != true)
            {
                Base.ARSetup.Current.RequireControlTotal = false;
            }

            try
            {
                invoice.CuryTaxTotal = sign * result.TotalTaxAmount;
                Base.Document.Cache.SetValueExt <ARInvoice.isTaxSaved>(invoice, true);
            }
            finally
            {
                Base.ARSetup.Current.RequireControlTotal = requireControlTotal;
            }

            if (invoice.ApplyPaymentWhenTaxAvailable == true)
            {
                PXSelectBase <ARAdjust2> select = new PXSelectJoin <ARAdjust2,
                                                                    InnerJoin <ARPayment, On <ARAdjust2.adjgDocType, Equal <ARPayment.docType>,
                                                                                              And <ARAdjust2.adjgRefNbr, Equal <ARPayment.refNbr> > > >,
                                                                    Where <ARAdjust2.adjdDocType, Equal <Required <ARInvoice.docType> >,
                                                                           And <ARAdjust2.adjdRefNbr, Equal <Required <ARInvoice.refNbr> > > > >(Base);

                decimal amountApplied = 0m;
                foreach (PXResult <ARAdjust2, ARPayment> res in select.Select(invoice.DocType, invoice.RefNbr))
                {
                    ARAdjust2 row     = (ARAdjust2)res;
                    ARPayment payment = (ARPayment)res;

                    ARAdjust2 copy = PXCache <ARAdjust2> .CreateCopy(row);

                    amountApplied += (copy.CuryAdjdAmt ?? 0m);

                    if (amountApplied > (invoice.CuryDocBal ?? 0m))
                    {
                        decimal newAdjdAmt = (copy.CuryAdjdAmt ?? 0m) - (amountApplied - (invoice.CuryDocBal ?? 0m));
                        copy.CuryAdjdAmt = newAdjdAmt > 0m ? newAdjdAmt : 0m;
                    }
                    Base.Adjustments.Update(copy);
                }
            }
        }
        protected void ApplyTax(PMQuote quote, GetTaxResult result)
        {
            TaxZone taxZone = null;

            AP.Vendor vendor = null;

            if (result.TaxSummary.Length > 0)
            {
                taxZone = (TaxZone)PXSetup <TaxZone> .Where <TaxZone.taxZoneID.IsEqual <@P.AsString> > .Select(Base, quote.TaxZoneID);

                vendor = (VendorMaster)PXSelectReadonly <VendorMaster, Where <VendorMaster.bAccountID, Equal <Required <VendorMaster.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

                if (vendor == null)
                {
                    throw new PXException(CR.Messages.ExternalTaxVendorNotFound);
                }
            }

            //Clear all existing Tax transactions:
            foreach (PXResult <CRTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { quote }))
            {
                CRTaxTran taxTran = (CRTaxTran)res;
                Base.Taxes.Delete(taxTran);
            }

            Base.Views.Caches.Add(typeof(Tax));

            for (int i = 0; i < result.TaxSummary.Length; i++)
            {
                string taxID = result.TaxSummary[i].TaxName;
                if (string.IsNullOrEmpty(taxID))
                {
                    taxID = result.TaxSummary[i].JurisCode;
                }

                if (string.IsNullOrEmpty(taxID))
                {
                    PXTrace.WriteInformation(Messages.EmptyValuesFromExternalTaxProvider);
                    continue;
                }

                CreateTax(Base, taxZone, vendor, result.TaxSummary[i], taxID);

                CRTaxTran tax = new CRTaxTran();
                tax.QuoteID        = quote.QuoteID;
                tax.TaxID          = taxID;
                tax.CuryTaxAmt     = result.TaxSummary[i].TaxAmount;
                tax.CuryTaxableAmt = result.TaxSummary[i].TaxableAmount;
                tax.TaxRate        = Convert.ToDecimal(result.TaxSummary[i].Rate) * 100;

                Base.Taxes.Insert(tax);
            }

            Base.Quote.SetValueExt <PMQuote.curyTaxTotal>(quote, result.TotalTaxAmount);

            decimal?СuryProductsAmount =
                quote.ManualTotalEntry == true
                                ? quote.CuryAmount - quote.CuryDiscTot
                                : quote.CuryLineTotal - quote.CuryDiscTot + quote.CuryTaxTotal;

            Base.Quote.SetValueExt <PMQuote.curyProductsAmount>(quote, СuryProductsAmount ?? 0m);
        }
        /*protected virtual GetTaxRequest BuildGetTaxRequestOpen(FSAppointment order)
         * {
         *  Stopwatch sw = new Stopwatch();
         *  sw.Start();
         *
         *  if (order == null)
         *      throw new PXArgumentException(ErrorMessages.ArgumentNullException);
         *
         *  Customer cust = (Customer)Base.TaxCustomer.View.SelectSingleBound(new object[] { order });
         *  Location loc = (Location)Base.TaxLocation.View.SelectSingleBound(new object[] { order });
         *
         *  IAddressBase fromAddress = GetFromAddress(order);
         *  IAddressBase toAddress = GetToAddress(order);
         *
         *  if (fromAddress == null)
         *      throw new PXException(Messages.FailedGetFromAddressSO);
         *
         *  if (toAddress == null)
         *      throw new PXException(Messages.FailedGetToAddressSO);
         *
         *  GetTaxRequest request = new GetTaxRequest();
         *  request.CompanyCode = CompanyCodeFromBranch(order.TaxZoneID, order.BranchID);
         *  request.CurrencyCode = order.CuryID;
         *  request.CustomerCode = cust.AcctCD;
         *  request.OriginAddress = AddressConverter.ConvertTaxAddress(fromAddress);
         *  request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress);
         *  request.DocCode = string.Format("SO.{0}.{1}", order.SrvOrdType, order.RefNbr);
         *  request.DocDate = order.ScheduledDateTimeBegin.GetValueOrDefault();
         *  request.LocationCode = GetExternalTaxProviderLocationCode(order);
         *
         *  int mult = 1;
         *
         *  if (!string.IsNullOrEmpty(loc.CAvalaraCustomerUsageType))
         *  {
         *      request.CustomerUsageType = loc.CAvalaraCustomerUsageType;
         *  }
         *  if (!string.IsNullOrEmpty(loc.CAvalaraExemptionNumber))
         *  {
         *      request.ExemptionNo = loc.CAvalaraExemptionNumber;
         *  }
         *
         *  FSSrvOrdType srvOrdType = (FSSrvOrdType)Base.ServiceOrderTypeSelected.View.SelectSingleBound(new object[] { order });
         *
         *  if (srvOrdType.DefaultOperation == SOOperation.Receipt)
         *  {
         *      request.DocType = TaxDocumentType.ReturnOrder;
         *      mult = -1;
         *
         *      PXSelectBase<FSAppointmentDet> selectLineWithInvoiceDate = new PXSelect<FSAppointmentDet,
         *      Where<FSAppointmentDet.srvOrdType, Equal<Required<FSAppointmentDet.srvOrdType>>, And<FSAppointmentDet.refNbr, Equal<Required<FSAppointmentDet.refNbr>>,
         *      And<FSAppointmentDet.invoiceDate, IsNotNull>>>>(Base);
         *
         *      FSAppointmentDet soLine = selectLineWithInvoiceDate.SelectSingle(order.SrvOrdType, order.RefNbr);
         *      if (soLine != null && soLine.TranDate != null)
         *      {
         *          request.TaxOverride.Reason = Messages.ReturnReason;
         *          request.TaxOverride.TaxDate = soLine.TranDate.Value;
         *          request.TaxOverride.TaxOverrideType = TaxOverrideType.TaxDate;
         *      }
         *
         *  }
         *  else
         *  {
         *      request.DocType = TaxDocumentType.SalesOrder;
         *  }
         *  request.DocType = TaxDocumentType.SalesOrder;
         *
         *
         *  PXSelectBase<FSAppointmentDet> select = new PXSelectJoin<FSAppointmentDet,
         *      LeftJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<FSAppointmentDet.inventoryID>>,
         *          LeftJoin<Account, On<Account.accountID, Equal<FSAppointmentDet.acctID>>>>,
         *      Where<FSAppointmentDet.srvOrdType, Equal<Current<FSAppointment.srvOrdType>>,
         *          And<FSAppointmentDet.refNbr, Equal<Current<FSAppointment.refNbr>>>>,
         *      OrderBy<Asc<FSAppointmentDet.srvOrdType, Asc<FSAppointmentDet.refNbr, Asc<FSAppointmentDet.lineNbr>>>>>(Base);
         *
         *  request.Discount = order.CuryDiscTot.GetValueOrDefault();
         *
         *  foreach (PXResult<FSAppointmentDet, InventoryItem, Account> res in select.View.SelectMultiBound(new object[] { order }))
         *  {
         *      FSAppointmentDet tran = (FSAppointmentDet)res;
         *      InventoryItem item = (InventoryItem)res;
         *      Account salesAccount = (Account)res;
         *
         *      if (tran.OpenAmt >= 0)
         *      {
         *          var line = new TaxCartItem();
         *          line.Index = tran.LineNbr ?? 0;
         *          if (srvOrdType.DefaultOperation != tran.Operation)
         *              line.Amount = -1 * mult * tran.CuryOpenAmt.GetValueOrDefault();
         *          else
         *              line.Amount = mult * tran.CuryOpenAmt.GetValueOrDefault();
         *          line.Description = tran.TranDesc;
         *          line.DestinationAddress = AddressConverter.ConvertTaxAddress(GetToAddress(order, tran));
         *          line.OriginAddress = AddressConverter.ConvertTaxAddress(GetFromAddress(order, tran));
         *          line.ItemCode = item.InventoryCD;
         *          line.Quantity = Math.Abs(tran.OpenQty.GetValueOrDefault());
         *          line.Discounted = request.Discount > 0;
         *          line.RevAcct = salesAccount.AccountCD;
         *
         *          line.TaxCode = tran.TaxCategoryID;
         *
         *          request.CartItems.Add(line);
         *      }
         *  }
         *
         *  sw.Stop();
         *  Debug.Print("BuildGetTaxRequestOpen() in {0} millisec.", sw.ElapsedMilliseconds);
         *
         *  return request;
         * }
         */
        /*protected virtual GetTaxRequest BuildGetTaxRequestUnbilled(FSAppointment order)
         * {
         *  Stopwatch sw = new Stopwatch();
         *  sw.Start();
         *
         *  if (order == null)
         *      throw new PXArgumentException(ErrorMessages.ArgumentNullException);
         *
         *  Customer cust = (Customer)Base.TaxCustomer.View.SelectSingleBound(new object[] { order });
         *  Location loc = (Location)Base.TaxLocation.View.SelectSingleBound(new object[] { order });
         *
         *  IAddressBase fromAddress = GetFromAddress(order);
         *  IAddressBase toAddress = GetToAddress(order);
         *
         *  if (fromAddress == null)
         *      throw new PXException(Messages.FailedGetFromAddressSO);
         *
         *  if (toAddress == null)
         *      throw new PXException(Messages.FailedGetToAddressSO);
         *
         *  GetTaxRequest request = new GetTaxRequest();
         *  request.CompanyCode = CompanyCodeFromBranch(order.TaxZoneID, order.BranchID);
         *  request.CurrencyCode = order.CuryID;
         *  request.CustomerCode = cust.AcctCD;
         *  request.OriginAddress = AddressConverter.ConvertTaxAddress(fromAddress);
         *  request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress);
         *  request.DocCode = string.Format("{0}.{1}.Open", order.SrvOrdType, order.RefNbr);
         *  request.DocDate = order.ScheduledDateTimeBegin.GetValueOrDefault();
         *  request.LocationCode = GetExternalTaxProviderLocationCode(order);
         *
         *  int mult = 1;
         *
         *  if (!string.IsNullOrEmpty(order.AvalaraCustomerUsageType))
         *  {
         *      request.CustomerUsageType = order.AvalaraCustomerUsageType;
         *  }
         *  if (!string.IsNullOrEmpty(loc.CAvalaraExemptionNumber))
         *  {
         *      request.ExemptionNo = loc.CAvalaraExemptionNumber;
         *  }
         *
         *  FSSrvOrdType srvOrdType = (FSSrvOrdType)Base.ServiceOrderTypeSelected.View.SelectSingleBound(new object[] { order });
         *
         *  if (srvOrdType.DefaultOperation == SOOperation.Receipt)
         *  {
         *      request.DocType = TaxDocumentType.ReturnOrder;
         *      mult = -1;
         *
         *      PXSelectBase<FSAppointmentDet> selectLineWithInvoiceDate = new PXSelect<FSAppointmentDet,
         *      Where<FSAppointmentDet.srvOrdType, Equal<Required<FSAppointmentDet.srvOrdType>>, And<FSAppointmentDet.refNbr, Equal<Required<FSAppointmentDet.refNbr>>,
         *      And<FSAppointmentDet.invoiceDate, IsNotNull>>>>(Base);
         *
         *      FSAppointmentDet soLine = selectLineWithInvoiceDate.SelectSingle(order.SrvOrdType, order.RefNbr);
         *      if (soLine != null && soLine.TranDate != null)
         *      {
         *          request.TaxOverride.Reason = Messages.ReturnReason;
         *          request.TaxOverride.TaxDate = soLine.TranDate.Value;
         *          request.TaxOverride.TaxOverrideType = TaxOverrideType.TaxDate;
         *      }
         *
         *  }
         *  else
         *  {
         *      request.DocType = TaxDocumentType.SalesOrder;
         *  }
         *
         *
         *  PXSelectBase<FSAppointmentDet> select = new PXSelectJoin<FSAppointmentDet,
         *      LeftJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<FSAppointmentDet.inventoryID>>,
         *          LeftJoin<Account, On<Account.accountID, Equal<FSAppointmentDet.salesAcctID>>>>,
         *      Where<FSAppointmentDet.srvOrdType, Equal<Current<FSAppointment.srvOrdType>>,
         *          And<FSAppointmentDet.refNbr, Equal<Current<FSAppointment.refNbr>>>>,
         *      OrderBy<Asc<FSAppointmentDet.srvOrdType, Asc<FSAppointmentDet.refNbr, Asc<FSAppointmentDet.lineNbr>>>>>(Base);
         *
         *  request.Discount = order.CuryDiscTot.GetValueOrDefault();
         *
         *  foreach (PXResult<FSAppointmentDet, InventoryItem, Account> res in select.View.SelectMultiBound(new object[] { order }))
         *  {
         *      FSAppointmentDet tran = (FSAppointmentDet)res;
         *      InventoryItem item = (InventoryItem)res;
         *      Account salesAccount = (Account)res;
         *
         *      if (tran.UnbilledAmt >= 0)
         *      {
         *          var line = new TaxCartItem();
         *          line.Index = tran.LineNbr ?? 0;
         *          if (srvOrdType.DefaultOperation != tran.Operation)
         *              line.Amount = -1 * mult * tran.CuryUnbilledAmt.GetValueOrDefault();
         *          else
         *              line.Amount = mult * tran.CuryUnbilledAmt.GetValueOrDefault();
         *          line.Description = tran.TranDesc;
         *          line.DestinationAddress = AddressConverter.ConvertTaxAddress(GetToAddress(order, tran));
         *          line.OriginAddress = AddressConverter.ConvertTaxAddress(GetFromAddress(order, tran));
         *          line.ItemCode = item.InventoryCD;
         *          line.Quantity = Math.Abs(tran.UnbilledQty.GetValueOrDefault());
         *          line.Discounted = request.Discount > 0;
         *          line.RevAcct = salesAccount.AccountCD;
         *
         *          line.TaxCode = tran.TaxCategoryID;
         *
         *          request.CartItems.Add(line);
         *      }
         *  }
         *
         *  sw.Stop();
         *  Debug.Print("BuildGetTaxRequestUnbilled() in {0} millisec.", sw.ElapsedMilliseconds);
         *
         *  return request;
         * }
         */
        /*protected virtual GetTaxRequest BuildGetTaxRequestFreight(FSAppointment order)
         * {
         *  Stopwatch sw = new Stopwatch();
         *  sw.Start();
         *
         *  if (order == null)
         *      throw new PXArgumentException(ErrorMessages.ArgumentNullException);
         *
         *  Customer cust = (Customer)Base.TaxCustomer.View.SelectSingleBound(new object[] { order });
         *  Location loc = (Location)Base.TaxLocation.View.SelectSingleBound(new object[] { order });
         *
         *  IAddressBase fromAddress = GetFromAddress(order);
         *  IAddressBase toAddress = GetToAddress(order);
         *
         *  if (fromAddress == null)
         *      throw new PXException(PX.Objects.CR.Messages.FailedGetFromAddressCR);
         *
         *  if (toAddress == null)
         *      throw new PXException(PX.Objects.CR.Messages.FailedGetToAddressCR);
         *
         *  GetTaxRequest request = new GetTaxRequest();
         *  request.CompanyCode = CompanyCodeFromBranch(order.TaxZoneID, order.BranchID);
         *  request.CurrencyCode = order.CuryID;
         *  request.CustomerCode = cust.AcctCD;
         *  request.OriginAddress = AddressConverter.ConvertTaxAddress(fromAddress);
         *  request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress);
         *  request.DocCode = $"{order.SrvOrdType}.{order.RefNbr}.Freight";
         *  request.DocDate = order.ScheduledDateTimeBegin.GetValueOrDefault();
         *  request.LocationCode = GetExternalTaxProviderLocationCode(order);
         *
         *  int mult = 1;
         *
         *  if (!string.IsNullOrEmpty(loc.CAvalaraCustomerUsageType))
         *  {
         *      request.CustomerUsageType = loc.CAvalaraCustomerUsageType;
         *  }
         *  if (!string.IsNullOrEmpty(loc.CAvalaraExemptionNumber))
         *  {
         *      request.ExemptionNo = loc.CAvalaraExemptionNumber;
         *  }
         *
         *  FSSrvOrdType srvOrdType = (FSSrvOrdType)Base.ServiceOrderTypeSelected.View.SelectSingleBound(new object[] { order });
         *
         *  if (srvOrdType.ARDocType == ARDocType.CreditMemo)
         *  {
         *      request.DocType = TaxDocumentType.ReturnOrder;
         *      mult = -1;
         *  }
         *  else
         *  {
         *      request.DocType = TaxDocumentType.SalesOrder;
         *  }
         *
         *  if (order.CuryFreightTot > 0)
         *  {
         *      var line = new TaxCartItem();
         *      line.Index = short.MaxValue;
         *      line.Amount = mult * order.CuryFreightTot.GetValueOrDefault();
         *      line.Description = PXMessages.LocalizeNoPrefix(Messages.FreightDesc);
         *      line.DestinationAddress = request.DestinationAddress;
         *      line.OriginAddress = request.OriginAddress;
         *      line.ItemCode = "N/A";
         *      line.Discounted = false;
         *      line.TaxCode = order.FreightTaxCategoryID;
         *
         *      request.CartItems.Add(line);
         *  }
         *
         *  sw.Stop();
         *  Debug.Print("BuildGetTaxRequestFreight() in {0} millisec.", sw.ElapsedMilliseconds);
         *
         *  return request;
         * }
         */
        protected virtual void ApplyTax(FSAppointment order, GetTaxResult result, GetTaxResult resultOpen, GetTaxResult resultUnbilled, GetTaxResult resultFreight)
        {
            TaxZone taxZone = (TaxZone)Base.TaxZone.View.SelectSingleBound(new object[] { order });

            if (taxZone == null)
            {
                throw new PXException(PX.Objects.SO.Messages.TaxZoneIsNotSet);
            }

            AP.Vendor vendor = PXSelect <AP.Vendor, Where <AP.Vendor.bAccountID, Equal <Required <AP.Vendor.bAccountID> > > > .Select(Base, taxZone.TaxVendorID);

            if (vendor == null)
            {
                throw new PXException(PX.Objects.CR.Messages.ExternalTaxVendorNotFound);
            }

            /*var sign = ((FSSrvOrdType)Base.ServiceOrderTypeSelected.View.SelectSingleBound(new object[] { order })).DefaultOperation == SOOperation.Receipt
             *  ? Sign.Minus
             *  : Sign.Plus;*/
            var sign = Sign.Plus;

            if (result != null)
            {
                //Clear all existing Tax transactions:
                foreach (PXResult <FSAppointmentTaxTran, Tax> res in Base.Taxes.View.SelectMultiBound(new object[] { order }))
                {
                    FSAppointmentTaxTran taxTran = res;
                    Base.Taxes.Delete(taxTran);
                }

                Base.Views.Caches.Add(typeof(Tax));

                decimal freightTax = 0;
                if (resultFreight != null)
                {
                    freightTax = sign * resultFreight.TotalTaxAmount;
                }

                //bool requireControlTotal = Base.ServiceOrderTypeSelected.Current.RequireControlTotal == true;

                /*if (order.Hold != true)
                 *  Base.ServiceOrderTypeSelected.Current.RequireControlTotal = false;*/

                var taxDetails = new List <PX.TaxProvider.TaxDetail>();
                foreach (TaxProvider.TaxDetail tax in result.TaxSummary.OrderByDescending(e => e.TaxAmount))
                {
                    if (tax.TaxAmount != 0 ||
                        taxDetails.Find(e => e.TaxName == tax.TaxName) == default(TaxProvider.TaxDetail))
                    {
                        taxDetails.Add(tax);
                    }
                }

                if (resultFreight != null)
                {
                    foreach (TaxProvider.TaxDetail tax in resultFreight.TaxSummary.OrderByDescending(e => e.TaxAmount))
                    {
                        if (tax.TaxAmount != 0 ||
                            taxDetails.Find(e => e.TaxName == tax.TaxName) == default(TaxProvider.TaxDetail))
                        {
                            taxDetails.Add(tax);
                        }
                    }
                }

                try
                {
                    foreach (var taxDetail in taxDetails)
                    {
                        string taxID = taxDetail.TaxName;

                        if (string.IsNullOrEmpty(taxID))
                        {
                            taxID = taxDetail.JurisCode;
                        }

                        if (string.IsNullOrEmpty(taxID))
                        {
                            PXTrace.WriteInformation(PX.Objects.SO.Messages.EmptyValuesFromExternalTaxProvider);
                            continue;
                        }

                        CreateTax(Base, taxZone, vendor, taxDetail, taxID);

                        FSAppointmentTaxTran tax = (FSAppointmentTaxTran)Base.Taxes.Cache.CreateInstance();;

                        tax.TaxID          = taxID;
                        tax.CuryTaxAmt     = Math.Abs(taxDetail.TaxAmount);
                        tax.CuryTaxableAmt = Math.Abs(taxDetail.TaxableAmount);
                        tax.TaxRate        = Convert.ToDecimal(taxDetail.Rate) * 100;
                        tax.JurisType      = taxDetail.JurisType;
                        tax.JurisName      = taxDetail.JurisName;

                        Base.Taxes.Insert(tax);
                    }

                    Base.AppointmentSelected.SetValueExt <FSAppointment.curyTaxTotal>(order, sign * result.TotalTaxAmount + freightTax);

                    decimal?СuryDocTotal = AppointmentEntry.GetCuryDocTotal(order.CuryBillableLineTotal, order.CuryLogBillableTranAmountTotal, order.CuryDiscTot, order.CuryTaxTotal, 0);
                    Base.AppointmentSelected.SetValueExt <FSAppointment.curyDocTotal>(order, СuryDocTotal ?? 0m);
                }
                finally
                {
                    //Base.ServiceOrderTypeSelected.Current.RequireControlTotal = requireControlTotal;
                }
            }


            /*if (resultUnbilled != null)
             *  Base.AppointmentRecords.SetValueExt<FSAppointment.curyUnbilledTaxTotal>(order, sign * resultUnbilled.TotalTaxAmount);
             *
             * if (resultOpen != null)
             *  Base.AppointmentRecords.SetValueExt<FSAppointment.curyOpenTaxTotal>(order, sign * resultOpen.TotalTaxAmount);*/

            order            = (FSAppointment)Base.AppointmentSelected.Cache.CreateCopy(order);
            order.IsTaxValid = true;
            Base.AppointmentSelected.Cache.Update(order);

            if (Base.TimeStamp == null)
            {
                Base.SelectTimeStamp();
            }

            SkipTaxCalcAndSave();
        }