import { Add, Divide, Multiply, Subtract } from "../../shared/math-operations"; import { TrUtils } from "../../utils/tr-utils"; export class DebitNoteTotalsService { static GetTotalsValue(PartsList: any, IsIndependentTax: boolean, DetailedInfo: boolean, Disc: any, Perc: string, TaxCodes: any, WithItems: boolean, Settings: any, EntitySettings:any) { // LPerc = TrUtils.SetPercToStringIfNull(LPerc); // PPerc = TrUtils.SetPercToStringIfNull(PPerc); Perc = TrUtils.SetPercToStringIfNull(Perc); // LDisc = TrUtils.SetValueToZeroIfNull(LDisc); // PDisc = TrUtils.SetValueToZeroIfNull(PDisc); Disc = TrUtils.SetValueToZeroIfNull(Disc); // opCodesList = this.CalculateLaborValues(opCodesList, IsIndependentTax); PartsList = this.CalculateLaborPartValues(PartsList, IsIndependentTax); let finalTotalsData: any = this.GetFinalRODataForSave(PartsList, IsIndependentTax, Disc, Perc, DetailedInfo, Settings, EntitySettings.DecimalsNumber); if (DetailedInfo) { finalTotalsData = this.GetDetailedTotalsData(finalTotalsData, IsIndependentTax, PartsList, TaxCodes, EntitySettings.DecimalsNumber); } if (WithItems) { // finalTotalsData.Ops = opCodesList; finalTotalsData.Items = PartsList; } return finalTotalsData; } static CalculateLaborPartValues(PartsList: any, IsIndependentTax: boolean) { PartsList = this.ResetLaborPartValues(PartsList, IsIndependentTax); // PartsList = this.GetLaborPartsDiscountPrice(PartsList); // PartsList = this.GetLaborPartsAfterDiscount(PartsList); // PartsList = this.GetPartsAfterTax(PartsList, IsIndependentTax); return PartsList; } static ResetLaborPartValues(PartsList: any, IsIndependentTax:boolean) { PartsList.forEach((Part: any) => { Part = this.ResetLaborPartValueIfInvalid(Part); Part.DiscountedPrice = Add(Part.Disc , Part.RecDisc); // Part.AfterPartDisc = Part.NetAmt; Part.AfterPartDisc = Subtract(Part.UnAmt, Part.Disc, Part.RecDisc); if (IsIndependentTax) { Part.AfterPartTax = Add(Part.AfterPartDisc , Part.CGST , Part.SGST , Part.IGST); } else { Part.AfterPartTax = Part.AfterPartDisc; } }); return PartsList; } static ResetLaborPartValueIfInvalid(Part: any) { Part.UnPr = TrUtils.SetValueToZeroIfNull(Part.UnPr); Part.Disc = TrUtils.SetValueToZeroIfNull(Part.Disc); Part.RecDisc = TrUtils.SetValueToZeroIfNull(Part.RecDisc); Part.CGST = TrUtils.SetValueToZeroIfNull(Part.CGST); Part.SGST = TrUtils.SetValueToZeroIfNull(Part.SGST); Part.IGST = TrUtils.SetValueToZeroIfNull(Part.IGST); return Part; } static GetFinalRODataForSave(PartsList: any, IsIndependentTax: boolean, Disc: any, Perc: string, DetailedInfo: boolean, Settings: any, DecimalsNumber: number = 2) { let finalTotalsData: any = {}; finalTotalsData = this.SetMainDiscountValues(Disc, Perc, finalTotalsData, DetailedInfo); finalTotalsData.Settings = Settings; finalTotalsData = this.GetFinalCustomerTotalsData(finalTotalsData, PartsList, IsIndependentTax, DetailedInfo, DecimalsNumber); return finalTotalsData; } static SetMainDiscountValues(Disc: string, Perc: string, finalTotalsData: any, DetailedInfo: boolean) { // finalTotalsData.LDisc = LDisc; // finalTotalsData.LPerc = LPerc; // finalTotalsData.PDisc = PDisc; // finalTotalsData.PPerc = PPerc; finalTotalsData.Disc = Disc; finalTotalsData.Perc = Perc; if (DetailedInfo) { // finalTotalsData.FixedLDisc = LDisc; // finalTotalsData.FixedPDisc = PDisc; finalTotalsData.FixedDisc = Disc; } return finalTotalsData; } static GetFinalCustomerTotalsData(finalTotalsData: any, PartsList: any, IsIndependentTax: boolean, DetailedInfo: boolean, DecimalsNumber: number = 2) { let CustomerAfterDiscTotals: number = this.GetSubTotalFor(PartsList); // let CustLaborTaxTotal = this.GetLaborTaxTotalFor(IsIndependentTax); let CustPartTaxTotal = this.GetPartsTaxTotalFor(PartsList, IsIndependentTax); finalTotalsData.SubTotal = CustomerAfterDiscTotals; // let CustLaborDiscTotal = this.GetLaborDiscountedTotal(LaborList, IsIndependentTax, finalTotalsData); let CustPartsDiscTotal = this.GetPartDiscountedTotal(PartsList, IsIndependentTax, finalTotalsData); // let CustLaborTotalAfterDisc = this.GetLaborTotalAfterDiscount(LaborList); let CustPartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList); finalTotalsData.STotal = Add(CustPartsDiscTotal, CustPartsTotalAfterDisc); let CustTotal: any = this.GetCustomerTotalBasedOnTaxType(finalTotalsData, CustPartTaxTotal, PartsList, IsIndependentTax); finalTotalsData.Round = Subtract(Math.round(CustTotal) , CustTotal); finalTotalsData.Total = Math.round(CustTotal); if (DetailedInfo) { finalTotalsData.FixedSubTotal = TrUtils.FixedTo(CustomerAfterDiscTotals, DecimalsNumber); finalTotalsData.FixedTotal = TrUtils.FixedTo(CustTotal, DecimalsNumber); } return finalTotalsData; } static GetSubTotalFor(PartsList: any) { // let LaborTotalAfterDisc: any = this.GetLaborTotalAfterDiscount(LaborList); let PartsTotalAfterDisc: any = this.GetPartsTotalAfterDiscount(PartsList); return PartsTotalAfterDisc; } static GetPartsTotalAfterDiscount(PartsList: any) { let PartsTotalAfterDisc: any = 0; PartsList.forEach((Part: any) => { PartsTotalAfterDisc = Add(PartsTotalAfterDisc,Part.AfterPartDisc); }); return PartsTotalAfterDisc; } static GetDetailedTotalsData(finalTotalsData: any, IsIndependentTax: boolean, PartsList: any, TaxCodes: any, DecimalsNumber: number = 2) { // finalTotalsData.CustLaborDiscTotal = this.GetLaborDiscountedTotal(opCodesList, IsIndependentTax, finalTotalsData); finalTotalsData.CustPartsDiscTotal = this.GetPartDiscountedTotal(PartsList, IsIndependentTax, finalTotalsData); // finalTotalsData.CustLaborTotalAfterDisc = this.GetLaborTotalAfterDiscount(opCodesList); finalTotalsData.CustPartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList); // finalTotalsData.CustLaborTotalBeforeDisc = TrUtils.FixedTo(finalTotalsData.CustLaborTotalAfterDisc // + finalTotalsData.CustLaborDiscTotal); finalTotalsData.CustPartsTotalBeforeDisc = Add(finalTotalsData.CustPartsTotalAfterDisc , finalTotalsData.CustPartsDiscTotal); // finalTotalsData.CustLaborITax = this.GetLaborTaxTotalFor(opCodesList, IsIndependentTax); // finalTotalsData.CustLaborSGST = this.GetLaborSGSTTaxTotal(opCodesList, IsIndependentTax); // finalTotalsData.CustLaborCGST = this.GetLaborCGSTTaxTotal(opCodesList, IsIndependentTax); // finalTotalsData.CustLaborIGST = this.GetLaborIGSTTaxTotal(opCodesList, IsIndependentTax); let TaxInfo:any=this.GetPartGSTTaxTotal(PartsList, IsIndependentTax); finalTotalsData.CustPartITax = TrUtils.SetValueToZeroIfNull(TaxInfo[3]); finalTotalsData.CustPartCGST = TrUtils.SetValueToZeroIfNull(TaxInfo[0]); finalTotalsData.CustPartIGST = TrUtils.SetValueToZeroIfNull(TaxInfo[2]); finalTotalsData.CustPartSGST = TrUtils.SetValueToZeroIfNull(TaxInfo[1]); // finalTotalsData.CustLaborAfterTax = Add(finalTotalsData.CustLaborITax , finalTotalsData.CustLaborTotalAfterDisc); finalTotalsData.CustPartAfterTax = Add(finalTotalsData.CustPartITax , finalTotalsData.CustPartsTotalAfterDisc); finalTotalsData.CustTaxGroupData = this.GetTaxGroupingForPartsByHSN(PartsList, TaxCodes, DecimalsNumber); finalTotalsData.CustTotalRoundedBy = TrUtils.FixedTo(finalTotalsData.Round, DecimalsNumber); finalTotalsData.CustRoundedTotal = TrUtils.FixedTo(finalTotalsData.Total, DecimalsNumber); for (var key in finalTotalsData) { if (key !== 'Total' && key !== 'SubTotal' && key !== 'LDisc' && key !== 'LPerc' && key !== 'PDisc' && key !== 'PPerc' && key !== 'Disc' && key !== 'Perc' && key !== 'Tax' && typeof finalTotalsData[key] === 'number') { finalTotalsData[key] = TrUtils.FixPriceValue(finalTotalsData[key], DecimalsNumber); } } return finalTotalsData; } static GetPartDiscountedTotal(PartsList: any, isTaxable: boolean, finalTotalsData: any) { let PartsDiscountedTotal: any = 0; let overallPartDisc: number = 0; if (!isTaxable) { overallPartDisc = TrUtils.SetValueToZeroIfNull(finalTotalsData.PDisc) } PartsList.forEach((Part: any) => { PartsDiscountedTotal = Add(PartsDiscountedTotal,Part.DiscountedPrice); }); return Add(PartsDiscountedTotal , overallPartDisc); } static GetPartsTaxTotalFor(PartsList: any, IsIndependentTax: boolean) { let TotalTaxAmt: any = 0; if (IsIndependentTax) { PartsList.forEach((Part: any) => { TotalTaxAmt = Add(TotalTaxAmt , Part.CGST , Part.SGST, Part.IGST); }); } return TotalTaxAmt; } static GetCustomerTotalBasedOnTaxType(finalTotalsData: any, PartsTaxAmount: number , PartsList: any, IsIndependentTax: boolean) { // let LaborTotalAfterDisc: any = this.GetLaborTotalAfterDiscount(LaborList); let PartsTotalAfterDisc: any = this.GetPartsTotalAfterDiscount(PartsList); if (IsIndependentTax) { return Add(PartsTotalAfterDisc , PartsTaxAmount); } else { return Subtract(PartsTotalAfterDisc, finalTotalsData.Disc); } } static ItemsTotalAfterDiscount(PartsTotalAfterDisc: number, PartsTaxAmount: number, MainPDisc: number, PDiscInPerc: string) { let ItemsTotal: number = Add(PartsTotalAfterDisc, PartsTaxAmount); if (!TrUtils.IsZero(MainPDisc)) { if (!TrUtils.IsEmpty(PDiscInPerc)) { ItemsTotal = Subtract(ItemsTotal, Divide(Multiply(ItemsTotal, Number(PDiscInPerc)), 100)); } else { ItemsTotal = Subtract(ItemsTotal, MainPDisc); } } return ItemsTotal; } static GetPartGSTTaxTotal(PartsList: any, IsIndependentTax: boolean) { let TotalCGSTAmt: number = 0; let TotalSGSTAmt: number = 0; let TotalIGSTAmt: number = 0; let TotalTaxAmt: number = 0; if (IsIndependentTax) { PartsList.forEach((Part: any) => { TotalCGSTAmt = Add(TotalCGSTAmt , Part.CGST); TotalSGSTAmt = Add(TotalSGSTAmt , Part.SGST); TotalIGSTAmt = Add(TotalIGSTAmt , Part.IGST); TotalTaxAmt = Add(TotalTaxAmt , Part.CGST , Part.SGST, Part.IGST); }); } return [TotalCGSTAmt, TotalSGSTAmt, TotalIGSTAmt, TotalTaxAmt]; } static GetTaxGroupingForPartsByHSN(Parts: any, TaxCodes: any, DecimalsNumber: number) { Parts = this.GetCombinedTaxPercentage(Parts, TaxCodes); // Parts = this.ResetPartsHSNIfInvalid(Parts); let FinalMatchedParts: any[] = this.ComparePartsByHSN(Parts, TaxCodes); return this.GetTaxGroupingInfoByHSN(FinalMatchedParts, TaxCodes, DecimalsNumber); } static GetCombinedTaxPercentage(Parts: any, TaxCodes: any) { Parts.forEach((Part: any) => { if (TrUtils.IsNull(Part.HSN)) { Part.HSN = ''; } let GSTValues: any[] = this.GetGSTValueBasedOnTaxCode(Part.TCode, TaxCodes); Part.CGSTAmt = TrUtils.SetValueToZeroIfNull(GSTValues[0]); Part.SGSTAmt = TrUtils.SetValueToZeroIfNull(GSTValues[1]); Part.IGSTAmt = TrUtils.SetValueToZeroIfNull(GSTValues[2]); Part.CombinedTaxPercentage = Add(Part.CGSTAmt ,Part.SGSTAmt , Part.IGSTAmt); }); return Parts; } static ComparePartsByHSN(Parts: any, TaxCodes: any) { let FinalMatchedParts: any[] = []; Parts.forEach((Part: any) => { let MatchedPartsBasedOnHSN = Parts.filter((argPart: any) => { let PartFound: boolean = false; FinalMatchedParts.forEach((FinalArgParts: any) => { let PartIndex: any = FinalArgParts.findIndex((FinalArgPart: any) => { return FinalArgPart._id === argPart._id; }); if (PartIndex !== -1) { PartFound = true; } }); return (argPart.HSN === Part.HSN) && (!PartFound) && (argPart.CGSTAmt === Part.CGSTAmt) && (argPart.IGSTAmt === Part.IGSTAmt) && (argPart.SGSTAmt === Part.SGSTAmt); }); if (MatchedPartsBasedOnHSN.length !== 0) { FinalMatchedParts.push(MatchedPartsBasedOnHSN); } }); return FinalMatchedParts; } static GetTaxGroupingInfoByHSN(FinalMatchedParts: any, TaxCodes: any, DecimalsNumber: number) { let HSNTaxInfo: any[] = []; FinalMatchedParts.forEach((MatchedPart: any) => { let TaxInfo: any = {}; let TaxOnAmount: any = 0; let TaxAmount: any = 0; let HSN: any = MatchedPart[0].HSN; TaxInfo.CombinedTaxPercentage = MatchedPart[0].CombinedTaxPercentage; MatchedPart.forEach((argMatchedGSTPart: any) => { TaxOnAmount = Add(TaxOnAmount,argMatchedGSTPart.AfterPartDisc); TaxAmount = Add(TaxAmount,argMatchedGSTPart.CGST); TaxAmount = Add(TaxAmount,argMatchedGSTPart.IGST); TaxAmount = Add(TaxAmount,argMatchedGSTPart.SGST); }); TaxInfo.HSN = HSN; TaxInfo.TotalTaxableAmount = TrUtils.FixPriceValue(TaxOnAmount, DecimalsNumber); TaxInfo.TotalTaxAmount = TrUtils.FixPriceValue(TaxAmount, DecimalsNumber); TaxInfo.ItemsCount = MatchedPart.length; // let GSTValues: any[] = this.GetGSTValueBasedOnTaxCode(MatchedPart[0].TCode, TaxCodes); // TaxInfo.CGST = GSTValues[0]; // TaxInfo.SGST = GSTValues[1]; // TaxInfo.IGST = GSTValues[2]; TaxInfo.CGST = MatchedPart[0].CGSTAmt; TaxInfo.IGST = MatchedPart[0].IGSTAmt; TaxInfo.SGST = MatchedPart[0].SGSTAmt; if (TaxOnAmount !== 0) { HSNTaxInfo.push(TaxInfo); } }); return HSNTaxInfo; } static GetGSTValueBasedOnTaxCode(TCode: any, TaxCodes: any) { let CGST: number = 0; let SGST: number = 0; let IGST: number = 0; if (TrUtils.IsNull(TCode)) { return [CGST, SGST, IGST]; } let TCodeIndex: any = TaxCodes.findIndex((TaxCode: any) => { return TaxCode._id === Number(TCode); }); if (TCodeIndex !== -1) { if (TaxCodes[TCodeIndex].Type === 'Intra') { return [TaxCodes[TCodeIndex].CGST, TaxCodes[TCodeIndex].SGST, 0]; } else { return [0, 0, TaxCodes[TCodeIndex].IGST]; } } else { return [CGST, SGST, IGST]; } } }