Esempio n. 1
0
        public virtual CommitTaxRequest BuildCommitTaxRequestWithFrt(ARInvoice invoice)
        {
            if (invoice == null)
            {
                throw new PXArgumentException(nameof(invoice), ErrorMessages.ArgumentNullException);
            }

            Customer cust = (Customer)Base.customer.View.SelectSingleBound(new object[] { invoice });

            CR.Location loc = (CR.Location)Base.location.View.SelectSingleBound(new object[] { invoice });

            CommitTaxRequest request = new CommitTaxRequest();

            request.CompanyCode       = Base1.CompanyCodeFromBranch(invoice.TaxZoneID, invoice.BranchID);
            request.CurrencyCode      = invoice.CuryID;
            request.CustomerCode      = cust.AcctCD;
            request.TaxRegistrationID = loc?.TaxRegistrationID;
            IAddressBase fromAddress = Base1.GetFromAddress(invoice);
            IAddressBase toAddress   = Base1.GetToAddress(invoice);

            if (fromAddress == null)
            {
                throw new PXException(Messages.FailedGetFrom);
            }

            if (toAddress == null)
            {
                throw new PXException(Messages.FailedGetTo);
            }

            request.OriginAddress      = AddressConverter.ConvertTaxAddress(fromAddress);
            request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress);
            request.DocCode            = $"AR.{invoice.DocType}.{invoice.RefNbr}";
            request.DocDate            = invoice.DocDate.GetValueOrDefault();
            request.LocationCode       = GetExternalTaxProviderLocationCode <ARTran, ARTran.FK.Invoice.SameAsCurrent, ARTran.siteID>(invoice);
            request.CustomerUsageType  = invoice.AvalaraCustomerUsageType;

            if (!string.IsNullOrEmpty(invoice.ExternalTaxExemptionNumber))
            {
                request.ExemptionNo = invoice.ExternalTaxExemptionNumber;
            }

            request.DocType = Base1.GetTaxDocumentType(invoice);
            Sign sign = Base1.GetDocumentSign(invoice);

            PXSelectBase <ARTran> select = new PXSelectJoin <ARTran, LeftJoin <InventoryItem, On <InventoryItem.inventoryID, Equal <ARTran.inventoryID> >,
                                                                               LeftJoin <Account, On <Account.accountID, Equal <ARTran.accountID> > > >,
                                                             Where <ARTran.tranType, Equal <Current <ARInvoice.docType> >,
                                                                    And <ARTran.refNbr, Equal <Current <ARInvoice.refNbr> >,
                                                                         And <Where <ARTran.lineType, NotEqual <SOLineType.discount>, Or <ARTran.lineType, IsNull> > > > >,
                                                             OrderBy <Asc <ARTran.tranType, Asc <ARTran.refNbr, Asc <ARTran.lineNbr> > > > >(Base);

            request.Discount = Base.Document.Current.CuryDiscTot.GetValueOrDefault();
            DateTime?taxDate = invoice.OrigDocDate;

            bool applyRetainage = Base.ARSetup.Current?.RetainTaxes != true && invoice.IsOriginalRetainageDocument();

            /// <summary>
            /// Add the following condition and logic per Jira [IP-23]
            /// </summary>>
            string taxCategory = (Base as SOInvoiceEntry).FreightDetails.Current?.TaxCategoryID;

            if (invoice.CuryFreightTot > 0 && GL.Branch.PK.Find(Base, Base.Accessinfo.BranchID).CountryID == Country_US && invoice.TaxZoneID == TaxCloud && !string.IsNullOrEmpty(taxCategory))
            {
                var line = new TaxCartItem();
                line.Index              = short.MinValue;
                line.Quantity           = 1;
                line.UOM                = "EA";
                line.Amount             = sign * invoice.CuryFreightTot.GetValueOrDefault();
                line.Description        = PXMessages.LocalizeNoPrefix(SO.Messages.FreightDesc);
                line.DestinationAddress = request.DestinationAddress;
                line.OriginAddress      = request.OriginAddress;
                line.ItemCode           = "N/A";
                line.Discounted         = false;
                line.TaxCode            = taxCategory;

                request.CartItems.Add(line);
            }

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

                var line = new TaxCartItem();
                line.Index              = tran.LineNbr ?? 0;
                line.Amount             = sign * (tran.CuryTranAmt.GetValueOrDefault() + (applyRetainage ? tran.CuryRetainageAmt.GetValueOrDefault() : 0m));
                line.Description        = tran.TranDesc;
                line.DestinationAddress = AddressConverter.ConvertTaxAddress(Base1.GetToAddress(invoice, tran));
                line.OriginAddress      = AddressConverter.ConvertTaxAddress(Base1.GetFromAddress(invoice, tran));
                line.ItemCode           = item.InventoryCD;
                line.Quantity           = Math.Abs(tran.Qty.GetValueOrDefault());
                line.UOM        = tran.UOM;
                line.Discounted = tran.LineType != SOLineType.Freight && request.Discount > 0;
                line.RevAcct    = salesAccount.AccountCD;

                line.TaxCode           = tran.TaxCategoryID;
                line.CustomerUsageType = tran.AvalaraCustomerUsageType;

                if (tran.OrigInvoiceDate != null)
                {
                    taxDate = tran.OrigInvoiceDate;
                }

                request.CartItems.Add(line);
            }

            if (applyRetainage)
            {
                var line = new TaxCartItem();
                line.Index              = invoice.LineCntr.GetValueOrDefault() + 1;
                line.Amount             = Sign.Minus * sign * invoice.CuryLineRetainageTotal.GetValueOrDefault();
                line.Description        = PXMessages.LocalizeFormatNoPrefix(AP.Messages.RetainageForTransactionDescription, GetLabel.For <ARDocType>(invoice.DocType), invoice.RefNbr);
                line.DestinationAddress = request.DestinationAddress;
                line.OriginAddress      = request.OriginAddress;
                line.ItemCode           = "Retainage";
                line.Discounted         = false;
                line.NonTaxable         = true;

                request.CartItems.Add(line);
            }

            if ((invoice.DocType == ARDocType.CreditMemo || invoice.DocType == ARDocType.CashReturn) && invoice.OrigDocDate != null)
            {
                request.TaxOverride.Reason          = Messages.ReturnReason;
                request.TaxOverride.TaxDate         = taxDate.Value;
                request.TaxOverride.TaxOverrideType = TaxOverrideType.TaxDate;
                sign = Sign.Minus;
            }

            return(request);
        }
Esempio n. 2
0
        protected GetTaxRequest BuildGetTaxRequestWithFRTCate <TLineAmt, TLineQty, TDocDiscount>(SOOrder order, string docCode, string debugMethodName)
            where TLineAmt : IBqlField
            where TLineQty : IBqlField
            where TDocDiscount : IBqlField
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();
            Debug.Indent();

            if (order == null)
            {
                throw new PXArgumentException(nameof(order));
            }

            Customer cust = (Customer)Base.customer.View.SelectSingleBound(new object[] { order });
            Location loc  = (Location)Base.location.View.SelectSingleBound(new object[] { order });

            IAddressBase fromAddress = GetFromAddress(order);
            IAddressBase toAddress   = GetToAddress(order);

            Debug.Print($"{DateTime.Now.TimeOfDay} Select Customer, Location, Addresses in {sw.ElapsedMilliseconds} millisec");

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

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

            GetTaxRequest request = new GetTaxRequest();

            request.CompanyCode        = Base1.CompanyCodeFromBranch(order.TaxZoneID, order.BranchID);
            request.CurrencyCode       = order.CuryID;
            request.CustomerCode       = cust.AcctCD;
            request.TaxRegistrationID  = loc?.TaxRegistrationID;
            request.OriginAddress      = AddressConverter.ConvertTaxAddress(fromAddress);
            request.DestinationAddress = AddressConverter.ConvertTaxAddress(toAddress);
            request.DocCode            = docCode;
            request.DocDate            = order.OrderDate.GetValueOrDefault();
            request.LocationCode       = GetExternalTaxProviderLocationCode <SOLine, SOLine.FK.Order.SameAsCurrent, SOLine.siteID>(order);

            Sign docSign = Sign.Plus;

            request.CustomerUsageType = order.AvalaraCustomerUsageType;

            if (!string.IsNullOrEmpty(order.ExternalTaxExemptionNumber))
            {
                request.ExemptionNo = order.ExternalTaxExemptionNumber;
            }

            SOOrderType orderType = (SOOrderType)Base.soordertype.View.SelectSingleBound(new object[] { order });

            if (orderType.DefaultOperation == SOOperation.Receipt)
            {
                request.DocType = TaxDocumentType.ReturnOrder;
                docSign         = Sign.Minus;
            }
            else
            {
                request.DocType = TaxDocumentType.SalesOrder;
            }

            PXSelectBase <SOLine> select = new PXSelectJoin <SOLine, LeftJoin <InventoryItem, On <SOLine.FK.InventoryItem>,
                                                                               LeftJoin <Account, On <Account.accountID, Equal <SOLine.salesAcctID> > > >,
                                                             Where <SOLine.orderType, Equal <Current <SOOrder.orderType> >,
                                                                    And <SOLine.orderNbr, Equal <Current <SOOrder.orderNbr> > > >,
                                                             OrderBy <Asc <SOLine.orderType,
                                                                           Asc <SOLine.orderNbr,
                                                                                Asc <SOLine.lineNbr> > > > >(Base);

            PXCache documentCache = Base.Caches[typeof(SOOrder)];

            request.Discount = (documentCache.GetValue <TDocDiscount>(order) as decimal?) ?? 0m;

            Stopwatch sw2 = new Stopwatch();

            sw2.Start();

            // Add additional condition to skip the calculation including the freight amount. Per YJ's request.
            if (order.CuryFreightTot > 0 && !string.IsNullOrEmpty(order.FreightTaxCategoryID))
            {
                var line = new TaxCartItem();
                line.Index              = short.MinValue;
                line.Quantity           = 1;
                line.UOM                = "EA";
                line.Amount             = docSign * 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);
            }

            PXCache lineCache = Base.Caches[typeof(SOLine)];

            foreach (PXResult <SOLine, InventoryItem, Account> res in select.View.SelectMultiBound(new object[] { order }))
            {
                SOLine        tran             = (SOLine)res;
                InventoryItem item             = (InventoryItem)res;
                Account       salesAccount     = (Account)res;
                bool          lineIsDiscounted = request.Discount > 0m &&
                                                 ((tran.DocumentDiscountRate ?? 1m) != 1m || (tran.GroupDiscountRate ?? 1m) != 1m);

                var line = new TaxCartItem();
                line.Index = tran.LineNbr ?? 0;

                decimal lineAmount = (lineCache.GetValue <TLineAmt>(tran) as decimal?) ?? 0m;
                decimal lineQty    = (lineCache.GetValue <TLineQty>(tran) as decimal?) ?? 0m;

                line.Amount = orderType.DefaultOperation != tran.Operation
                                        ? Sign.Minus * docSign * lineAmount
                                        : docSign * lineAmount;

                line.Description        = tran.TranDesc;
                line.DestinationAddress = AddressConverter.ConvertTaxAddress(Base1.GetToAddress(order, tran));
                line.OriginAddress      = AddressConverter.ConvertTaxAddress(Base1.GetFromAddress(order, tran));
                line.ItemCode           = item.InventoryCD;
                line.Quantity           = Math.Abs(lineQty);
                line.UOM        = tran.UOM;
                line.Discounted = lineIsDiscounted;
                line.RevAcct    = salesAccount.AccountCD;

                line.TaxCode           = tran.TaxCategoryID;
                line.CustomerUsageType = tran.AvalaraCustomerUsageType;

                if (tran.Operation == SOOperation.Receipt && tran.InvoiceDate != null)
                {
                    line.TaxOverride.Reason          = Messages.ReturnReason;
                    line.TaxOverride.TaxDate         = tran.InvoiceDate.Value;
                    line.TaxOverride.TaxOverrideType = TaxOverrideType.TaxDate;
                }

                request.CartItems.Add(line);
            }

            sw2.Stop();
            Debug.Print($"{DateTime.Now.TimeOfDay} Select detail lines in {sw2.ElapsedMilliseconds} millisec.");

            Debug.Unindent();
            sw.Stop();
            Debug.Print($"{DateTime.Now.TimeOfDay} {debugMethodName}() in {sw.ElapsedMilliseconds} millisec.");

            return(request);
        }