protected virtual void AppendTail <T, W>(PXGraph graph, List <object> ret, T record, object row, params object[] parameters) where T : class, ITaxDetail, PX.Data.IBqlTable, new() where W : IBqlWhere, new() { IComparer <Tax> taxByCalculationLevelComparer = GetTaxByCalculationLevelComparer(); taxByCalculationLevelComparer.ThrowOnNull(nameof(taxByCalculationLevelComparer)); PXSelectBase <Tax> select = new PXSelectReadonly2 <Tax, LeftJoin <TaxRev, On <TaxRev.taxID, Equal <Tax.taxID>, And <TaxRev.outdated, Equal <False>, And <TaxRev.taxType, Equal <TaxType.sales>, And <Tax.taxType, NotEqual <CSTaxType.withholding>, And <Tax.taxType, NotEqual <CSTaxType.use>, And <Tax.reverseTax, Equal <False>, And <Required <TaxRev.startDate>, Between <TaxRev.startDate, TaxRev.endDate> > > > > > > > >, Where2 <Where <Tax.taxID, Equal <Required <Tax.taxID> > >, And <W> > >(graph); List <object> newParams = new List <object>(); newParams.Add(this.GetDocDate(ParentCache(graph), row)); newParams.Add(record.TaxID); if (parameters != null) { newParams.AddRange(parameters); } foreach (PXResult <Tax, TaxRev> line in select.View.SelectMultiBound(new object[] { row }, newParams.ToArray())) { int idx; for (idx = ret.Count; (idx > 0) && taxByCalculationLevelComparer.Compare((PXResult <T, Tax, TaxRev>)ret[idx - 1], line) > 0; idx--) { ; } ret.Insert(idx, new PXResult <T, Tax, TaxRev>(record, (Tax)line, (TaxRev)line)); } }
public Decimal CalcTaxableFromTotalAmount(PXCache cache, object row, string aTaxZoneID, string aTaxCategoryID, DateTime aDocDate, Decimal aCuryTotal) { IComparer <Tax> taxComparer = GetTaxComparer(); taxComparer.ThrowOnNull(nameof(taxComparer)); Decimal result = Decimal.Zero; PXGraph graph = cache.Graph; List <TaxZoneDet> taxList = GetApplicableTaxList(graph, aTaxZoneID, aTaxCategoryID, aDocDate); Dictionary <string, PXResult <Tax, TaxRev> > taxRates = GetTaxRevisionList(graph, aDocDate); List <PXResult <Tax, TaxRev> > orderedTaxList = new List <PXResult <Tax, TaxRev> >(taxList.Count); foreach (TaxZoneDet iDet in taxList) { if (taxRates.TryGetValue(iDet.TaxID, out PXResult <Tax, TaxRev> line)) { int idx; for (idx = orderedTaxList.Count; (idx > 0) && taxComparer.Compare(orderedTaxList[idx - 1], line) > 0; idx--) { ; } orderedTaxList.Insert(idx, new PXResult <Tax, TaxRev>(line, line)); } } Decimal rateInclusive = Decimal.Zero; Decimal rateLvl1 = Decimal.Zero; Decimal rateLvl2 = Decimal.Zero; foreach (PXResult <Tax, TaxRev> iRes in orderedTaxList) { Tax tax = iRes; TaxRev taxRev = iRes; Decimal multiplier = tax.ReverseTax == true ? Decimal.MinusOne : Decimal.One; switch (tax.TaxCalcLevel) { case CSTaxCalcLevel.Inclusive: rateInclusive += multiplier * taxRev.TaxRate.Value; break; case CSTaxCalcLevel.CalcOnItemAmt: rateLvl1 += multiplier * taxRev.TaxRate.Value; break; case CSTaxCalcLevel.CalcOnItemAmtPlusTaxAmt: rateLvl2 += multiplier * taxRev.TaxRate.Value; break; } } decimal baseLvl2 = cache.Graph.FindImplementation <IPXCurrencyHelper>().RoundCury(aCuryTotal / (1 + rateLvl2 / 100)); decimal baseLvl1 = cache.Graph.FindImplementation <IPXCurrencyHelper>().RoundCury(baseLvl2 / (1 + (rateLvl1 + rateInclusive) / 100)); Decimal curyTaxTotal = decimal.Zero; Decimal curyTax2Total = decimal.Zero; foreach (PXResult <Tax, TaxRev> iRes in orderedTaxList) { Tax tax = iRes; TaxRev taxRev = iRes; Decimal multiplier = tax.ReverseTax == true ? Decimal.MinusOne : Decimal.One; switch (tax.TaxCalcLevel) { case CSTaxCalcLevel.Inclusive: break; case CSTaxCalcLevel.CalcOnItemAmt: curyTaxTotal += multiplier * cache.Graph.FindImplementation <IPXCurrencyHelper>().RoundCury((baseLvl1 * taxRev.TaxRate / 100m) ?? 0m); break; case CSTaxCalcLevel.CalcOnItemAmtPlusTaxAmt: curyTax2Total += multiplier * cache.Graph.FindImplementation <IPXCurrencyHelper>().RoundCury((baseLvl2 * taxRev.TaxRate / 100m) ?? 0m); break; } } result = aCuryTotal - curyTaxTotal - curyTax2Total; return(result); }
protected List <object> SelectTaxes <TWhere, TLineNbr>(PXGraph graph, object[] currents, PXTaxCheck taxchk, params object[] parameters) where TWhere : IBqlWhere, new() where TLineNbr : IBqlOperand { IComparer <Tax> taxByCalculationLevelComparer = GetTaxByCalculationLevelComparer(); taxByCalculationLevelComparer.ThrowOnNull(nameof(taxByCalculationLevelComparer)); Dictionary <string, PXResult <Tax, TaxRev> > tail = new Dictionary <string, PXResult <Tax, TaxRev> >(); foreach (PXResult <Tax, TaxRev> record in PXSelectReadonly2 <Tax, LeftJoin <TaxRev, On <TaxRev.taxID, Equal <Tax.taxID>, And <TaxRev.outdated, Equal <boolFalse>, And2 <Where <TaxRev.taxType, Equal <TaxType.purchase>, And <Tax.reverseTax, Equal <boolFalse>, Or <TaxRev.taxType, Equal <TaxType.sales>, And <Where <Tax.reverseTax, Equal <boolTrue>, Or <Tax.taxType, Equal <CSTaxType.use>, Or <Tax.taxType, Equal <CSTaxType.withholding> > > > > > > >, And <Current <POLandedCostDoc.docDate>, Between <TaxRev.startDate, TaxRev.endDate> > > > > >, TWhere> .SelectMultiBound(graph, currents, parameters)) { tail[((Tax)record).TaxID] = record; } List <object> ret = new List <object>(); switch (taxchk) { case PXTaxCheck.Line: foreach (POLandedCostTax record in PXSelect <POLandedCostTax, Where <POLandedCostTax.docType, Equal <Current <POLandedCostDoc.docType> >, And <POLandedCostTax.refNbr, Equal <Current <POLandedCostDoc.refNbr> >, And <POLandedCostTax.lineNbr, Equal <TLineNbr> > > > > .SelectMultiBound(graph, currents)) { if (tail.TryGetValue(record.TaxID, out PXResult <Tax, TaxRev> line)) { int idx; for (idx = ret.Count; (idx > 0) && taxByCalculationLevelComparer.Compare((PXResult <POLandedCostTax, Tax, TaxRev>)ret[idx - 1], line) > 0; idx--) { ; } ret.Insert(idx, new PXResult <POLandedCostTax, Tax, TaxRev>(record, (Tax)line, (TaxRev)line)); } } return(ret); case PXTaxCheck.RecalcLine: foreach (POLandedCostTax record in PXSelect <POLandedCostTax, Where <POLandedCostTax.docType, Equal <Current <POLandedCostDoc.docType> >, And <POLandedCostTax.refNbr, Equal <Current <POLandedCostDoc.refNbr> >, And <POLandedCostTax.lineNbr, Less <intMax> > > > > .SelectMultiBound(graph, currents)) { if (tail.TryGetValue(record.TaxID, out PXResult <Tax, TaxRev> line)) { int idx; for (idx = ret.Count; (idx > 0) && ((POLandedCostTax)(PXResult <POLandedCostTax, Tax, TaxRev>)ret[idx - 1]).LineNbr == record.LineNbr && taxByCalculationLevelComparer.Compare((PXResult <POLandedCostTax, Tax, TaxRev>)ret[idx - 1], line) > 0; idx--) { ; } ret.Insert(idx, new PXResult <POLandedCostTax, Tax, TaxRev>(record, (Tax)line, (TaxRev)line)); } } return(ret); case PXTaxCheck.RecalcTotals: foreach (POLandedCostTaxTran record in PXSelect <POLandedCostTaxTran, Where <POLandedCostTaxTran.docType, Equal <Current <POLandedCostDoc.docType> >, And <POLandedCostTaxTran.refNbr, Equal <Current <POLandedCostDoc.refNbr> > > > > .SelectMultiBound(graph, currents)) { if (record.TaxID != null && tail.TryGetValue(record.TaxID, out PXResult <Tax, TaxRev> line)) { int idx; for (idx = ret.Count; (idx > 0) && taxByCalculationLevelComparer.Compare((PXResult <POLandedCostTaxTran, Tax, TaxRev>)ret[idx - 1], line) > 0; idx--) { ; } ret.Insert(idx, new PXResult <POLandedCostTaxTran, Tax, TaxRev>(record, (Tax)line, (TaxRev)line)); } } return(ret); default: return(ret); } }
public Decimal CalcTaxableFromTotalAmount( PXCache cache, object row, HashSet<string> taxList, DateTime aDocDate, Decimal aCuryTotal) { IComparer<Tax> taxComparer = GetTaxComparer(); taxComparer.ThrowOnNull(nameof(taxComparer)); Decimal result = Decimal.Zero; PXGraph graph = cache.Graph; Dictionary<string, PXResult<Tax, TaxRev>> taxRates = GetTaxRevisionList(graph, aDocDate); List<PXResult<Tax, TaxRev>> orderedTaxList = new List<PXResult<Tax, TaxRev>>(taxList.Count); foreach (string taxID in taxList) { if (taxRates.TryGetValue(taxID, out PXResult<Tax, TaxRev> line)) { int idx; for (idx = orderedTaxList.Count; (idx > 0) && taxComparer.Compare(orderedTaxList[idx - 1], line) > 0; idx--) ; var tax = (Tax)line; if (_taxCalcMode != null && tax.TaxCalcLevel != CSTaxCalcLevel.CalcOnItemAmtPlusTaxAmt) { switch (_taxCalcMode) { case TaxCalculationMode.Net: tax.TaxCalcLevel = CSTaxCalcLevel.CalcOnItemAmt; break; case TaxCalculationMode.Gross: tax.TaxCalcLevel = CSTaxCalcLevel.Inclusive; break; } } orderedTaxList.Insert(idx, new PXResult<Tax, TaxRev>(tax, (TaxRev)line)); } } Decimal rateInclusive = Decimal.Zero; Decimal rateLvl1 = Decimal.Zero; Decimal rateLvl2 = Decimal.Zero; foreach (PXResult<Tax, TaxRev> iRes in orderedTaxList) { Tax tax = iRes; TaxRev taxRev = iRes; Decimal multiplier = tax.ReverseTax == true ? Decimal.MinusOne : Decimal.One; if (tax.TaxType == CSTaxType.PerUnit) { PXTrace.WriteError(Messages.PerUnitTaxesNotSupportedOperation); throw new PXException(Messages.PerUnitTaxesNotSupportedOperation); } switch (tax.TaxCalcLevel) { case CSTaxCalcLevel.Inclusive: rateInclusive += multiplier * taxRev.TaxRate.Value; break; case CSTaxCalcLevel.CalcOnItemAmt: rateLvl1 += multiplier * taxRev.TaxRate.Value; break; case CSTaxCalcLevel.CalcOnItemAmtPlusTaxAmt: rateLvl2 += multiplier * taxRev.TaxRate.Value; break; } } decimal baseLvl2 = PXDBCurrencyAttribute.RoundCury(cache, row, aCuryTotal / (1 + rateLvl2 / 100), _precision); decimal baseLvl1 = PXDBCurrencyAttribute.RoundCury(cache, row, baseLvl2 / (1 + (rateLvl1 + rateInclusive) / 100), _precision); Decimal curyTaxTotal = decimal.Zero; Decimal curyTax2Total = decimal.Zero; foreach (PXResult<Tax, TaxRev> iRes in orderedTaxList) { Tax tax = iRes; TaxRev taxRev = iRes; Decimal multiplier = tax.ReverseTax == true ? Decimal.MinusOne : Decimal.One; switch (tax.TaxCalcLevel) { case CSTaxCalcLevel.Inclusive: break; case CSTaxCalcLevel.CalcOnItemAmt: curyTaxTotal += multiplier * PXDBCurrencyAttribute.RoundCury(cache, row, (baseLvl1 * taxRev.TaxRate / 100m) ?? 0m, _precision); break; case CSTaxCalcLevel.CalcOnItemAmtPlusTaxAmt: curyTax2Total += multiplier * PXDBCurrencyAttribute.RoundCury(cache, row, (baseLvl2 * taxRev.TaxRate / 100m) ?? 0m, _precision); break; } } result = aCuryTotal - curyTaxTotal - curyTax2Total; return result; }