예제 #1
0
        public virtual void AddPOOrderProc(POOrder order, bool createNew)
        {
            APInvoice prepayment;

            if (createNew)
            {
                prepayment = Base.Document.Insert(new APInvoice {
                    DocType = APDocType.Prepayment
                });
                prepayment.DocDesc = order.OrderDesc;
                if (PXAccess.FeatureInstalled <FeaturesSet.vendorRelations>())
                {
                    prepayment.VendorID                   = order.PayToVendorID;
                    prepayment.VendorLocationID           = (order.VendorID == order.PayToVendorID) ? order.VendorLocationID : null;
                    prepayment.SuppliedByVendorID         = order.VendorID;
                    prepayment.SuppliedByVendorLocationID = order.VendorLocationID;
                }
                else
                {
                    prepayment.VendorID =
                        prepayment.SuppliedByVendorID         = order.VendorID;
                    prepayment.VendorLocationID               =
                        prepayment.SuppliedByVendorLocationID = order.VendorLocationID;
                }
                prepayment.CuryID = order.CuryID;
                Base.Document.Update(prepayment);
                prepayment.TaxCalcMode = order.TaxCalcMode;
                prepayment.InvoiceNbr  = order.OrderNbr;
                prepayment.DueDate     = order.OrderDate;
                prepayment.TaxZoneID   = order.TaxZoneID;
                Base.Document.Update(prepayment);
            }
            else
            {
                prepayment = Base.Document.Current;
            }

            TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID, TaxAttribute>(Base.Transactions.Cache, null, TaxCalc.ManualCalc);

            var orderLines = PXSelectReadonly <POLineRS,
                                               Where <POLineRS.orderType, Equal <Required <POOrder.orderType> >,
                                                      And <POLineRS.orderNbr, Equal <Required <POOrder.orderNbr> > > >,
                                               OrderBy <Asc <POLineRS.sortOrder, Asc <POLineRS.lineNbr> > > >
                             .Select(Base, order.OrderType, order.OrderNbr)
                             .RowCast <POLineRS>()
                             .ToList();

            bool hasAdded = AddPOOrderLines(orderLines);

            if (!hasAdded)
            {
                throw new PXException(Messages.APInvoicePOOrderCreation_NoApplicableLinesFound);
            }

            Base.AddOrderTaxes(order);

            TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID, TaxAttribute>(Base.Transactions.Cache, null, TaxCalc.ManualLineCalc);
        }
        public virtual APInvoice ReleaseRetainageProc(APInvoice doc, RetainageOptions retainageOpts, bool isAutoRelease = false)
        {
            Base.Clear(PXClearOption.PreserveTimeStamp);

            if (retainageOpts.CuryRetainageAmt <= 0 || retainageOpts.CuryRetainageAmt > doc.CuryRetainageUnreleasedAmt)
            {
                throw new PXException(Messages.IncorrectRetainageAmount);
            }

            // Magic. We need to prevent rewriting of CurrencyInfo.IsReadOnly
            // by true in CurrencyInfoView
            //
            Base.CurrentDocument.Cache.AllowUpdate = true;

            PXResult <APInvoice, CurrencyInfo, Terms, Vendor> resultDoc =
                APInvoice_CurrencyInfo_Terms_Vendor
                .SelectSingleBound(Base, null, doc.DocType, doc.RefNbr, doc.VendorID)
                .Cast <PXResult <APInvoice, CurrencyInfo, Terms, Vendor> >()
                .First();

            CurrencyInfo info        = resultDoc;
            APInvoice    origInvoice = resultDoc;
            Vendor       vendor      = resultDoc;

            CurrencyInfo new_info = PXCache <CurrencyInfo> .CreateCopy(info);

            new_info.CuryInfoID = null;
            new_info.IsReadOnly = false;
            new_info            = PXCache <CurrencyInfo> .CreateCopy(Base.currencyinfo.Insert(new_info));

            APInvoice invoice = PXCache <APInvoice> .CreateCopy(origInvoice);

            invoice.CuryInfoID = new_info.CuryInfoID;
            invoice.DocType    = APDocType.Invoice;
            invoice.RefNbr     = null;
            invoice.LineCntr   = null;
            invoice.InvoiceNbr = retainageOpts.InvoiceNbr;

            // Must be set for _RowSelected event handler
            //
            invoice.OpenDoc  = true;
            invoice.Released = false;

            Base.Document.Cache.SetDefaultExt <APInvoice.isMigratedRecord>(invoice);
            invoice.BatchNbr        = null;
            invoice.PrebookBatchNbr = null;
            invoice.Prebooked       = false;
            invoice.ScheduleID      = null;
            invoice.Scheduled       = false;
            invoice.NoteID          = null;

            invoice.DueDate         = null;
            invoice.DiscDate        = null;
            invoice.CuryOrigDiscAmt = 0m;
            invoice.OrigDocType     = origInvoice.DocType;
            invoice.OrigRefNbr      = origInvoice.RefNbr;
            invoice.OrigDocDate     = origInvoice.DocDate;

            invoice.PaySel              = false;
            invoice.CuryLineTotal       = 0m;
            invoice.IsTaxPosted         = false;
            invoice.IsTaxValid          = false;
            invoice.CuryVatTaxableTotal = 0m;
            invoice.CuryVatExemptTotal  = 0m;

            invoice.CuryDocBal     = 0m;
            invoice.CuryOrigDocAmt = retainageOpts.CuryRetainageAmt;
            invoice.Hold           = !isAutoRelease && Base.apsetup.Current.HoldEntry == true || Base.IsApprovalRequired(invoice, Base.Document.Cache);

            invoice.DocDate     = retainageOpts.DocDate;
            invoice.FinPeriodID = retainageOpts.FinPeriodID;

            Base.ClearRetainageSummary(invoice);
            invoice.RetainageApply      = false;
            invoice.IsRetainageDocument = true;

            invoice = Base.Document.Insert(invoice);

            if (new_info != null)
            {
                CurrencyInfo b_info = (CurrencyInfo)PXSelect <CurrencyInfo,
                                                              Where <CurrencyInfo.curyInfoID, Equal <Current <APInvoice.curyInfoID> > > > .Select(Base);

                b_info.CuryID         = new_info.CuryID;
                b_info.CuryEffDate    = new_info.CuryEffDate;
                b_info.CuryRateTypeID = new_info.CuryRateTypeID;
                b_info.CuryRate       = new_info.CuryRate;
                b_info.RecipRate      = new_info.RecipRate;
                b_info.CuryMultDiv    = new_info.CuryMultDiv;
                Base.currencyinfo.Update(b_info);
            }

            decimal retainagePercent = (decimal)(retainageOpts.CuryRetainageAmt / doc.CuryRetainageTotal);

            PXResultset <APTran> details = PXSelectGroupBy <APTran,
                                                            Where <APTran.tranType, Equal <Required <APTran.tranType> >,
                                                                   And <APTran.refNbr, Equal <Required <APTran.refNbr> >,
                                                                        And <APTran.curyRetainageAmt, NotEqual <decimal0> > > >,
                                                            Aggregate <
                                                                GroupBy <APTran.taxCategoryID,
                                                                         Sum <APTran.curyRetainageAmt> > > >
                                           .Select(Base, doc.DocType, doc.RefNbr);

            APTran  tranNew       = null;
            decimal prevCuryTotal = 0m;

            TaxCalc oldTaxCalc = TaxBaseAttribute.GetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null);

            TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null, TaxCalc.ManualCalc);

            foreach (APTran detail in details)
            {
                // Create APTran record for chosen retainage amount,
                // clear all required fields to prevent tax calculation,
                // discount calculation and retainage calculation.
                // CuryUnitCost = 0m and CuryLineAmt = 0m here to prevent their
                // FieldDefaulting events, because in our case default value
                // should be equal to zero.
                //
                tranNew = Base.Transactions.Insert(new APTran
                {
                    CuryUnitCost = 0m,
                    CuryLineAmt  = 0m
                });

                tranNew.BranchID      = origInvoice.BranchID;
                tranNew.TaxCategoryID = detail.TaxCategoryID;
                tranNew.AccountID     = origInvoice.RetainageAcctID;
                tranNew.SubID         = origInvoice.RetainageSubID;
                tranNew.ProjectID     = ProjectDefaultAttribute.NonProject();

                tranNew.Qty                  = 0m;
                tranNew.CuryUnitCost         = 0m;
                tranNew.ManualDisc           = true;
                tranNew.DiscPct              = 0m;
                tranNew.CuryDiscAmt          = 0m;
                tranNew.RetainagePct         = 0m;
                tranNew.CuryRetainageAmt     = 0m;
                tranNew.CuryTaxableAmt       = 0m;
                tranNew.CuryTaxAmt           = 0;
                tranNew.CuryExpenseAmt       = 0m;
                tranNew.GroupDiscountRate    = 1m;
                tranNew.DocumentDiscountRate = 1m;

                using (new PXLocaleScope(vendor.LocaleName))
                {
                    tranNew.TranDesc = PXMessages.LocalizeFormatNoPrefix(
                        Messages.RetainageForTransactionDescription,
                        APDocTypeDict[origInvoice.DocType],
                        origInvoice.RefNbr);
                }

                prevCuryTotal       = (retainageOpts.CuryRetainageAmt ?? 0m) - (invoice.CuryDocBal ?? 0m);
                tranNew.CuryLineAmt = PXCurrencyAttribute.RoundCury(Base.Transactions.Cache, tranNew, (detail.CuryRetainageAmt ?? 0m) * retainagePercent);
                tranNew             = Base.Transactions.Update(tranNew);
            }

            ClearCurrentDocumentDiscountDetails();

            // We should copy all taxes from the original document
            // because it is possible to add or delete them.
            //
            foreach (APTaxTran aptaxtran in PXSelect <APTaxTran,
                                                      Where <APTaxTran.module, Equal <BatchModule.moduleAP>,
                                                             And <APTaxTran.tranType, Equal <Required <APTaxTran.tranType> >,
                                                                  And <APTaxTran.refNbr, Equal <Required <APTaxTran.refNbr> > > > > >
                     .Select(Base, origInvoice.DocType, origInvoice.RefNbr)
                     .RowCast <APTaxTran>()
                     .Where(row => row.CuryRetainedTaxAmt != 0m))
            {
                APTaxTran new_aptaxtran = Base.Taxes.Insert(new APTaxTran
                {
                    TaxID = aptaxtran.TaxID
                });

                if (new_aptaxtran != null)
                {
                    new_aptaxtran = PXCache <APTaxTran> .CreateCopy(new_aptaxtran);

                    new_aptaxtran.TaxRate = aptaxtran.TaxRate;
                    new_aptaxtran         = Base.Taxes.Update(new_aptaxtran);
                }
            }

            TaxBaseAttribute.SetTaxCalc <APTran.taxCategoryID>(Base.Transactions.Cache, null, oldTaxCalc);
            decimal diff = (retainageOpts.CuryRetainageAmt ?? 0m) - (invoice.CuryDocBal ?? 0m);

            if (tranNew != null && diff != 0m)
            {
                HashSet <string> taxList = PXSelectJoin <APTax,
                                                         InnerJoin <Tax, On <Tax.taxID, Equal <APTax.taxID> > >,
                                                         Where <APTax.tranType, Equal <Required <APTax.tranType> >,
                                                                And <APTax.refNbr, Equal <Required <APTax.refNbr> >,
                                                                     And <APTax.lineNbr, Equal <Required <APTax.lineNbr> >,
                                                                          And <Tax.taxType, NotEqual <CSTaxType.use> > > > > >
                                           .Select(Base, tranNew.TranType, tranNew.RefNbr, tranNew.LineNbr)
                                           .RowCast <APTax>()
                                           .Select(row => row.TaxID)
                                           .ToHashSet();

                // To guarantee correct document total amount
                // we should calculate last line total,
                // including its taxes.
                //
                TaxAttribute.CalcTaxable calcClass = new TaxAttribute.CalcTaxable(false, TaxAttribute.TaxCalcLevelEnforcing.None);
                decimal curyLineAmt = calcClass.CalcTaxableFromTotalAmount(
                    Base.Transactions.Cache,
                    tranNew,
                    taxList,
                    invoice.DocDate.Value,
                    prevCuryTotal);

                tranNew.CuryLineAmt = curyLineAmt;
                tranNew             = Base.Transactions.Update(tranNew);
            }

            APVendorRefNbrAttribute aPVendorRefNbrAttribute = Base.Document.Cache.GetAttributesReadonly <APInvoice.invoiceNbr>()
                                                              .OfType <APVendorRefNbrAttribute>().FirstOrDefault();

            if (aPVendorRefNbrAttribute != null)
            {
                var args = new PXFieldVerifyingEventArgs(invoice, invoice.InvoiceNbr, true);
                aPVendorRefNbrAttribute.FieldVerifying(Base.Document.Cache, args);
            }

            return(invoice);
        }
예제 #3
0
        private static void AddTaxesAndApplications(ARInvoiceEntry ie, PendingPPDCreditMemoApp doc, Customer customer, ARInvoice invoice)
        {
            ARTaxTran artaxMax               = null;
            decimal?  TaxTotal               = 0m;
            decimal?  InclusiveTotal         = 0m;
            decimal?  DiscountedTaxableTotal = 0m;
            decimal?  DiscountedPriceTotal   = 0m;
            decimal   CashDiscPercent        = (decimal)(doc.CuryAdjdPPDAmt / doc.InvCuryOrigDocAmt);

            PXResultset <ARTaxTran> taxes = PXSelectJoin <ARTaxTran,
                                                          InnerJoin <Tax, On <Tax.taxID, Equal <ARTaxTran.taxID> > >,
                                                          Where <ARTaxTran.module, Equal <BatchModule.moduleAR>,
                                                                 And <ARTaxTran.tranType, Equal <Required <ARTaxTran.tranType> >,
                                                                      And <ARTaxTran.refNbr, Equal <Required <ARTaxTran.refNbr> > > > > > .Select(ie, doc.AdjdDocType, doc.AdjdRefNbr);

            //add taxes
            foreach (PXResult <ARTaxTran, Tax> res in taxes)
            {
                Tax       tax   = res;
                ARTaxTran artax = PXCache <ARTaxTran> .CreateCopy(res);

                ARTaxTran artaxNew = ie.Taxes.Search <ARTaxTran.taxID>(artax.TaxID);

                if (artaxNew == null)
                {
                    artax.TranType    = null;
                    artax.RefNbr      = null;
                    artax.TaxPeriodID = null;
                    artax.Released    = false;
                    artax.Voided      = false;
                    artax.CuryInfoID  = invoice.CuryInfoID;

                    TaxBaseAttribute.SetTaxCalc <ARTran.taxCategoryID, ARTaxAttribute>(ie.Transactions.Cache, null, TaxCalc.NoCalc);
                    artaxNew = ie.Taxes.Insert(artax);

                    artaxNew.CuryTaxableAmt = 0m;
                    artaxNew.CuryTaxAmt     = 0m;
                    artaxNew.TaxRate        = artax.TaxRate;
                }

                bool isTaxable = CalculateDiscountedTaxes(ie.Taxes.Cache, artax, CashDiscPercent);
                DiscountedPriceTotal += artax.CuryDiscountedPrice;

                decimal?CuryTaxableAmt = artax.CuryTaxableAmt - artax.CuryDiscountedTaxableAmt;
                decimal?CuryTaxAmt     = artax.CuryTaxAmt - artax.CuryDiscountedPrice;

                artaxNew.CuryTaxableAmt += CuryTaxableAmt;
                artaxNew.CuryTaxAmt     += CuryTaxAmt;

                TaxBaseAttribute.SetTaxCalc <ARTran.taxCategoryID, ARTaxAttribute>(ie.Transactions.Cache, null, TaxCalc.ManualCalc);
                ie.Taxes.Update(artaxNew);

                if (isTaxable)
                {
                    DiscountedTaxableTotal += artax.CuryDiscountedTaxableAmt;
                    if (artaxMax == null || artaxNew.CuryTaxableAmt > artaxMax.CuryTaxableAmt)
                    {
                        artaxMax = artaxNew;
                    }
                }

                if (tax.TaxCalcLevel == CSTaxCalcLevel.Inclusive)
                {
                    InclusiveTotal += CuryTaxAmt;
                }
                else
                {
                    TaxTotal += CuryTaxAmt;
                }
            }

            //adjust taxes according to parent ARInvoice
            decimal?DiscountedInvTotal = doc.InvCuryOrigDocAmt - doc.InvCuryOrigDiscAmt;
            decimal?DiscountedDocTotal = DiscountedTaxableTotal + DiscountedPriceTotal;

            if (doc.InvCuryOrigDiscAmt == doc.CuryAdjdPPDAmt &&
                artaxMax != null &&
                doc.InvCuryVatTaxableTotal + doc.InvCuryTaxTotal == doc.InvCuryOrigDocAmt &&
                DiscountedDocTotal != DiscountedInvTotal)
            {
                artaxMax.CuryTaxableAmt += DiscountedDocTotal - DiscountedInvTotal;
                TaxBaseAttribute.SetTaxCalc <ARTran.taxCategoryID, ARTaxAttribute>(ie.Transactions.Cache, null, TaxCalc.ManualCalc);
                ie.Taxes.Update(artaxMax);
            }

            //add document details
            ARTran tranNew = ie.Transactions.Insert();

            tranNew.BranchID = doc.AdjdBranchID;
            using (new PXLocaleScope(customer.LocaleName))
                tranNew.TranDesc = string.Format("{0} {1}, {2} {3}", PXMessages.LocalizeNoPrefix(DocTypes[doc.AdjdDocType]), doc.AdjdRefNbr, PXMessages.LocalizeNoPrefix(Messages.Payment), doc.AdjgRefNbr);
            tranNew.CuryExtPrice         = doc.CuryAdjdPPDAmt - TaxTotal;
            tranNew.CuryTaxableAmt       = tranNew.CuryExtPrice - InclusiveTotal;
            tranNew.CuryTaxAmt           = TaxTotal + InclusiveTotal;
            tranNew.AccountID            = customer.DiscTakenAcctID;
            tranNew.SubID                = customer.DiscTakenSubID;
            tranNew.TaxCategoryID        = null;
            tranNew.IsFree               = true;
            tranNew.ManualDisc           = true;
            tranNew.CuryDiscAmt          = 0m;
            tranNew.DiscPct              = 0m;
            tranNew.GroupDiscountRate    = 1m;
            tranNew.DocumentDiscountRate = 1m;

            if (taxes.Count == 1)
            {
                ARTaxTran artax  = taxes[0];
                ARTran    artran = PXSelectJoin <ARTran,
                                                 InnerJoin <ARTax, On <ARTax.tranType, Equal <ARTran.tranType>,
                                                                       And <ARTax.refNbr, Equal <ARTran.refNbr>,
                                                                            And <ARTax.lineNbr, Equal <ARTran.lineNbr> > > > >,
                                                 Where <ARTax.tranType, Equal <Required <ARTax.tranType> >,
                                                        And <ARTax.refNbr, Equal <Required <ARTax.refNbr> >,
                                                             And <ARTax.taxID, Equal <Required <ARTax.taxID> > > > >,
                                                 OrderBy <Asc <ARTran.lineNbr> > > .SelectSingleBound(ie, null, artax.TranType, artax.RefNbr, artax.TaxID);

                if (artran != null)
                {
                    tranNew.TaxCategoryID = artran.TaxCategoryID;
                }
            }

            ie.Transactions.Update(tranNew);

            //add applications
            ARAdjust adj = new ARAdjust();

            adj.AdjdDocType = doc.AdjdDocType;
            adj.AdjdRefNbr  = doc.AdjdRefNbr;
            adj             = ie.Adjustments_1.Insert(adj);

            adj.CuryAdjgAmt = doc.InvCuryDocBal;
            ie.Adjustments_1.Update(adj);
        }