예제 #1
0
        public static void Process(CROpportunity doc)
        {
            List <CROpportunity> list = new List <CROpportunity>();

            list.Add(doc);
            Process(list, false);
        }
예제 #2
0
        public static void CalculateAvalaraTax(OpportunityMaint rg, CROpportunity order)
        {
            TaxSvc service = new TaxSvc();

            AvalaraMaint.SetupService(rg, service);

            AddressSvc addressService = new AddressSvc();

            AvalaraMaint.SetupService(rg, addressService);

            GetTaxRequest getRequest       = null;
            bool          isValidByDefault = true;

            if (order.IsTaxValid != true)
            {
                getRequest = BuildGetTaxRequest(rg, order);

                if (getRequest.Lines.Count > 0)
                {
                    isValidByDefault = false;
                }
                else
                {
                    getRequest = null;
                }
            }

            if (isValidByDefault)
            {
                PXDatabase.Update <CROpportunity>(
                    new PXDataFieldAssign("IsTaxValid", true),
                    new PXDataFieldRestrict("OpportunityID", PXDbType.NVarChar, CROpportunity.OpportunityIDLength, order.OpportunityID, PXComp.EQ)
                    );
                return;
            }

            GetTaxResult result = service.GetTax(getRequest);

            if (result.ResultCode == SeverityLevel.Success)
            {
                try
                {
                    ApplyAvalaraTax(rg, order, result);
                    PXDatabase.Update <CROpportunity>(
                        new PXDataFieldAssign("IsTaxValid", true),
                        new PXDataFieldRestrict("OpportunityID", PXDbType.NVarChar, CROpportunity.OpportunityIDLength, order.OpportunityID, PXComp.EQ)
                        );
                }
                catch (Exception ex)
                {
                    throw new PXException(ex, TX.Messages.FailedToApplyTaxes);
                }
            }
            else
            {
                LogMessages(result);

                throw new PXException(TX.Messages.FailedToGetTaxes);
            }
        }
예제 #3
0
        public virtual IEnumerable ConvertToOpportunity(PXAdapter adapter)
        {
            bool           isOpportunityAutoNumberOn = this.IsNumberingAutonumbered(Setup.Current.OpportunityNumberingID);
            List <Contact> contacts = new List <Contact>(adapter.Get().Cast <Contact>());

            foreach (Contact lead in contacts)
            {
                OpportunityMaint opportunityMaint = PXGraph.CreateInstance <OpportunityMaint>();
                CROpportunity    opportunity      = (CROpportunity)opportunityMaint.Opportunity.Cache.CreateInstance();

                if (!isOpportunityAutoNumberOn)
                {
                    if (OpportunityInfo.AskExt() != WebDialogResult.OK || !OpportunityInfo.VerifyRequired())
                    {
                        return(contacts);
                    }
                    CROpportunity existing = PXSelect <CROpportunity, Where <CROpportunity.opportunityID, Equal <Required <CROpportunity.opportunityID> > > > .SelectSingleBound(this, null, OpportunityInfo.Current.OpportunityID);

                    if (existing != null)
                    {
                        OpportunityInfo.Cache.RaiseExceptionHandling <OpportunityFilter.opportunityID>(OpportunityInfo.Current, OpportunityInfo.Current.OpportunityID, new PXSetPropertyException(Messages.OpportunityAlreadyExists, OpportunityInfo.Current.OpportunityID));
                        return(contacts);
                    }

                    object cd = OpportunityInfo.Current.OpportunityID;
                    opportunityMaint.Opportunity.Cache.RaiseFieldUpdating <CROpportunity.opportunityID>(null, ref cd);
                    opportunity.OpportunityID = (string)cd;
                }
                PXLongOperation.StartOperation(this, delegate()
                {
                    CRContactClass cls = PXSelect <CRContactClass, Where <CRContactClass.classID, Equal <Current <Contact.classID> > > > .SelectSingleBound(this, new object[] { lead });
                    if (cls != null && cls.OwnerToOpportunity == true)
                    {
                        opportunity.WorkgroupID = lead.WorkgroupID;
                        opportunity.OwnerID     = lead.OwnerID;
                    }

                    if (lead.BAccountID != null)
                    {
                        opportunity.BAccountID = lead.BAccountID;
                    }
                    opportunity.ContactID = lead.ContactID;
                    opportunity           = (CROpportunity)opportunityMaint.Opportunity.Cache.Insert(opportunity);

                    ContactMaint contactGraph = PXGraph.CreateInstance <ContactMaint>();
                    lead.ContactType          = ContactTypesAttribute.Person;
                    contactGraph.Contact.Update(lead);
                    contactGraph.Save.Press();

                    opportunityMaint.Opportunity.Search <CROpportunity.opportunityID>(opportunity.OpportunityID);

                    throw new PXRedirectRequiredException(opportunityMaint, "Opportunity", true);
                });
            }
            return(contacts);
        }
예제 #4
0
        public virtual FLXProject CreateProject(CROpportunityProducts opporProd)
        {
            CROpportunity current    = this.Base.Opportunity.Current;
            FLXProject    flxProject = new FLXProject();
            PXFieldState  valueExt1  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeSALESREP") as PXFieldState;
            PXFieldState  valueExt2  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeSALESPERSO") as PXFieldState;
            PXFieldState  valueExt3  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeINDUSTRY") as PXFieldState;
            PXFieldState  valueExt4  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeAPPLICATIO") as PXFieldState;
            PXFieldState  valueExt5  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeDESIGNINPA") as PXFieldState;
            PXFieldState  valueExt6  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeCM") as PXFieldState;
            PXFieldState  valueExt7  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeDISTRY") as PXFieldState;
            PXFieldState  valueExt8  = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeENDCUSTOME") as PXFieldState;

            if (valueExt1.Value != null)
            {
                flxProject.SalesRepID = new int?((int)PXSelectorAttribute.GetField(this.Base.bAccountBasic.Cache, (object)this.Base.BAccounts, "acctCD", valueExt1.Value, "bAccountID"));
            }
            if (valueExt2.Value != null)
            {
                flxProject.SalespersonID = new int?((int)PXSelectorAttribute.GetField(this.SalesPersonView.Cache, (object)this.SalesPersonView, "salesPersonCD", valueExt2.Value, "SalesPersonID"));
            }
            if (valueExt6.Value != null)
            {
                flxProject.CM = new int?((int)PXSelectorAttribute.GetField(this.Base.bAccountBasic.Cache, (object)this.Base.BAccounts, "acctCD", valueExt6.Value, "bAccountID"));
            }
            if (valueExt7.Value != null)
            {
                flxProject.Distributor = new int?((int)PXSelectorAttribute.GetField(this.Base.bAccountBasic.Cache, (object)this.Base.BAccounts, "acctCD", valueExt7.Value, "bAccountID"));
            }
            flxProject.Industry      = valueExt3.Value == null ? (string)null : valueExt3.Value.ToString();
            flxProject.Application   = valueExt4.Value == null ? (string)null : valueExt4.Value.ToString();
            flxProject.CountryID     = valueExt5.Value == null ? (string)null : OpportunityMaint_Extension.GetAddressCountry((PXGraph)this.Base, (string)valueExt5.Value);
            flxProject.EndCustomerID = new int?((int)PXSelectorAttribute.GetField(this.Base.bAccountBasic.Cache, (object)this.Base.BAccounts, "acctCD", valueExt8.Value, "bAccountID"));
            flxProject.OpportunityID = current.OpportunityID;
            flxProject.CustomerID    = current.BAccountID;
            flxProject.OpporLineNbr  = opporProd.LineNbr;
            flxProject.EAU           = opporProd.Qty;
            flxProject.VendorID      = opporProd.VendorID;
            flxProject.Descr         = opporProd.Descr;
            switch (OpportunityMaint_Extension.GetItemType((PXGraph)this.Base, opporProd.InventoryID))
            {
            case "F":
            case "M":
            case "A":
                flxProject.StockItem = opporProd.InventoryID;
                break;

            default:
                flxProject.NonStockItem = opporProd.InventoryID;
                break;
            }
            return(flxProject);
        }
예제 #5
0
        protected virtual void Contact_BAccountID_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            Contact contact = (Contact)e.Row;

            if (contact.BAccountID != (int?)e.NewValue && contact.ContactID > 0)
            {
                CRCase        crCase = Cases.SelectSingle();
                CROpportunity op     = Opportunities.SelectSingle();
                if (crCase != null || op != null)
                {
                    throw new PXSetPropertyException(Messages.CannotChangeBAccount);
                }
            }
        }
예제 #6
0
        public virtual FLXCommissionTable CreateComisionTable(
            CROpportunityProducts opporProd)
        {
            FLXCommissionTable flxCommissionTable = new FLXCommissionTable();
            CROpportunity      current            = this.Base.Opportunity.Current;
            PXFieldState       valueExt           = this.Base.Opportunity.Cache.GetValueExt((object)current, "AttributeENDCUSTOME") as PXFieldState;

            flxCommissionTable.EndCustomerID = new int?((int)PXSelectorAttribute.GetField(this.Base.bAccountBasic.Cache, (object)this.Base.BAccounts, "acctCD", valueExt.Value, "bAccountID"));
            flxCommissionTable.CustomerID    = current.BAccountID;
            flxCommissionTable.OpportunityID = current.OpportunityID;
            flxCommissionTable.OpporLineNbr  = opporProd.LineNbr;
            flxCommissionTable.NonStock      = opporProd.InventoryID;
            return(flxCommissionTable);
        }
예제 #7
0
        protected static IAddressBase GetToAddress(OpportunityMaint rg, CROpportunity order)
        {
            Address shipAddress = null;

            Location loc = (Location)PXSelect <Location,
                                               Where <Location.bAccountID, Equal <Required <Location.bAccountID> >, And <Location.locationID, Equal <Required <Location.locationID> > > > > .
                           Select(rg, order.BAccountID, order.LocationID);

            if (loc != null)
            {
                shipAddress = PXSelect <Address, Where <Address.addressID, Equal <Required <Address.addressID> > > > .Select(rg, loc.DefAddressID);
            }

            return(shipAddress);
        }
예제 #8
0
        private bool CanDelete(CROpportunityClass row)
        {
            if (row != null)
            {
                CROpportunity c = PXSelect <CROpportunity,
                                            Where <CROpportunity.classID, Equal <Required <CROpportunity.classID> > > > .
                                  SelectWindowed(this, 0, 1, row.CROpportunityClassID);

                if (c != null)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #9
0
        public virtual void CROpportunityProbability_RowDeleting(PXCache sender, PXRowDeletingEventArgs e)
        {
            if (!e.ExternalCall)
            {
                return;
            }

            CROpportunityProbability probability = e.Row as CROpportunityProbability;

            if (probability == null)
            {
                return;
            }

            // checking if the opportunities with such class exist
            CROpportunity opp = PXSelect <CROpportunity,
                                          Where <CROpportunity.stageID, Equal <Required <CROpportunityProbability.stageCode> > > > .
                                SelectWindowed(this, 0, 1, probability.StageCode);

            if (opp != null)
            {
                throw new PXException(Messages.StageCannotBeDeleted, probability.Name);
            }

            // checking if another classes with such state exists
            List <string> classesWithActiveProbability = new List <string>();

            foreach (CROpportunityClassProbability activeProbabilityInAnotherClass in PXSelect <CROpportunityClassProbability,
                                                                                                Where <CROpportunityClassProbability.stageID, Equal <Required <CROpportunityProbability.stageCode> >,
                                                                                                       And <CROpportunityClassProbability.classID, NotEqual <Current <CROpportunityClass.cROpportunityClassID> > > > > .
                     Select(this, probability.StageCode))
            {
                classesWithActiveProbability.Add(activeProbabilityInAnotherClass.ClassID);
            }
            if (classesWithActiveProbability.Count > 0)
            {
                throw new PXException(Messages.StageIsActiveInClasses, string.Join(", ", classesWithActiveProbability));
            }

            // ask before deleting stage - because it is used in every class
            if (OpportunityProbabilities.Ask(Messages.Warning, Messages.StageWillBeDeletedFromAllClasses, MessageButtons.YesNo, MessageIcon.Warning) != WebDialogResult.Yes)
            {
                e.Cancel = true;
            }
        }
        public virtual IEnumerable ConvertToOpportunity(PXAdapter adapter)
        {
            Save.Press();
            bool           isOpportunityAutoNumberOn = this.IsNumberingAutonumbered(Setup.Current.OpportunityNumberingID);
            List <Contact> contacts = new List <Contact>(adapter.Get().Cast <Contact>());

            foreach (Contact l in contacts)
            {
                OpportunityMaint opportunityMaint = CreateInstance <OpportunityMaint>();
                CROpportunity    opportunity      = (CROpportunity)opportunityMaint.Opportunity.Cache.Insert();

                if (!isOpportunityAutoNumberOn)
                {
                    if (OpportunityInfo.AskExt() != WebDialogResult.OK || !OpportunityInfo.VerifyRequired())
                    {
                        return(contacts);
                    }
                    CROpportunity existing = PXSelect <CROpportunity, Where <CROpportunity.opportunityID, Equal <Required <CROpportunity.opportunityID> > > > .SelectSingleBound(this, null, OpportunityInfo.Current.OpportunityID);

                    if (existing != null)
                    {
                        OpportunityInfo.Cache.RaiseExceptionHandling <OpportunityFilter.opportunityID>(OpportunityInfo.Current, OpportunityInfo.Current.OpportunityID, new PXSetPropertyException(Messages.OpportunityAlreadyExists, OpportunityInfo.Current.OpportunityID));
                        return(contacts);
                    }

                    object cd = OpportunityInfo.Current.OpportunityID;
                    opportunityMaint.Opportunity.Cache.RaiseFieldUpdating <CROpportunity.opportunityID>(null, ref cd);
                    opportunity.OpportunityID = (string)cd;
                }
                Contact lead = l;
                PXLongOperation.StartOperation(this, delegate()
                {
                    CRContactClass cls = PXSelect <CRContactClass, Where <CRContactClass.classID, Equal <Current <Contact.classID> > > > .SelectSingleBound(this, new object[] { lead });
                    if (cls != null && cls.OwnerToOpportunity == true)
                    {
                        opportunity.WorkgroupID = lead.WorkgroupID;
                        opportunity.OwnerID     = lead.OwnerID;
                    }
                    if (cls != null && cls.TargetOpportunityClassID != null)
                    {
                        opportunity.CROpportunityClassID = cls.TargetOpportunityClassID;
                    }

                    if (lead.BAccountID != null)
                    {
                        opportunity.BAccountID = lead.BAccountID;
                    }

                    if (lead.ParentBAccountID != null)
                    {
                        opportunity.ParentBAccountID = lead.ParentBAccountID;
                    }

                    if (lead.CampaignID != null)
                    {
                        opportunity.CampaignSourceID = lead.CampaignID;
                    }
                    opportunity.ContactID       = lead.ContactID;
                    opportunity.ConvertedLeadID = lead.ContactID;
                    opportunity.OpportunityName = string.IsNullOrEmpty(lead.FullName) ? lead.DisplayName : lead.FullName;
                    opportunity = (CROpportunity)opportunityMaint.Opportunity.Cache.Update(opportunity);

                    ContactMaint contactGraph = CreateInstance <ContactMaint>();
                    lead.ContactType          = ContactTypesAttribute.Person;
                    lead.QualificationDate    = PXTimeZoneInfo.Now;
                    lead.ConvertedBy          = Accessinfo.UserID;
                    lead = contactGraph.Contact.Update(lead);

                    opportunityMaint.Opportunity.Search <CROpportunity.opportunityID>(opportunity.OpportunityID);
                    lead = opportunityMaint.Leads.Update(lead);

                    // Copy Note text and Files references
                    CRSetup setup = PXSetupOptional <CRSetup> .Select(opportunityMaint);
                    PXNoteAttribute.CopyNoteAndFiles(opportunityMaint.Leads.Cache, lead, opportunityMaint.OpportunityCurrent.Cache, opportunity, setup);

                    throw new PXRedirectRequiredException(opportunityMaint, "Opportunity", true);
                });
            }
            return(contacts);
        }
예제 #11
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;
            }
        }
예제 #12
0
        protected static GetTaxRequest BuildGetTaxRequest(OpportunityMaint rg, CROpportunity order)
        {
            if (order == null)
            {
                throw new PXArgumentException(ErrorMessages.ArgumentNullException);
            }

            BAccount cust = (BAccount)PXSelect <BAccount,
                                                Where <BAccount.bAccountID, Equal <Required <BAccount.bAccountID> > > > .
                            Select(rg, order.BAccountID);

            Location loc = (Location)PXSelect <Location,
                                               Where <Location.bAccountID, Equal <Required <Location.bAccountID> >, And <Location.locationID, Equal <Required <Location.locationID> > > > > .
                           Select(rg, order.BAccountID, order.LocationID);

            IAddressBase addressFrom = GetFromAddress(rg);
            IAddressBase addressTo   = GetToAddress(rg, order);

            if (addressFrom == null)
            {
                throw new PXException(Messages.FailedGetFromAddressSO);
            }

            if (addressTo == null)
            {
                throw new PXException(Messages.FailedGetToAddressSO);
            }

            var avalaraSetup = (TXAvalaraSetup)PXSetupOptional <TXAvalaraSetup> .Select(rg);

            GetTaxRequest request = new GetTaxRequest();

            request.CompanyCode        = AvalaraMaint.CompanyCodeFromBranch(rg, rg.Accessinfo.BranchID);
            request.CurrencyCode       = order.CuryID;
            request.CustomerCode       = cust.AcctCD;
            request.OriginAddress      = AvalaraMaint.FromAddress(addressFrom);
            request.DestinationAddress = AvalaraMaint.FromAddress(addressTo);
            request.DetailLevel        = DetailLevel.Summary;
            request.DocCode            = string.Format("CR.{0}", order.OpportunityID);
            request.DocDate            = order.CloseDate.GetValueOrDefault();

            int mult = 1;

            if (!string.IsNullOrEmpty(loc.CAvalaraCustomerUsageType))
            {
                request.CustomerUsageType = loc.CAvalaraCustomerUsageType;
            }
            if (!string.IsNullOrEmpty(loc.CAvalaraExemptionNumber))
            {
                request.ExemptionNo = loc.CAvalaraExemptionNumber;
            }

            request.DocType = DocumentType.SalesOrder;

            PXSelectBase <CROpportunityProducts> select = new PXSelectJoin <CROpportunityProducts,
                                                                            LeftJoin <InventoryItem, On <InventoryItem.inventoryID, Equal <CROpportunityProducts.inventoryID> >,
                                                                                      LeftJoin <Account, On <Account.accountID, Equal <InventoryItem.salesAcctID> > > >,
                                                                            Where <CROpportunityProducts.cROpportunityID, Equal <Current <CROpportunity.opportunityID> > >,
                                                                            OrderBy <Asc <CROpportunityProducts.cROpportunityProductID> > >(rg);

            foreach (PXResult <CROpportunityProducts, InventoryItem, Account> res in select.View.SelectMultiBound(new object[] { order }))
            {
                CROpportunityProducts tran = (CROpportunityProducts)res;
                InventoryItem         item = (InventoryItem)res;
                Account salesAccount       = (Account)res;

                Line line = new Line();
                line.No                 = Convert.ToString(tran.CROpportunityProductID);
                line.Amount             = mult * tran.CuryAmount.GetValueOrDefault();
                line.Description        = tran.TransactionDescription;
                line.DestinationAddress = request.DestinationAddress;
                line.OriginAddress      = request.OriginAddress;
                line.ItemCode           = item.InventoryCD;
                line.Qty                = Math.Abs(Convert.ToDouble(tran.Qty.GetValueOrDefault()));
                line.Discounted         = request.Discount > 0;
                line.TaxIncluded        = avalaraSetup.IsInclusiveTax == true;

                if (avalaraSetup != null && avalaraSetup.SendRevenueAccount == true)
                {
                    line.RevAcct = salesAccount.AccountCD;
                }

                line.TaxCode = tran.TaxCategoryID;

                request.Lines.Add(line);
            }

            return(request);
        }
예제 #13
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("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;
            }
        }