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); } } }
public override void Initialize() { base.Initialize(); RetainageOptions releaseRetainageOptions = ReleaseRetainageOptions.Current; PXAction action = Base.Actions["action"]; if (action != null) { action.AddMenuAction(releaseRetainage); } }
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); }); }
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); }
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()); }