public static void ReleaseRetainage(ARInvoiceEntry graph, ARInvoiceExt invoice, ARRetainageFilter filter, bool isAutoRelease)
        {
            graph.Clear(PXClearOption.ClearAll);
            PXUIFieldAttribute.SetError(graph.Document.Cache, null, null, null);

            RetainageOptions retainageOptions = new RetainageOptions();

            retainageOptions.DocDate          = filter.DocDate;
            retainageOptions.FinPeriodID      = filter.FinPeriodID;
            retainageOptions.CuryRetainageAmt = invoice.CuryRetainageReleasedAmt;

            ARInvoiceEntryRetainage retainageExt = graph.GetExtension <ARInvoiceEntryRetainage>();

            ARInvoice retainageInvoice = retainageExt.ReleaseRetainageProc(invoice, retainageOptions, isAutoRelease);

            graph.Save.Press();

            if (isAutoRelease)
            {
                List <ARRegister> toRelease = new List <ARRegister>()
                {
                    retainageInvoice
                };
                using (new PXTimeStampScope(null))
                {
                    ARDocumentRelease.ReleaseDoc(toRelease, true);
                }
            }
        }
예제 #2
0
        public override void Initialize()
        {
            base.Initialize();

            RetainageOptions releaseRetainageOptions = ReleaseRetainageOptions.Current;

            PXAction action = Base.Actions["action"];

            if (action != null)
            {
                action.AddMenuAction(releaseRetainage);
            }
        }
예제 #3
0
        protected virtual void ARRetainageFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            ARRetainageFilter filter = e.Row as ARRetainageFilter;

            if (filter == null)
            {
                return;
            }

            bool isAutoRelease = ARSetup.Current.RetainageInvoicesAutoRelease == true;

            DocumentList.SetProcessDelegate(delegate(List <ARInvoiceExt> list)
            {
                ARInvoiceEntry graph = CreateInstance <ARInvoiceEntry>();
                ARInvoiceEntryRetainage retainageExt = graph.GetExtension <ARInvoiceEntryRetainage>();

                RetainageOptions retainageOptions  = new RetainageOptions();
                retainageOptions.DocDate           = filter.DocDate;
                retainageOptions.MasterFinPeriodID = FinPeriodIDAttribute.CalcMasterPeriodID <ARRetainageFilter.finPeriodID>(graph.Caches[typeof(ARRetainageFilter)], filter);

                retainageExt.ReleaseRetainageProc(list, retainageOptions, isAutoRelease);
            });
        }
예제 #4
0
        public virtual ARInvoice ReleaseRetainageProc(ARInvoice doc, RetainageOptions retainageOpts, bool isAutoRelease = false)
        {
            Base.Clear(PXClearOption.PreserveTimeStamp);

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

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

            PXResult <ARInvoice, CurrencyInfo, Terms, Customer> resultDoc =
                ARInvoice_CurrencyInfo_Terms_Customer
                .SelectSingleBound(Base, null, doc.DocType, doc.RefNbr, doc.CustomerID)
                .Cast <PXResult <ARInvoice, CurrencyInfo, Terms, Customer> >()
                .First();

            CurrencyInfo info        = resultDoc;
            ARInvoice    origInvoice = resultDoc;
            Customer     customer    = 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));

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

            invoice.CuryInfoID = new_info.CuryInfoID;
            invoice.DocType    = ARDocType.Invoice;
            invoice.RefNbr     = null;
            invoice.LineCntr   = null;
            invoice.InvoiceNbr = origInvoice.InvoiceNbr;

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

            Base.Document.Cache.SetDefaultExt <ARInvoice.isMigratedRecord>(invoice);
            Base.Document.Cache.SetDefaultExt <ARInvoice.hold>(invoice);
            invoice.BatchNbr   = null;
            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.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.ARSetup.Current.HoldEntry == true;

            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 <ARInvoice.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 <ARTran> details = PXSelectGroupBy <ARTran,
                                                            Where <ARTran.tranType, Equal <Required <ARTran.tranType> >,
                                                                   And <ARTran.refNbr, Equal <Required <ARTran.refNbr> >,
                                                                        And <ARTran.curyRetainageAmt, NotEqual <decimal0> > > >,
                                                            Aggregate <
                                                                GroupBy <ARTran.taxCategoryID,
                                                                         Sum <ARTran.curyRetainageAmt> > > >
                                           .Select(Base, doc.DocType, doc.RefNbr);

            ARTran  tranNew       = null;
            decimal prevCuryTotal = 0m;

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

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

            foreach (ARTran detail in details)
            {
                // Create ARTran record for chosen retainage amount,
                // clear all required fields to prevent tax calculation,
                // discount calculation and retainage calculation.
                // CuryUnitPrice = 0m and CuryExtPrice = 0m here to prevent their
                // FieldDefaulting events, because in our case default value
                // should be equal to zero.
                //
                tranNew = Base.Transactions.Insert(new ARTran
                {
                    CuryUnitPrice = 0m,
                    CuryExtPrice  = 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.ManualDisc           = true;
                tranNew.DiscPct              = 0m;
                tranNew.CuryDiscAmt          = 0m;
                tranNew.RetainagePct         = 0m;
                tranNew.CuryRetainageAmt     = 0m;
                tranNew.CuryTaxableAmt       = 0m;
                tranNew.CuryTaxAmt           = 0;
                tranNew.GroupDiscountRate    = 1m;
                tranNew.DocumentDiscountRate = 1m;

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

                prevCuryTotal        = (retainageOpts.CuryRetainageAmt ?? 0m) - (invoice.CuryDocBal ?? 0m);
                tranNew.CuryExtPrice = 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 (ARTaxTran artaxtran in PXSelect <ARTaxTran,
                                                      Where <ARTaxTran.module, Equal <BatchModule.moduleAR>,
                                                             And <ARTaxTran.tranType, Equal <Required <ARTaxTran.tranType> >,
                                                                  And <ARTaxTran.refNbr, Equal <Required <ARTaxTran.refNbr> > > > > >
                     .Select(Base, origInvoice.DocType, origInvoice.RefNbr)
                     .RowCast <ARTaxTran>()
                     .Where(row => row.CuryRetainedTaxAmt != 0m))
            {
                ARTaxTran new_artaxtran = Base.Taxes.Insert(new ARTaxTran
                {
                    TaxID = artaxtran.TaxID
                });

                if (new_artaxtran != null)
                {
                    new_artaxtran = PXCache <ARTaxTran> .CreateCopy(new_artaxtran);

                    new_artaxtran.TaxRate = artaxtran.TaxRate;
                    new_artaxtran         = Base.Taxes.Update(new_artaxtran);
                }
            }

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

            if (tranNew != null && diff != 0m)
            {
                HashSet <string> taxList = PXSelectJoin <ARTax,
                                                         InnerJoin <Tax, On <Tax.taxID, Equal <ARTax.taxID> > >,
                                                         Where <ARTax.tranType, Equal <Required <ARTax.tranType> >,
                                                                And <ARTax.refNbr, Equal <Required <ARTax.refNbr> >,
                                                                     And <ARTax.lineNbr, Equal <Required <ARTax.lineNbr> >,
                                                                          And <Tax.taxType, NotEqual <CSTaxType.use> > > > > >
                                           .Select(Base, tranNew.TranType, tranNew.RefNbr, tranNew.LineNbr)
                                           .RowCast <ARTax>()
                                           .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 curyExtPrice = calcClass.CalcTaxableFromTotalAmount(
                    Base.Transactions.Cache,
                    tranNew,
                    taxList,
                    invoice.DocDate.Value,
                    prevCuryTotal);

                tranNew.CuryExtPrice = curyExtPrice;
                tranNew = Base.Transactions.Update(tranNew);
            }

            return(invoice);
        }
예제 #5
0
        public virtual IEnumerable ReleaseRetainage(PXAdapter adapter)
        {
            ARInvoice doc = Base.Document.Current;

            if (doc != null &&
                doc.DocType == ARDocType.Invoice &&
                doc.RetainageApply == true &&
                doc.CuryRetainageUnreleasedAmt > 0m)
            {
                ARRetainageInvoice retainageDoc = RetainageDocuments
                                                  .Select()
                                                  .RowCast <ARRetainageInvoice>()
                                                  .FirstOrDefault(row => row.Released != true);

                if (retainageDoc != null)
                {
                    throw new PXException(
                              AP.Messages.ReleaseRetainageNotReleasedDocument,
                              PXMessages.LocalizeNoPrefix(ARDocTypeDict[retainageDoc.DocType]),
                              retainageDoc.RefNbr,
                              PXMessages.LocalizeNoPrefix(ARDocTypeDict[doc.DocType]));
                }

                ARRegister reversingDoc;
                if (Base.CheckReversingRetainageDocumentAlreadyExists(Base.Document.Current, out reversingDoc))
                {
                    throw new PXException(
                              AP.Messages.ReleaseRetainageReversingDocumentExists,
                              PXMessages.LocalizeNoPrefix(ARDocTypeDict[doc.DocType]),
                              PXMessages.LocalizeNoPrefix(ARDocTypeDict[reversingDoc.DocType]),
                              reversingDoc.RefNbr);
                }

                Base.Save.Press();

                RetainageOptions retainageOpts = ReleaseRetainageOptions.Current;
                WebDialogResult  wdr           = ReleaseRetainageOptions.AskExt(
                    (graph, view) =>
                {
                    retainageOpts.CuryRetainageTotal         = doc.CuryRetainageUnreleasedAmt;
                    retainageOpts.RetainagePct               = 100m;
                    retainageOpts.CuryRetainageAmt           = doc.CuryRetainageUnreleasedAmt;
                    retainageOpts.CuryRetainageUnreleasedAmt = retainageOpts.CuryRetainageTotal - retainageOpts.CuryRetainageAmt;
                },
                    true);

                if (wdr == WebDialogResult.OK)
                {
                    ARInvoice invoice = PXCache <ARInvoice> .CreateCopy(doc);

                    try
                    {
                        ReleaseRetainageProc(invoice, retainageOpts);
                        return(new List <ARInvoice> {
                            Base.Document.Current
                        });
                    }
                    catch (PXException)
                    {
                        Base.Clear(PXClearOption.PreserveTimeStamp);
                        Base.Document.Current = doc;
                        throw;
                    }
                }
            }

            return(adapter.Get());
        }