shareneus 1.4.96 → 1.4.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/sales-receive/sales-receive-print.service.js +9 -4
- package/dist/sales-receive/sales-receive-totals.service.d.ts +185 -0
- package/dist/sales-receive/sales-receive-totals.service.js +246 -49
- package/dist/sales-receive/sales-total-calculation.d.ts +5 -0
- package/dist/sales-receive/sales-total-calculation.js +161 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -130,3 +130,4 @@ export { GetItemPriceForPriceList } from "./inventory/items/item-price-for-price
|
|
|
130
130
|
export { CalcItemFinalSalePrice } from "./inventory/items/item-price-for-pricelist";
|
|
131
131
|
export { IsNotNull, IsNull } from "./shared/util";
|
|
132
132
|
export { GetAgeString } from "./shared/util";
|
|
133
|
+
export { SalesTotalCalculationsWithDecimals } from "./sales-receive/sales-total-calculation";
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DebitNotePdfService = exports.DCWithoutPricePdfService = exports.DCLandscapeWithoutPricePdfService = exports.DCLandscapePdfService = exports.CustomerBalancesService = exports.SalesByCustomerPDFService = exports.CustWiseSalesDetailsService = exports.CreditNoteTotalsService = exports.CreditNotePdfService = exports.ConsultationPDFService = exports.ConsultationFullPrintService = exports.ConsultationFeeReceiptPrintService = exports.CNPrintService = exports.ChecklistsPDFService = exports.CheckListPrintService = exports.CategoryWiseItemPDFService = exports.SalesReceiptprintService = exports.AppointmentTotalsService = exports.AnalysisPDFService = exports.VenBalanceXlsxFileService = exports.TallySalesImportXlsxFileService = exports.StockXlsxFileService = exports.IssueSparesXlsxFileService = exports.ScheduledDrugXlsxFileService = exports.ScheduledDrugSummaryXlsxFileService = exports.SalesByServiceSummaryXlsxFileService = exports.SummaryXlsxFileService = exports.ServiceAdvisorWisePartXlsxFileService = exports.ServiceAdvisorWiseLaborXlsxFileService = exports.RepairOrdersXlsxFileService = exports.PaymentsMadeXlsxFileService = exports.PaymentReceiveXlsxFileService = exports.OperatorWiseSummaryXlsxFileService = exports.OperatorWiseDetailsXlsxFileService = exports.ManfWiseSalesXlsxFileService = exports.ItemsWiseSalesXlsxFileService = exports.ItemWiseMOSummaryXlsxFileService = exports.ItemWiseMODetailsXlsxFileService = exports.ItemWiseDoctorSaleXlsxFileService = exports.InvoicesWiseXlsxFileService = exports.InsuranceExpireXlsxFileService = exports.GSTR2ExcelService = exports.GSTR1ExcelService = exports.GSTROXlsxFileService = exports.ExpiringDrugsXlsxFileService = exports.SalesByCustomerXlsxFileService = exports.CustWiseSalesXlsxFileService = exports.CustBalanceXlsxFileService = exports.CategoryWiseItemXlsxFileService = exports.AnalysisXlsxFileService = void 0;
|
|
4
4
|
exports.SharedPDFService = exports.SharedInvoiceprintService = exports.WOPrintService = exports.ScheduledDrugSummaryPDFService = exports.ScheduledDrugPDFService = exports.SalesTotalsService = exports.SaleReceiptPrintService = exports.SalesReceiptpdfService = exports.SalesPrintService = exports.SalesPdfService = exports.SalesByServiceSummaryPDF = exports.ROTotalsService = exports.ROPrintService = exports.RoprintService = exports.RepairOrdersReportsPDFService = exports.ReorderPointPDFService = exports.ReceiptPrintService = exports.PurchaseOrderPDFService = exports.PurchaseOrderTotalsService = exports.PurchaseOrderPrintService = exports.PosReceiptPrintService = exports.POTotalsService = exports.PaymentsReportPDFService = exports.ReceiptPDFService = exports.PackShipPrintService = exports.PackShipPDFService = exports.OperatorWiseSalesSummaryPDF = exports.OperatorWiseSalesDetailsPDF = exports.MaterialOutprintService = exports.MeetingPdfService = exports.ManfWiseSalesService = exports.ItemWiseSalesPDFService = exports.ItemWiseMOSummaryPDF = exports.ItemWiseMODetailsPDF = exports.ItemWiseDoctorSalePDFService = exports.ItemDetaisPdf = exports.IssuePartsprintService = exports.InvoiceTotalsService = exports.InvoiceLandscapePdfService = exports.InvPrintService = exports.InvoiceprintService = exports.InsuranceExpirePDF = exports.ExpiringDrugPDFService = exports.EstPrintService = exports.EquipmentDesignPdf = exports.DeliveryChallanTotalsService = exports.DeliveryChallanPrintService = exports.DeliveryChallanPdfService = exports.DebitNoteTotalsService = exports.DebitNotePrintService = void 0;
|
|
5
|
-
exports.GetAgeString = exports.IsNull = exports.IsNotNull = exports.CalcItemFinalSalePrice = exports.GetItemPriceForPriceList = exports.SalesReceiveTotalsService = exports.SalesReceivePrintService = exports.SalesReceivePdfService = exports.AdjustmentDrugPDFService = exports.HSNSummaryPDFService = exports.HSNSummaryExcelService = exports.ItemBarCodeLabelPdf = exports.NextServiceDatePDFService = exports.NextServiceDateXlsxFileService = exports.ConsultationLetterHeadPDFService = exports.InvoiceLetterheadPdfService = exports.HCInvoiceprintService = exports.InvoicePortraitPrintService = exports.MyDate = exports.TrUtils = exports.VendorDebitNoteTotalsService = exports.VendorDebitNotePrintService = exports.VendorDebitNotePdfService = exports.VendorCreditNoteTotalsService = exports.VendorCreditNotePrintService = exports.VendorCreditNotePDFService = exports.VendorBalancesService = exports.TransferOrderPrintService = exports.TechnicianPrintService = exports.TechnicianpdfService = exports.TaskReportsPDfService = exports.TaskPDfService = exports.PrintSharedService = void 0;
|
|
5
|
+
exports.SalesTotalCalculationsWithDecimals = exports.GetAgeString = exports.IsNull = exports.IsNotNull = exports.CalcItemFinalSalePrice = exports.GetItemPriceForPriceList = exports.SalesReceiveTotalsService = exports.SalesReceivePrintService = exports.SalesReceivePdfService = exports.AdjustmentDrugPDFService = exports.HSNSummaryPDFService = exports.HSNSummaryExcelService = exports.ItemBarCodeLabelPdf = exports.NextServiceDatePDFService = exports.NextServiceDateXlsxFileService = exports.ConsultationLetterHeadPDFService = exports.InvoiceLetterheadPdfService = exports.HCInvoiceprintService = exports.InvoicePortraitPrintService = exports.MyDate = exports.TrUtils = exports.VendorDebitNoteTotalsService = exports.VendorDebitNotePrintService = exports.VendorDebitNotePdfService = exports.VendorCreditNoteTotalsService = exports.VendorCreditNotePrintService = exports.VendorCreditNotePDFService = exports.VendorBalancesService = exports.TransferOrderPrintService = exports.TechnicianPrintService = exports.TechnicianpdfService = exports.TaskReportsPDfService = exports.TaskPDfService = exports.PrintSharedService = void 0;
|
|
6
6
|
var analysis_excel_service_1 = require("./accounting/invoice/reports/excel/analysis-excel.service");
|
|
7
7
|
Object.defineProperty(exports, "AnalysisXlsxFileService", { enumerable: true, get: function () { return analysis_excel_service_1.AnalysisXlsxFileService; } });
|
|
8
8
|
var category_wise_item_excel_service_1 = require("./accounting/invoice/reports/excel/category-wise-item-excel.service");
|
|
@@ -268,3 +268,5 @@ Object.defineProperty(exports, "IsNotNull", { enumerable: true, get: function ()
|
|
|
268
268
|
Object.defineProperty(exports, "IsNull", { enumerable: true, get: function () { return util_1.IsNull; } });
|
|
269
269
|
var util_2 = require("./shared/util");
|
|
270
270
|
Object.defineProperty(exports, "GetAgeString", { enumerable: true, get: function () { return util_2.GetAgeString; } });
|
|
271
|
+
var sales_total_calculation_1 = require("./sales-receive/sales-total-calculation");
|
|
272
|
+
Object.defineProperty(exports, "SalesTotalCalculationsWithDecimals", { enumerable: true, get: function () { return sales_total_calculation_1.SalesTotalCalculationsWithDecimals; } });
|
|
@@ -4,10 +4,11 @@ exports.SalesReceivePrintService = void 0;
|
|
|
4
4
|
const aggregation_1 = require("../aggregation/aggregation");
|
|
5
5
|
const code_enums_1 = require("../enums/code-enums");
|
|
6
6
|
const enums_1 = require("../enums/enums");
|
|
7
|
+
const math_operations_1 = require("../shared/math-operations");
|
|
7
8
|
const shared_print_service_1 = require("../shared/shared-print.service");
|
|
8
9
|
const my_date_1 = require("../utils/my-date");
|
|
9
10
|
const tr_utils_1 = require("../utils/tr-utils");
|
|
10
|
-
const
|
|
11
|
+
const sales_total_calculation_1 = require("./sales-total-calculation");
|
|
11
12
|
class SalesReceivePrintService {
|
|
12
13
|
static GetSalesReceivePrintInfo(OriginalSalesReceiveData, OriginalEntityData, image, IncludeGST, ConsolidateGST, TaxCodes, IsProforma) {
|
|
13
14
|
var _a, _b;
|
|
@@ -26,10 +27,14 @@ class SalesReceivePrintService {
|
|
|
26
27
|
SalesReceivePrintData = shared_print_service_1.PrintSharedService.GetEntityHeaderStyles(SalesReceivePrintData, OriginalEntityData, image);
|
|
27
28
|
SalesReceivePrintData = this.GetSalesReceiveOtherDetailsForPrint(SalesReceivePrintData, argSalesReceiveData);
|
|
28
29
|
let IsTaxable = (IncludeGST && tr_utils_1.TrUtils.isTaxable(argSalesReceiveData.Settings.Tax)) ? true : false;
|
|
29
|
-
let finalTotalsData =
|
|
30
|
+
// let finalTotalsData: any = SalesReceiveTotalsService.GetTotalsValue([], argSalesReceiveData.Items, IsTaxable,
|
|
31
|
+
// true,
|
|
32
|
+
// argSalesReceiveData.Disc, argSalesReceiveData.Perc, TaxCodes, true, argSalesReceiveData.Settings, SalesReceivePrintData.Entity);
|
|
33
|
+
let finalTotalsData = (0, sales_total_calculation_1.SalesTotalCalculationsWithDecimals)(argSalesReceiveData.Items, [], IsTaxable, argSalesReceiveData.DecimalsNumber);
|
|
30
34
|
if (ConsolidateGST) {
|
|
31
|
-
finalTotalsData.CustLaborTotalBeforeDisc = finalTotalsData.CustLaborAfterTax;
|
|
32
|
-
finalTotalsData.CustPartsTotalBeforeDisc = finalTotalsData.CustPartAfterTax;
|
|
35
|
+
// finalTotalsData.CustLaborTotalBeforeDisc = finalTotalsData.CustLaborAfterTax;
|
|
36
|
+
// finalTotalsData.CustPartsTotalBeforeDisc = finalTotalsData.CustPartAfterTax;
|
|
37
|
+
finalTotalsData.CustPartsTotalBeforeDisc = (0, math_operations_1.Add)(finalTotalsData.totalTaxOnItems, (0, math_operations_1.Subtract)(finalTotalsData.subtotalOnItems, finalTotalsData.totalDiscountOnItems));
|
|
33
38
|
}
|
|
34
39
|
SalesReceivePrintData = tr_utils_1.TrUtils.ConcatObjects(SalesReceivePrintData, finalTotalsData);
|
|
35
40
|
SalesReceivePrintData.Items = this.GetItemsPrintInfo(SalesReceivePrintData.Items, ConsolidateGST, TaxCodes, (_b = (_a = OriginalEntityData.Entity.Settings) === null || _a === void 0 ? void 0 : _a.Acc) === null || _b === void 0 ? void 0 : _b.LTot, SalesReceivePrintData.Entity.DecimalsNumber);
|
|
@@ -1,27 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service class for calculating sales receive totals including taxes, discounts and final amounts
|
|
3
|
+
*/
|
|
1
4
|
export declare class SalesReceiveTotalsService {
|
|
5
|
+
/**
|
|
6
|
+
* Main method to calculate totals for sales receive operations
|
|
7
|
+
* @param opCodesList - Array of operation codes/labor items
|
|
8
|
+
* @param PartsList - Array of parts/items to be processed
|
|
9
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
10
|
+
* @param DetailedInfo - Whether to include detailed breakdown information
|
|
11
|
+
* @param Disc - Discount amount
|
|
12
|
+
* @param Perc - Discount percentage
|
|
13
|
+
* @param TaxCodes - Available tax codes for GST calculations
|
|
14
|
+
* @param WithItems - Whether to include items in the response
|
|
15
|
+
* @param Settings - General settings object
|
|
16
|
+
* @param EntitySettings - Entity-specific settings including decimal places
|
|
17
|
+
* @returns Object containing calculated totals and breakdown information
|
|
18
|
+
*/
|
|
2
19
|
static GetTotalsValue(opCodesList: any, PartsList: any, IsIndependentTax: boolean, DetailedInfo: boolean, Disc: any, Perc: string, TaxCodes: any, WithItems: boolean, Settings: any, EntitySettings?: any): any;
|
|
20
|
+
/**
|
|
21
|
+
* Calculates labor part values including discounts and taxes
|
|
22
|
+
* @param PartsList - Array of parts to be processed
|
|
23
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
24
|
+
* @returns Processed parts list with calculated values
|
|
25
|
+
*/
|
|
3
26
|
static CalculateLaborPartValues(PartsList: any, IsIndependentTax: boolean): any;
|
|
27
|
+
/**
|
|
28
|
+
* Resets and recalculates labor part values including discounts and taxes
|
|
29
|
+
* @param PartsList - Array of parts to be processed
|
|
30
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
31
|
+
* @returns Parts list with reset and recalculated values
|
|
32
|
+
*/
|
|
4
33
|
static ResetLaborPartValues(PartsList: any, IsIndependentTax: boolean): any;
|
|
34
|
+
/**
|
|
35
|
+
* Resets part values to zero if they are null or invalid
|
|
36
|
+
* @param Part - Individual part item to reset
|
|
37
|
+
* @returns Part with reset values
|
|
38
|
+
*/
|
|
5
39
|
static ResetLaborPartValueIfInvalid(Part: any): any;
|
|
40
|
+
/**
|
|
41
|
+
* Prepares final repair order data for saving with calculated totals
|
|
42
|
+
* @param LaborList - Array of labor items
|
|
43
|
+
* @param PartsList - Array of parts
|
|
44
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
45
|
+
* @param Disc - Discount amount
|
|
46
|
+
* @param Perc - Discount percentage
|
|
47
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
48
|
+
* @param Settings - General settings
|
|
49
|
+
* @param DecimalsNumber - Number of decimal places for calculations
|
|
50
|
+
* @returns Final totals data object ready for saving
|
|
51
|
+
*/
|
|
6
52
|
static GetFinalRODataForSave(LaborList: any, PartsList: any, IsIndependentTax: boolean, Disc: any, Perc: string, DetailedInfo: boolean, Settings: any, DecimalsNumber: any): any;
|
|
53
|
+
/**
|
|
54
|
+
* Sets main discount values in the totals data object
|
|
55
|
+
* @param Disc - Discount amount
|
|
56
|
+
* @param Perc - Discount percentage
|
|
57
|
+
* @param finalTotalsData - Totals data object to update
|
|
58
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
59
|
+
* @returns Updated totals data with discount values
|
|
60
|
+
*/
|
|
7
61
|
static SetMainDiscountValues(Disc: string, Perc: string, finalTotalsData: any, DetailedInfo: boolean): any;
|
|
62
|
+
/**
|
|
63
|
+
* Calculates final customer totals including subtotals, taxes, and rounded amounts
|
|
64
|
+
* @param finalTotalsData - Existing totals data object
|
|
65
|
+
* @param LaborList - Array of labor items
|
|
66
|
+
* @param PartsList - Array of parts
|
|
67
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
68
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
69
|
+
* @param DecimalsNumber - Number of decimal places for calculations
|
|
70
|
+
* @returns Updated totals data with customer calculations
|
|
71
|
+
*/
|
|
8
72
|
static GetFinalCustomerTotalsData(finalTotalsData: any, LaborList: any, PartsList: any, IsIndependentTax: boolean, DetailedInfo: boolean, DecimalsNumber?: number): any;
|
|
73
|
+
/**
|
|
74
|
+
* Calculates subtotal for labor and parts combined
|
|
75
|
+
* @param LaborList - Array of labor items
|
|
76
|
+
* @param PartsList - Array of parts
|
|
77
|
+
* @returns Calculated subtotal amount
|
|
78
|
+
*/
|
|
9
79
|
static GetSubTotalFor(LaborList: any, PartsList: any): any;
|
|
80
|
+
/**
|
|
81
|
+
* Calculates total amount for parts after applying discounts
|
|
82
|
+
* @param PartsList - Array of parts
|
|
83
|
+
* @returns Total parts amount after discounts
|
|
84
|
+
*/
|
|
10
85
|
static GetPartsTotalAfterDiscount(PartsList: any): any;
|
|
86
|
+
/**
|
|
87
|
+
* Generates detailed totals data including tax breakdowns and groupings
|
|
88
|
+
* @param finalTotalsData - Existing totals data
|
|
89
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
90
|
+
* @param opCodesList - Array of operation codes
|
|
91
|
+
* @param PartsList - Array of parts
|
|
92
|
+
* @param TaxCodes - Available tax codes
|
|
93
|
+
* @param DecimalsNumber - Number of decimal places
|
|
94
|
+
* @returns Enhanced totals data with detailed breakdowns
|
|
95
|
+
*/
|
|
11
96
|
static GetDetailedTotalsData(finalTotalsData: any, IsIndependentTax: boolean, opCodesList: any, PartsList: any, TaxCodes: any, DecimalsNumber?: number): any;
|
|
97
|
+
/**
|
|
98
|
+
* Groups parts by tax percentage for consolidated tax reporting
|
|
99
|
+
* @param Parts - Array of parts to group
|
|
100
|
+
* @param TaxCodes - Available tax codes
|
|
101
|
+
* @param DecimalsNumber - Number of decimal places
|
|
102
|
+
* @returns Array of parts grouped by tax percentage
|
|
103
|
+
*/
|
|
12
104
|
static GetTaxGroupingForPartsByPerc(Parts: any, TaxCodes: any, DecimalsNumber: any): any[];
|
|
105
|
+
/**
|
|
106
|
+
* Compares and groups parts by tax percentage rates
|
|
107
|
+
* @param Parts - Array of parts to compare
|
|
108
|
+
* @param TaxCodes - Available tax codes
|
|
109
|
+
* @returns Array of grouped parts with same tax percentages
|
|
110
|
+
*/
|
|
13
111
|
static ComparePartsByPerc(Parts: any, TaxCodes: any): any[];
|
|
112
|
+
/**
|
|
113
|
+
* Calculates total discounted amount for all parts
|
|
114
|
+
* @param PartsList - Array of parts
|
|
115
|
+
* @param isTaxable - Whether parts are taxable
|
|
116
|
+
* @param finalTotalsData - Existing totals data
|
|
117
|
+
* @returns Total discounted amount including overall part discount
|
|
118
|
+
*/
|
|
14
119
|
static GetPartDiscountedTotal(PartsList: any, isTaxable: boolean, finalTotalsData: any): any;
|
|
120
|
+
/**
|
|
121
|
+
* Calculates total tax amount for all parts
|
|
122
|
+
* @param PartsList - Array of parts
|
|
123
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
124
|
+
* @returns Total tax amount for all parts
|
|
125
|
+
*/
|
|
15
126
|
static GetPartsTaxTotalFor(PartsList: any, IsIndependentTax: boolean): any;
|
|
127
|
+
/**
|
|
128
|
+
* Calculates customer total based on tax calculation type
|
|
129
|
+
* @param finalTotalsData - Existing totals data
|
|
130
|
+
* @param LaborTaxAmount - Total labor tax amount
|
|
131
|
+
* @param PartsTaxAmount - Total parts tax amount
|
|
132
|
+
* @param LaborList - Array of labor items
|
|
133
|
+
* @param PartsList - Array of parts
|
|
134
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
135
|
+
* @returns Final customer total based on tax type
|
|
136
|
+
*/
|
|
16
137
|
static GetCustomerTotalBasedOnTaxType(finalTotalsData: any, LaborTaxAmount: number, PartsTaxAmount: number, LaborList: any, PartsList: any, IsIndependentTax: boolean): any;
|
|
138
|
+
/**
|
|
139
|
+
* Calculates items total after applying discounts (percentage or fixed)
|
|
140
|
+
* @param PartsTotalAfterDisc - Parts total after discount
|
|
141
|
+
* @param PartsTaxAmount - Parts tax amount
|
|
142
|
+
* @param MainPDisc - Main parts discount amount
|
|
143
|
+
* @param PDiscInPerc - Parts discount percentage
|
|
144
|
+
* @returns Final items total after all discounts
|
|
145
|
+
*/
|
|
17
146
|
static ItemsTotalAfterDiscount(PartsTotalAfterDisc: number, PartsTaxAmount: number, MainPDisc: number, PDiscInPerc: string): number;
|
|
147
|
+
/**
|
|
148
|
+
* Calculates total CGST tax amount for labor items
|
|
149
|
+
* @param opCodesList - Array of operation codes/labor
|
|
150
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
151
|
+
* @returns Total CGST amount for labor
|
|
152
|
+
*/
|
|
18
153
|
static GetLaborCGSTTaxTotal(opCodesList: any, IsIndependentTax: boolean): any;
|
|
154
|
+
/**
|
|
155
|
+
* Calculates total IGST tax amount for labor items
|
|
156
|
+
* @param opCodesList - Array of operation codes/labor
|
|
157
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
158
|
+
* @returns Total IGST amount for labor
|
|
159
|
+
*/
|
|
19
160
|
static GetLaborIGSTTaxTotal(opCodesList: any, IsIndependentTax: boolean): any;
|
|
161
|
+
/**
|
|
162
|
+
* Calculates total SGST tax amount for labor items
|
|
163
|
+
* @param opCodesList - Array of operation codes/labor
|
|
164
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
165
|
+
* @returns Total SGST amount for labor
|
|
166
|
+
*/
|
|
20
167
|
static GetLaborSGSTTaxTotal(opCodesList: any, IsIndependentTax: boolean): any;
|
|
168
|
+
/**
|
|
169
|
+
* Calculates GST tax breakdown for all parts (CGST, SGST, IGST, Total)
|
|
170
|
+
* @param PartsList - Array of parts
|
|
171
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
172
|
+
* @returns Array containing [CGST, SGST, IGST, Total Tax] amounts
|
|
173
|
+
*/
|
|
21
174
|
static GetPartGSTTaxTotal(PartsList: any, IsIndependentTax: boolean): number[];
|
|
175
|
+
/**
|
|
176
|
+
* Groups parts by HSN code for tax reporting and compliance
|
|
177
|
+
* @param Parts - Array of parts to group
|
|
178
|
+
* @param TaxCodes - Available tax codes
|
|
179
|
+
* @param DecimalsNumber - Number of decimal places
|
|
180
|
+
* @returns Tax grouping information organized by HSN codes
|
|
181
|
+
*/
|
|
22
182
|
static GetTaxGroupingForPartsByHSN(Parts: any, TaxCodes: any, DecimalsNumber: number): any[];
|
|
183
|
+
/**
|
|
184
|
+
* Adds combined tax percentage calculation to each part based on tax codes
|
|
185
|
+
* @param Parts - Array of parts to process
|
|
186
|
+
* @param TaxCodes - Available tax codes for lookup
|
|
187
|
+
* @returns Parts array with added tax percentage information
|
|
188
|
+
*/
|
|
23
189
|
static GetCombinedTaxPercentage(Parts: any, TaxCodes: any): any;
|
|
190
|
+
/**
|
|
191
|
+
* Compares and groups parts by HSN code and tax rates
|
|
192
|
+
* @param Parts - Array of parts to compare
|
|
193
|
+
* @param TaxCodes - Available tax codes
|
|
194
|
+
* @returns Array of parts grouped by HSN code and tax rates
|
|
195
|
+
*/
|
|
24
196
|
static ComparePartsByHSN(Parts: any, TaxCodes: any): any[];
|
|
197
|
+
/**
|
|
198
|
+
* Generates detailed tax information grouped by HSN codes for compliance reporting
|
|
199
|
+
* @param FinalMatchedParts - Array of grouped parts by HSN
|
|
200
|
+
* @param TaxCodes - Available tax codes
|
|
201
|
+
* @param DecimalsNumber - Number of decimal places for formatting
|
|
202
|
+
* @returns Array of HSN-wise tax information objects
|
|
203
|
+
*/
|
|
25
204
|
static GetTaxGroupingInfoByHSN(FinalMatchedParts: any, TaxCodes: any, DecimalsNumber: any): any[];
|
|
205
|
+
/**
|
|
206
|
+
* Retrieves GST values (CGST, SGST, IGST) based on tax code lookup
|
|
207
|
+
* @param TCode - Tax code identifier
|
|
208
|
+
* @param TaxCodes - Array of available tax codes
|
|
209
|
+
* @returns Array containing [CGST, SGST, IGST] values for the tax code
|
|
210
|
+
*/
|
|
26
211
|
static GetGSTValueBasedOnTaxCode(TCode: any, TaxCodes: any): any[];
|
|
27
212
|
}
|
|
@@ -3,39 +3,71 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SalesReceiveTotalsService = void 0;
|
|
4
4
|
const tr_utils_1 = require("../utils/tr-utils");
|
|
5
5
|
const aggregation_1 = require("../aggregation/aggregation");
|
|
6
|
+
/**
|
|
7
|
+
* Service class for calculating sales receive totals including taxes, discounts and final amounts
|
|
8
|
+
*/
|
|
6
9
|
class SalesReceiveTotalsService {
|
|
10
|
+
/**
|
|
11
|
+
* Main method to calculate totals for sales receive operations
|
|
12
|
+
* @param opCodesList - Array of operation codes/labor items
|
|
13
|
+
* @param PartsList - Array of parts/items to be processed
|
|
14
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
15
|
+
* @param DetailedInfo - Whether to include detailed breakdown information
|
|
16
|
+
* @param Disc - Discount amount
|
|
17
|
+
* @param Perc - Discount percentage
|
|
18
|
+
* @param TaxCodes - Available tax codes for GST calculations
|
|
19
|
+
* @param WithItems - Whether to include items in the response
|
|
20
|
+
* @param Settings - General settings object
|
|
21
|
+
* @param EntitySettings - Entity-specific settings including decimal places
|
|
22
|
+
* @returns Object containing calculated totals and breakdown information
|
|
23
|
+
*/
|
|
7
24
|
static GetTotalsValue(opCodesList, PartsList, IsIndependentTax, DetailedInfo, Disc, Perc, TaxCodes, WithItems, Settings, EntitySettings = {}) {
|
|
8
|
-
//
|
|
9
|
-
// PPerc = TrUtils.SetPercToStringIfNull(PPerc);
|
|
25
|
+
// Sanitize input parameters to ensure valid values
|
|
10
26
|
Perc = tr_utils_1.TrUtils.SetPercToStringIfNull(Perc);
|
|
11
|
-
// LDisc = TrUtils.SetValueToZeroIfNull(LDisc);
|
|
12
|
-
// PDisc = TrUtils.SetValueToZeroIfNull(PDisc);
|
|
13
27
|
Disc = tr_utils_1.TrUtils.SetValueToZeroIfNull(Disc);
|
|
14
|
-
//
|
|
28
|
+
// Calculate labor part values with tax considerations
|
|
15
29
|
PartsList = this.CalculateLaborPartValues(PartsList, IsIndependentTax);
|
|
30
|
+
// Get the main totals data
|
|
16
31
|
let finalTotalsData = this.GetFinalRODataForSave(opCodesList, PartsList, IsIndependentTax, Disc, Perc, DetailedInfo, Settings, EntitySettings.DecimalsNumber);
|
|
32
|
+
// Add detailed breakdown if requested
|
|
17
33
|
if (DetailedInfo) {
|
|
18
34
|
finalTotalsData = this.GetDetailedTotalsData(finalTotalsData, IsIndependentTax, opCodesList, PartsList, TaxCodes, EntitySettings.DecimalsNumber);
|
|
19
35
|
}
|
|
36
|
+
// Include items in response if requested
|
|
20
37
|
if (WithItems) {
|
|
21
|
-
// finalTotalsData.Ops = opCodesList;
|
|
22
38
|
finalTotalsData.Items = PartsList;
|
|
23
39
|
}
|
|
24
40
|
return finalTotalsData;
|
|
25
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Calculates labor part values including discounts and taxes
|
|
44
|
+
* @param PartsList - Array of parts to be processed
|
|
45
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
46
|
+
* @returns Processed parts list with calculated values
|
|
47
|
+
*/
|
|
26
48
|
static CalculateLaborPartValues(PartsList, IsIndependentTax) {
|
|
27
49
|
PartsList = this.ResetLaborPartValues(PartsList, IsIndependentTax);
|
|
28
50
|
return PartsList;
|
|
29
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Resets and recalculates labor part values including discounts and taxes
|
|
54
|
+
* @param PartsList - Array of parts to be processed
|
|
55
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
56
|
+
* @returns Parts list with reset and recalculated values
|
|
57
|
+
*/
|
|
30
58
|
static ResetLaborPartValues(PartsList, IsIndependentTax) {
|
|
31
59
|
PartsList.forEach((Part) => {
|
|
60
|
+
// Reset invalid values to defaults
|
|
32
61
|
Part = this.ResetLaborPartValueIfInvalid(Part);
|
|
62
|
+
// Set minimum quantity to 1 if zero
|
|
33
63
|
if (tr_utils_1.TrUtils.IsZero(Part.Qty)) {
|
|
34
64
|
Part.Qty = 1;
|
|
35
65
|
}
|
|
66
|
+
// Calculate total discounted price
|
|
36
67
|
Part.DiscountedPrice = (0, aggregation_1.addition)(Part.Disc, Part.RecDisc);
|
|
37
|
-
//
|
|
68
|
+
// Calculate amount after discount
|
|
38
69
|
Part.AfterPartDisc = (0, aggregation_1.subtraction)(Part.UnAmt, Part.Disc, Part.RecDisc);
|
|
70
|
+
// Calculate amount after tax based on tax type
|
|
39
71
|
if (IsIndependentTax) {
|
|
40
72
|
Part.AfterPartTax = (0, aggregation_1.addition)(Part.AfterPartDisc, Part.CGST, Part.SGST, Part.IGST);
|
|
41
73
|
}
|
|
@@ -45,6 +77,11 @@ class SalesReceiveTotalsService {
|
|
|
45
77
|
});
|
|
46
78
|
return PartsList;
|
|
47
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Resets part values to zero if they are null or invalid
|
|
82
|
+
* @param Part - Individual part item to reset
|
|
83
|
+
* @returns Part with reset values
|
|
84
|
+
*/
|
|
48
85
|
static ResetLaborPartValueIfInvalid(Part) {
|
|
49
86
|
Part.UnPr = tr_utils_1.TrUtils.SetValueToZeroIfNull(Part.UnPr);
|
|
50
87
|
Part.Disc = tr_utils_1.TrUtils.SetValueToZeroIfNull(Part.Disc);
|
|
@@ -54,51 +91,93 @@ class SalesReceiveTotalsService {
|
|
|
54
91
|
Part.IGST = tr_utils_1.TrUtils.SetValueToZeroIfNull(Part.IGST);
|
|
55
92
|
return Part;
|
|
56
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Prepares final repair order data for saving with calculated totals
|
|
96
|
+
* @param LaborList - Array of labor items
|
|
97
|
+
* @param PartsList - Array of parts
|
|
98
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
99
|
+
* @param Disc - Discount amount
|
|
100
|
+
* @param Perc - Discount percentage
|
|
101
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
102
|
+
* @param Settings - General settings
|
|
103
|
+
* @param DecimalsNumber - Number of decimal places for calculations
|
|
104
|
+
* @returns Final totals data object ready for saving
|
|
105
|
+
*/
|
|
57
106
|
static GetFinalRODataForSave(LaborList, PartsList, IsIndependentTax, Disc, Perc, DetailedInfo, Settings, DecimalsNumber) {
|
|
58
107
|
let finalTotalsData = {};
|
|
108
|
+
// Set discount values
|
|
59
109
|
finalTotalsData = this.SetMainDiscountValues(Disc, Perc, finalTotalsData, DetailedInfo);
|
|
110
|
+
// Add settings to response
|
|
60
111
|
finalTotalsData.Settings = Settings;
|
|
112
|
+
// Calculate customer totals
|
|
61
113
|
finalTotalsData = this.GetFinalCustomerTotalsData(finalTotalsData, [], PartsList, IsIndependentTax, DetailedInfo, DecimalsNumber);
|
|
62
114
|
return finalTotalsData;
|
|
63
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Sets main discount values in the totals data object
|
|
118
|
+
* @param Disc - Discount amount
|
|
119
|
+
* @param Perc - Discount percentage
|
|
120
|
+
* @param finalTotalsData - Totals data object to update
|
|
121
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
122
|
+
* @returns Updated totals data with discount values
|
|
123
|
+
*/
|
|
64
124
|
static SetMainDiscountValues(Disc, Perc, finalTotalsData, DetailedInfo) {
|
|
65
|
-
// finalTotalsData.LDisc = LDisc;
|
|
66
|
-
// finalTotalsData.LPerc = LPerc;
|
|
67
|
-
// finalTotalsData.PDisc = PDisc;
|
|
68
|
-
// finalTotalsData.PPerc = PPerc;
|
|
69
125
|
finalTotalsData.Disc = Disc;
|
|
70
126
|
finalTotalsData.Perc = Perc;
|
|
71
127
|
if (DetailedInfo) {
|
|
72
|
-
// finalTotalsData.FixedLDisc = LDisc;
|
|
73
|
-
// finalTotalsData.FixedPDisc = PDisc;
|
|
74
128
|
finalTotalsData.FixedDisc = Disc;
|
|
75
129
|
}
|
|
76
130
|
return finalTotalsData;
|
|
77
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Calculates final customer totals including subtotals, taxes, and rounded amounts
|
|
134
|
+
* @param finalTotalsData - Existing totals data object
|
|
135
|
+
* @param LaborList - Array of labor items
|
|
136
|
+
* @param PartsList - Array of parts
|
|
137
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
138
|
+
* @param DetailedInfo - Whether to include detailed information
|
|
139
|
+
* @param DecimalsNumber - Number of decimal places for calculations
|
|
140
|
+
* @returns Updated totals data with customer calculations
|
|
141
|
+
*/
|
|
78
142
|
static GetFinalCustomerTotalsData(finalTotalsData, LaborList, PartsList, IsIndependentTax, DetailedInfo, DecimalsNumber = 2) {
|
|
143
|
+
// Calculate subtotal after discounts
|
|
79
144
|
let CustomerAfterDiscTotals = this.GetSubTotalFor([], PartsList);
|
|
80
|
-
//
|
|
145
|
+
// Calculate parts tax total
|
|
81
146
|
let CustPartTaxTotal = this.GetPartsTaxTotalFor(PartsList, IsIndependentTax);
|
|
147
|
+
// Set subtotal with proper decimal formatting
|
|
82
148
|
finalTotalsData.SubTotal = tr_utils_1.TrUtils.FixedTo(CustomerAfterDiscTotals, DecimalsNumber);
|
|
83
|
-
//
|
|
149
|
+
// Calculate discount totals
|
|
84
150
|
let CustPartsDiscTotal = this.GetPartDiscountedTotal(PartsList, IsIndependentTax, finalTotalsData);
|
|
85
|
-
// let CustLaborTotalAfterDisc = this.GetLaborTotalAfterDiscount(LaborList);
|
|
86
151
|
let CustPartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList);
|
|
152
|
+
// Calculate sum total
|
|
87
153
|
finalTotalsData.STotal = (0, aggregation_1.addition)(CustPartsDiscTotal, CustPartsTotalAfterDisc);
|
|
154
|
+
// Calculate final customer total
|
|
88
155
|
let CustTotal = this.GetCustomerTotalBasedOnTaxType(finalTotalsData, 0, CustPartTaxTotal, [], PartsList, IsIndependentTax);
|
|
156
|
+
// Calculate rounding difference and final total
|
|
89
157
|
finalTotalsData.Round = (0, aggregation_1.subtraction)(Math.round(CustTotal), CustTotal);
|
|
90
158
|
finalTotalsData.Total = Math.round(CustTotal);
|
|
159
|
+
// Add detailed information if requested
|
|
91
160
|
if (DetailedInfo) {
|
|
92
161
|
finalTotalsData.FixedSubTotal = tr_utils_1.TrUtils.FixedTo(CustomerAfterDiscTotals, DecimalsNumber);
|
|
93
162
|
finalTotalsData.FixedTotal = tr_utils_1.TrUtils.FixedTo(CustTotal, DecimalsNumber);
|
|
94
163
|
}
|
|
95
164
|
return finalTotalsData;
|
|
96
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Calculates subtotal for labor and parts combined
|
|
168
|
+
* @param LaborList - Array of labor items
|
|
169
|
+
* @param PartsList - Array of parts
|
|
170
|
+
* @returns Calculated subtotal amount
|
|
171
|
+
*/
|
|
97
172
|
static GetSubTotalFor(LaborList, PartsList) {
|
|
98
|
-
// let LaborTotalAfterDisc: any = this.GetLaborTotalAfterDiscount(LaborList);
|
|
99
173
|
let PartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList);
|
|
100
174
|
return PartsTotalAfterDisc;
|
|
101
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Calculates total amount for parts after applying discounts
|
|
178
|
+
* @param PartsList - Array of parts
|
|
179
|
+
* @returns Total parts amount after discounts
|
|
180
|
+
*/
|
|
102
181
|
static GetPartsTotalAfterDiscount(PartsList) {
|
|
103
182
|
let PartsTotalAfterDisc = 0;
|
|
104
183
|
PartsList.forEach((Part) => {
|
|
@@ -106,29 +185,36 @@ class SalesReceiveTotalsService {
|
|
|
106
185
|
});
|
|
107
186
|
return PartsTotalAfterDisc;
|
|
108
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Generates detailed totals data including tax breakdowns and groupings
|
|
190
|
+
* @param finalTotalsData - Existing totals data
|
|
191
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
192
|
+
* @param opCodesList - Array of operation codes
|
|
193
|
+
* @param PartsList - Array of parts
|
|
194
|
+
* @param TaxCodes - Available tax codes
|
|
195
|
+
* @param DecimalsNumber - Number of decimal places
|
|
196
|
+
* @returns Enhanced totals data with detailed breakdowns
|
|
197
|
+
*/
|
|
109
198
|
static GetDetailedTotalsData(finalTotalsData, IsIndependentTax, opCodesList, PartsList, TaxCodes, DecimalsNumber = 2) {
|
|
110
|
-
//
|
|
199
|
+
// Add parts discount and total information
|
|
111
200
|
finalTotalsData.CustPartsDiscTotal = this.GetPartDiscountedTotal(PartsList, IsIndependentTax, finalTotalsData);
|
|
112
|
-
// finalTotalsData.CustLaborTotalAfterDisc = this.GetLaborTotalAfterDiscount(opCodesList);
|
|
113
201
|
finalTotalsData.CustPartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList);
|
|
114
|
-
// finalTotalsData.CustLaborTotalBeforeDisc = TrUtils.FixedTo(finalTotalsData.CustLaborTotalAfterDisc
|
|
115
|
-
// + finalTotalsData.CustLaborDiscTotal);
|
|
116
202
|
finalTotalsData.CustPartsTotalBeforeDisc = (0, aggregation_1.addition)(finalTotalsData.CustPartsTotalAfterDisc, finalTotalsData.CustPartsDiscTotal);
|
|
117
|
-
//
|
|
118
|
-
// finalTotalsData.CustLaborSGST = this.GetLaborSGSTTaxTotal(opCodesList, IsIndependentTax);
|
|
119
|
-
// finalTotalsData.CustLaborCGST = this.GetLaborCGSTTaxTotal(opCodesList, IsIndependentTax);
|
|
120
|
-
// finalTotalsData.CustLaborIGST = this.GetLaborIGSTTaxTotal(opCodesList, IsIndependentTax);
|
|
203
|
+
// Get GST tax breakdown
|
|
121
204
|
let TaxInfo = this.GetPartGSTTaxTotal(PartsList, IsIndependentTax);
|
|
122
205
|
finalTotalsData.CustPartITax = tr_utils_1.TrUtils.SetValueToZeroIfNull(TaxInfo[3]);
|
|
123
206
|
finalTotalsData.CustPartCGST = tr_utils_1.TrUtils.SetValueToZeroIfNull(TaxInfo[0]);
|
|
124
207
|
finalTotalsData.CustPartIGST = tr_utils_1.TrUtils.SetValueToZeroIfNull(TaxInfo[2]);
|
|
125
208
|
finalTotalsData.CustPartSGST = tr_utils_1.TrUtils.SetValueToZeroIfNull(TaxInfo[1]);
|
|
126
|
-
//
|
|
209
|
+
// Calculate after tax amount
|
|
127
210
|
finalTotalsData.CustPartAfterTax = (0, aggregation_1.addition)(finalTotalsData.CustPartITax, finalTotalsData.CustPartsTotalAfterDisc);
|
|
211
|
+
// Add tax grouping information
|
|
128
212
|
finalTotalsData.CustTaxGroupData = this.GetTaxGroupingForPartsByHSN(tr_utils_1.TrUtils.Stringify(PartsList), TaxCodes, DecimalsNumber);
|
|
129
213
|
finalTotalsData.CustTaxGroupDataByPerc = this.GetTaxGroupingForPartsByPerc(PartsList, TaxCodes, DecimalsNumber);
|
|
214
|
+
// Add rounding information
|
|
130
215
|
finalTotalsData.CustTotalRoundedBy = tr_utils_1.TrUtils.FixedTo(finalTotalsData.Round, DecimalsNumber);
|
|
131
216
|
finalTotalsData.CustRoundedTotal = tr_utils_1.TrUtils.FixedTo(finalTotalsData.Total, DecimalsNumber);
|
|
217
|
+
// Format all numeric values to proper decimal places
|
|
132
218
|
for (var key in finalTotalsData) {
|
|
133
219
|
if (key !== 'Total' && key !== 'SubTotal' &&
|
|
134
220
|
key !== 'LDisc' && key !== 'LPerc' && key !== 'PDisc' &&
|
|
@@ -139,17 +225,34 @@ class SalesReceiveTotalsService {
|
|
|
139
225
|
}
|
|
140
226
|
return finalTotalsData;
|
|
141
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Groups parts by tax percentage for consolidated tax reporting
|
|
230
|
+
* @param Parts - Array of parts to group
|
|
231
|
+
* @param TaxCodes - Available tax codes
|
|
232
|
+
* @param DecimalsNumber - Number of decimal places
|
|
233
|
+
* @returns Array of parts grouped by tax percentage
|
|
234
|
+
*/
|
|
142
235
|
static GetTaxGroupingForPartsByPerc(Parts, TaxCodes, DecimalsNumber) {
|
|
236
|
+
// Add combined tax percentage to each part
|
|
143
237
|
Parts = this.GetCombinedTaxPercentage(tr_utils_1.TrUtils.Stringify(Parts), TaxCodes);
|
|
144
|
-
//
|
|
238
|
+
// Group parts with same tax percentages
|
|
145
239
|
let FinalMatchedParts = this.ComparePartsByPerc(Parts, TaxCodes);
|
|
240
|
+
// Generate tax grouping information
|
|
146
241
|
return this.GetTaxGroupingInfoByHSN(FinalMatchedParts, TaxCodes, DecimalsNumber);
|
|
147
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Compares and groups parts by tax percentage rates
|
|
245
|
+
* @param Parts - Array of parts to compare
|
|
246
|
+
* @param TaxCodes - Available tax codes
|
|
247
|
+
* @returns Array of grouped parts with same tax percentages
|
|
248
|
+
*/
|
|
148
249
|
static ComparePartsByPerc(Parts, TaxCodes) {
|
|
149
250
|
let FinalMatchedParts = [];
|
|
150
251
|
Parts === null || Parts === void 0 ? void 0 : Parts.forEach((Part) => {
|
|
252
|
+
// Find parts with matching tax amounts that haven't been grouped yet
|
|
151
253
|
let MatchedPartsBasedOnHSN = Parts.filter((argPart) => {
|
|
152
254
|
let PartFound = false;
|
|
255
|
+
// Check if part is already in a group
|
|
153
256
|
FinalMatchedParts.forEach((FinalArgParts) => {
|
|
154
257
|
let PartIndex = FinalArgParts.findIndex((FinalArgPart) => {
|
|
155
258
|
return FinalArgPart._id === argPart._id;
|
|
@@ -158,35 +261,44 @@ class SalesReceiveTotalsService {
|
|
|
158
261
|
PartFound = true;
|
|
159
262
|
}
|
|
160
263
|
});
|
|
161
|
-
//
|
|
162
|
-
// let argCGST = argGSTValues[0];
|
|
163
|
-
// let argSGST = argGSTValues[1];
|
|
164
|
-
// let argIGST = argGSTValues[2];
|
|
165
|
-
// let partGSTValues: any[] = this.GetGSTValueBasedOnTaxCode(Part.TCode, TaxCodes);
|
|
166
|
-
// let partCGST = partGSTValues[0];
|
|
167
|
-
// let partSGST = partGSTValues[1];
|
|
168
|
-
// let partIGST = partGSTValues[2];
|
|
264
|
+
// Return parts with same tax percentages that aren't already grouped
|
|
169
265
|
return (!PartFound) &&
|
|
170
266
|
(argPart.CGSTAmt === Part.CGSTAmt) && (argPart.IGSTAmt === Part.IGSTAmt) &&
|
|
171
267
|
(argPart.SGSTAmt === Part.SGSTAmt);
|
|
172
268
|
});
|
|
269
|
+
// Add group if it contains parts
|
|
173
270
|
if (MatchedPartsBasedOnHSN.length !== 0) {
|
|
174
271
|
FinalMatchedParts.push(MatchedPartsBasedOnHSN);
|
|
175
272
|
}
|
|
176
273
|
});
|
|
177
274
|
return FinalMatchedParts;
|
|
178
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Calculates total discounted amount for all parts
|
|
278
|
+
* @param PartsList - Array of parts
|
|
279
|
+
* @param isTaxable - Whether parts are taxable
|
|
280
|
+
* @param finalTotalsData - Existing totals data
|
|
281
|
+
* @returns Total discounted amount including overall part discount
|
|
282
|
+
*/
|
|
179
283
|
static GetPartDiscountedTotal(PartsList, isTaxable, finalTotalsData) {
|
|
180
284
|
let PartsDiscountedTotal = 0;
|
|
181
285
|
let overallPartDisc = 0;
|
|
286
|
+
// Add overall part discount if not taxable
|
|
182
287
|
if (!isTaxable) {
|
|
183
288
|
overallPartDisc = tr_utils_1.TrUtils.SetValueToZeroIfNull(finalTotalsData.PDisc);
|
|
184
289
|
}
|
|
290
|
+
// Sum up individual part discounts
|
|
185
291
|
PartsList.forEach((Part) => {
|
|
186
292
|
PartsDiscountedTotal = (0, aggregation_1.addition)(PartsDiscountedTotal, Part.DiscountedPrice);
|
|
187
293
|
});
|
|
188
294
|
return (0, aggregation_1.addition)(PartsDiscountedTotal, overallPartDisc);
|
|
189
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Calculates total tax amount for all parts
|
|
298
|
+
* @param PartsList - Array of parts
|
|
299
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
300
|
+
* @returns Total tax amount for all parts
|
|
301
|
+
*/
|
|
190
302
|
static GetPartsTaxTotalFor(PartsList, IsIndependentTax) {
|
|
191
303
|
let TotalTaxAmt = 0;
|
|
192
304
|
if (IsIndependentTax) {
|
|
@@ -196,28 +308,56 @@ class SalesReceiveTotalsService {
|
|
|
196
308
|
}
|
|
197
309
|
return TotalTaxAmt;
|
|
198
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Calculates customer total based on tax calculation type
|
|
313
|
+
* @param finalTotalsData - Existing totals data
|
|
314
|
+
* @param LaborTaxAmount - Total labor tax amount
|
|
315
|
+
* @param PartsTaxAmount - Total parts tax amount
|
|
316
|
+
* @param LaborList - Array of labor items
|
|
317
|
+
* @param PartsList - Array of parts
|
|
318
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
319
|
+
* @returns Final customer total based on tax type
|
|
320
|
+
*/
|
|
199
321
|
static GetCustomerTotalBasedOnTaxType(finalTotalsData, LaborTaxAmount, PartsTaxAmount, LaborList, PartsList, IsIndependentTax) {
|
|
200
|
-
// let LaborTotalAfterDisc: any = this.GetLaborTotalAfterDiscount(LaborList);
|
|
201
322
|
let PartsTotalAfterDisc = this.GetPartsTotalAfterDiscount(PartsList);
|
|
202
323
|
if (IsIndependentTax) {
|
|
324
|
+
// Add tax amounts to the total
|
|
203
325
|
return (0, aggregation_1.addition)(PartsTotalAfterDisc, LaborTaxAmount, PartsTaxAmount);
|
|
204
326
|
}
|
|
205
327
|
else {
|
|
328
|
+
// Subtract discount from the total
|
|
206
329
|
return (0, aggregation_1.subtraction)(PartsTotalAfterDisc, finalTotalsData.Disc);
|
|
207
330
|
}
|
|
208
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Calculates items total after applying discounts (percentage or fixed)
|
|
334
|
+
* @param PartsTotalAfterDisc - Parts total after discount
|
|
335
|
+
* @param PartsTaxAmount - Parts tax amount
|
|
336
|
+
* @param MainPDisc - Main parts discount amount
|
|
337
|
+
* @param PDiscInPerc - Parts discount percentage
|
|
338
|
+
* @returns Final items total after all discounts
|
|
339
|
+
*/
|
|
209
340
|
static ItemsTotalAfterDiscount(PartsTotalAfterDisc, PartsTaxAmount, MainPDisc, PDiscInPerc) {
|
|
210
341
|
let ItemsTotal = (0, aggregation_1.addition)(PartsTotalAfterDisc, PartsTaxAmount);
|
|
342
|
+
// Apply discount if present
|
|
211
343
|
if (!tr_utils_1.TrUtils.IsZero(MainPDisc)) {
|
|
212
344
|
if (!tr_utils_1.TrUtils.IsEmpty(PDiscInPerc)) {
|
|
345
|
+
// Apply percentage discount
|
|
213
346
|
ItemsTotal = (0, aggregation_1.subtraction)(ItemsTotal, (0, aggregation_1.division)((0, aggregation_1.multiply)(ItemsTotal, Number(PDiscInPerc)), 100));
|
|
214
347
|
}
|
|
215
348
|
else {
|
|
349
|
+
// Apply fixed discount
|
|
216
350
|
ItemsTotal = (0, aggregation_1.subtraction)(ItemsTotal, MainPDisc);
|
|
217
351
|
}
|
|
218
352
|
}
|
|
219
353
|
return ItemsTotal;
|
|
220
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Calculates total CGST tax amount for labor items
|
|
357
|
+
* @param opCodesList - Array of operation codes/labor
|
|
358
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
359
|
+
* @returns Total CGST amount for labor
|
|
360
|
+
*/
|
|
221
361
|
static GetLaborCGSTTaxTotal(opCodesList, IsIndependentTax) {
|
|
222
362
|
let TotalTaxAmt = 0;
|
|
223
363
|
if (IsIndependentTax) {
|
|
@@ -227,6 +367,12 @@ class SalesReceiveTotalsService {
|
|
|
227
367
|
}
|
|
228
368
|
return TotalTaxAmt;
|
|
229
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Calculates total IGST tax amount for labor items
|
|
372
|
+
* @param opCodesList - Array of operation codes/labor
|
|
373
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
374
|
+
* @returns Total IGST amount for labor
|
|
375
|
+
*/
|
|
230
376
|
static GetLaborIGSTTaxTotal(opCodesList, IsIndependentTax) {
|
|
231
377
|
let TotalTaxAmt = 0;
|
|
232
378
|
if (IsIndependentTax) {
|
|
@@ -236,6 +382,12 @@ class SalesReceiveTotalsService {
|
|
|
236
382
|
}
|
|
237
383
|
return TotalTaxAmt;
|
|
238
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Calculates total SGST tax amount for labor items
|
|
387
|
+
* @param opCodesList - Array of operation codes/labor
|
|
388
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
389
|
+
* @returns Total SGST amount for labor
|
|
390
|
+
*/
|
|
239
391
|
static GetLaborSGSTTaxTotal(opCodesList, IsIndependentTax) {
|
|
240
392
|
let TotalTaxAmt = 0;
|
|
241
393
|
if (IsIndependentTax) {
|
|
@@ -245,6 +397,12 @@ class SalesReceiveTotalsService {
|
|
|
245
397
|
}
|
|
246
398
|
return TotalTaxAmt;
|
|
247
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* Calculates GST tax breakdown for all parts (CGST, SGST, IGST, Total)
|
|
402
|
+
* @param PartsList - Array of parts
|
|
403
|
+
* @param IsIndependentTax - Whether tax is calculated independently
|
|
404
|
+
* @returns Array containing [CGST, SGST, IGST, Total Tax] amounts
|
|
405
|
+
*/
|
|
248
406
|
static GetPartGSTTaxTotal(PartsList, IsIndependentTax) {
|
|
249
407
|
let TotalCGSTAmt = 0;
|
|
250
408
|
let TotalSGSTAmt = 0;
|
|
@@ -260,30 +418,56 @@ class SalesReceiveTotalsService {
|
|
|
260
418
|
}
|
|
261
419
|
return [TotalCGSTAmt, TotalSGSTAmt, TotalIGSTAmt, TotalTaxAmt];
|
|
262
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Groups parts by HSN code for tax reporting and compliance
|
|
423
|
+
* @param Parts - Array of parts to group
|
|
424
|
+
* @param TaxCodes - Available tax codes
|
|
425
|
+
* @param DecimalsNumber - Number of decimal places
|
|
426
|
+
* @returns Tax grouping information organized by HSN codes
|
|
427
|
+
*/
|
|
263
428
|
static GetTaxGroupingForPartsByHSN(Parts, TaxCodes, DecimalsNumber) {
|
|
429
|
+
// Add combined tax percentage to parts
|
|
264
430
|
Parts = this.GetCombinedTaxPercentage(Parts, TaxCodes);
|
|
265
|
-
//
|
|
431
|
+
// Group parts by HSN code
|
|
266
432
|
let FinalMatchedParts = this.ComparePartsByHSN(Parts, TaxCodes);
|
|
433
|
+
// Generate HSN-based tax grouping information
|
|
267
434
|
return this.GetTaxGroupingInfoByHSN(FinalMatchedParts, TaxCodes, DecimalsNumber);
|
|
268
435
|
}
|
|
436
|
+
/**
|
|
437
|
+
* Adds combined tax percentage calculation to each part based on tax codes
|
|
438
|
+
* @param Parts - Array of parts to process
|
|
439
|
+
* @param TaxCodes - Available tax codes for lookup
|
|
440
|
+
* @returns Parts array with added tax percentage information
|
|
441
|
+
*/
|
|
269
442
|
static GetCombinedTaxPercentage(Parts, TaxCodes) {
|
|
270
443
|
Parts.forEach((Part) => {
|
|
444
|
+
// Ensure HSN is not null
|
|
271
445
|
if (tr_utils_1.TrUtils.IsNull(Part.HSN)) {
|
|
272
446
|
Part.HSN = '';
|
|
273
447
|
}
|
|
448
|
+
// Get GST values based on tax code
|
|
274
449
|
let GSTValues = this.GetGSTValueBasedOnTaxCode(Part.TCode, TaxCodes);
|
|
275
450
|
Part.CGSTAmt = tr_utils_1.TrUtils.SetValueToZeroIfNull(GSTValues[0]);
|
|
276
451
|
Part.SGSTAmt = tr_utils_1.TrUtils.SetValueToZeroIfNull(GSTValues[1]);
|
|
277
452
|
Part.IGSTAmt = tr_utils_1.TrUtils.SetValueToZeroIfNull(GSTValues[2]);
|
|
453
|
+
// Calculate combined tax percentage
|
|
278
454
|
Part.CombinedTaxPercentage = (0, aggregation_1.addition)(Part.CGSTAmt, Part.SGSTAmt, Part.IGSTAmt);
|
|
279
455
|
});
|
|
280
456
|
return Parts;
|
|
281
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* Compares and groups parts by HSN code and tax rates
|
|
460
|
+
* @param Parts - Array of parts to compare
|
|
461
|
+
* @param TaxCodes - Available tax codes
|
|
462
|
+
* @returns Array of parts grouped by HSN code and tax rates
|
|
463
|
+
*/
|
|
282
464
|
static ComparePartsByHSN(Parts, TaxCodes) {
|
|
283
465
|
let FinalMatchedParts = [];
|
|
284
466
|
Parts.forEach((Part) => {
|
|
467
|
+
// Find parts with same HSN and tax rates that haven't been grouped
|
|
285
468
|
let MatchedPartsBasedOnHSN = Parts.filter((argPart) => {
|
|
286
469
|
let PartFound = false;
|
|
470
|
+
// Check if part is already in a group
|
|
287
471
|
FinalMatchedParts.forEach((FinalArgParts) => {
|
|
288
472
|
let PartIndex = FinalArgParts.findIndex((FinalArgPart) => {
|
|
289
473
|
return FinalArgPart._id === argPart._id;
|
|
@@ -292,24 +476,25 @@ class SalesReceiveTotalsService {
|
|
|
292
476
|
PartFound = true;
|
|
293
477
|
}
|
|
294
478
|
});
|
|
295
|
-
//
|
|
296
|
-
// let argCGST = argGSTValues[0];
|
|
297
|
-
// let argSGST = argGSTValues[1];
|
|
298
|
-
// let argIGST = argGSTValues[2];
|
|
299
|
-
// let partGSTValues: any[] = this.GetGSTValueBasedOnTaxCode(Part.TCode, TaxCodes);
|
|
300
|
-
// let partCGST = partGSTValues[0];
|
|
301
|
-
// let partSGST = partGSTValues[1];
|
|
302
|
-
// let partIGST = partGSTValues[2];
|
|
479
|
+
// Return parts with same HSN and tax rates that aren't grouped yet
|
|
303
480
|
return (argPart.HSN === Part.HSN) && (!PartFound) &&
|
|
304
481
|
(argPart.CGSTAmt === Part.CGSTAmt) && (argPart.IGSTAmt === Part.IGSTAmt) &&
|
|
305
482
|
(argPart.SGSTAmt === Part.SGSTAmt);
|
|
306
483
|
});
|
|
484
|
+
// Add group if it contains parts
|
|
307
485
|
if (MatchedPartsBasedOnHSN.length !== 0) {
|
|
308
486
|
FinalMatchedParts.push(MatchedPartsBasedOnHSN);
|
|
309
487
|
}
|
|
310
488
|
});
|
|
311
489
|
return FinalMatchedParts;
|
|
312
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Generates detailed tax information grouped by HSN codes for compliance reporting
|
|
493
|
+
* @param FinalMatchedParts - Array of grouped parts by HSN
|
|
494
|
+
* @param TaxCodes - Available tax codes
|
|
495
|
+
* @param DecimalsNumber - Number of decimal places for formatting
|
|
496
|
+
* @returns Array of HSN-wise tax information objects
|
|
497
|
+
*/
|
|
313
498
|
static GetTaxGroupingInfoByHSN(FinalMatchedParts, TaxCodes, DecimalsNumber) {
|
|
314
499
|
let HSNTaxInfo = [];
|
|
315
500
|
FinalMatchedParts.forEach((MatchedPart) => {
|
|
@@ -319,8 +504,10 @@ class SalesReceiveTotalsService {
|
|
|
319
504
|
let CGSTAmt = 0;
|
|
320
505
|
let SGSTAmt = 0;
|
|
321
506
|
let IGSTAmt = 0;
|
|
507
|
+
// Get HSN code and tax percentage from first item
|
|
322
508
|
let HSN = MatchedPart[0].HSN;
|
|
323
509
|
TaxInfo.CombinedTaxPercentage = MatchedPart[0].CombinedTaxPercentage;
|
|
510
|
+
// Calculate totals for all parts in this HSN group
|
|
324
511
|
MatchedPart.forEach((argMatchedGSTPart) => {
|
|
325
512
|
TaxOnAmount = (0, aggregation_1.addition)(TaxOnAmount, tr_utils_1.TrUtils.FixedTo(argMatchedGSTPart.AfterPartDisc, DecimalsNumber));
|
|
326
513
|
TaxAmount = (0, aggregation_1.addition)(TaxAmount, tr_utils_1.TrUtils.FixedTo(argMatchedGSTPart.CGST, DecimalsNumber));
|
|
@@ -330,6 +517,7 @@ class SalesReceiveTotalsService {
|
|
|
330
517
|
SGSTAmt = (0, aggregation_1.addition)(SGSTAmt, tr_utils_1.TrUtils.FixedTo(argMatchedGSTPart.SGST, DecimalsNumber));
|
|
331
518
|
IGSTAmt = (0, aggregation_1.addition)(IGSTAmt, tr_utils_1.TrUtils.FixedTo(argMatchedGSTPart.IGST, DecimalsNumber));
|
|
332
519
|
});
|
|
520
|
+
// Build tax information object
|
|
333
521
|
TaxInfo.HSN = HSN;
|
|
334
522
|
TaxInfo.CGSTAmt = CGSTAmt;
|
|
335
523
|
TaxInfo.SGSTAmt = SGSTAmt;
|
|
@@ -337,38 +525,47 @@ class SalesReceiveTotalsService {
|
|
|
337
525
|
TaxInfo.TotalTaxableAmount = tr_utils_1.TrUtils.FixPriceValue(TaxOnAmount, DecimalsNumber);
|
|
338
526
|
TaxInfo.TotalTaxAmount = tr_utils_1.TrUtils.FixPriceValue(TaxAmount, DecimalsNumber);
|
|
339
527
|
TaxInfo.ItemsCount = MatchedPart.length;
|
|
340
|
-
// let GSTValues: any[] = this.GetGSTValueBasedOnTaxCode(MatchedPart[0].TCode, TaxCodes);
|
|
341
|
-
// TaxInfo.CGST = GSTValues[0];
|
|
342
|
-
// TaxInfo.SGST = GSTValues[1];
|
|
343
|
-
// TaxInfo.IGST = GSTValues[2];
|
|
344
528
|
TaxInfo.CGST = MatchedPart[0].CGSTAmt;
|
|
345
529
|
TaxInfo.IGST = MatchedPart[0].IGSTAmt;
|
|
346
530
|
TaxInfo.SGST = MatchedPart[0].SGSTAmt;
|
|
531
|
+
// Only add if there's a taxable amount
|
|
347
532
|
if (TaxOnAmount !== 0) {
|
|
348
533
|
HSNTaxInfo.push(TaxInfo);
|
|
349
534
|
}
|
|
350
535
|
});
|
|
351
536
|
return HSNTaxInfo;
|
|
352
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Retrieves GST values (CGST, SGST, IGST) based on tax code lookup
|
|
540
|
+
* @param TCode - Tax code identifier
|
|
541
|
+
* @param TaxCodes - Array of available tax codes
|
|
542
|
+
* @returns Array containing [CGST, SGST, IGST] values for the tax code
|
|
543
|
+
*/
|
|
353
544
|
static GetGSTValueBasedOnTaxCode(TCode, TaxCodes) {
|
|
354
545
|
let CGST = 0;
|
|
355
546
|
let SGST = 0;
|
|
356
547
|
let IGST = 0;
|
|
548
|
+
// Return zeros if tax code is null
|
|
357
549
|
if (tr_utils_1.TrUtils.IsNull(TCode)) {
|
|
358
550
|
return [CGST, SGST, IGST];
|
|
359
551
|
}
|
|
552
|
+
// Find tax code in the array
|
|
360
553
|
let TCodeIndex = TaxCodes.findIndex((TaxCode) => {
|
|
361
554
|
return TaxCode._id === Number(TCode);
|
|
362
555
|
});
|
|
556
|
+
// Return appropriate tax values based on tax type
|
|
363
557
|
if (TCodeIndex !== -1) {
|
|
364
558
|
if (TaxCodes[TCodeIndex].Type === 'Intra') {
|
|
559
|
+
// Intra-state: CGST + SGST
|
|
365
560
|
return [TaxCodes[TCodeIndex].CGST, TaxCodes[TCodeIndex].SGST, 0];
|
|
366
561
|
}
|
|
367
562
|
else {
|
|
563
|
+
// Inter-state: IGST only
|
|
368
564
|
return [0, 0, TaxCodes[TCodeIndex].IGST];
|
|
369
565
|
}
|
|
370
566
|
}
|
|
371
567
|
else {
|
|
568
|
+
// Tax code not found, return zeros
|
|
372
569
|
return [CGST, SGST, IGST];
|
|
373
570
|
}
|
|
374
571
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function SalesTotalCalculations(items?: any[], ops?: any[], isTaxable?: boolean): any;
|
|
2
|
+
/**
|
|
3
|
+
* Enhanced version with decimal places control
|
|
4
|
+
*/
|
|
5
|
+
export declare function SalesTotalCalculationsWithDecimals(items?: any[], ops?: any[], isTaxable?: boolean, decimalPlaces?: number): any;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SalesTotalCalculations = SalesTotalCalculations;
|
|
4
|
+
exports.SalesTotalCalculationsWithDecimals = SalesTotalCalculationsWithDecimals;
|
|
5
|
+
const math_operations_1 = require("../shared/math-operations");
|
|
6
|
+
const util_1 = require("../shared/util");
|
|
7
|
+
/**
|
|
8
|
+
* Safely handles null/undefined arrays and returns empty array
|
|
9
|
+
*/
|
|
10
|
+
function safeArray(arr) {
|
|
11
|
+
return Array.isArray(arr) ? arr : [];
|
|
12
|
+
}
|
|
13
|
+
function SalesTotalCalculations(items = [], ops = [], isTaxable = false) {
|
|
14
|
+
// Handle null/undefined arrays
|
|
15
|
+
const safeItems = safeArray(items);
|
|
16
|
+
const safeOps = safeArray(ops);
|
|
17
|
+
// Initialize all totals
|
|
18
|
+
let total = 0;
|
|
19
|
+
let subtotalOnItems = 0;
|
|
20
|
+
let subtotalOnLabor = 0;
|
|
21
|
+
let subtotal = 0;
|
|
22
|
+
let totalTax = 0;
|
|
23
|
+
let totalTaxOnItems = 0;
|
|
24
|
+
let totalTaxOnLabor = 0;
|
|
25
|
+
let totalDiscount = 0;
|
|
26
|
+
let totalDiscountOnItems = 0;
|
|
27
|
+
let totalDiscountOnLabor = 0;
|
|
28
|
+
let roundOff = 0;
|
|
29
|
+
// Tax breakdown totals - only calculate if taxable
|
|
30
|
+
let totalSGST = 0;
|
|
31
|
+
let totalCGST = 0;
|
|
32
|
+
let totalIGST = 0;
|
|
33
|
+
let totalSGSTOnItems = 0;
|
|
34
|
+
let totalCGSTOnItems = 0;
|
|
35
|
+
let totalIGSTOnItems = 0;
|
|
36
|
+
let totalSGSTOnLabor = 0;
|
|
37
|
+
let totalCGSTOnLabor = 0;
|
|
38
|
+
let totalIGSTOnLabor = 0;
|
|
39
|
+
// Calculate items totals with null safety
|
|
40
|
+
safeItems.forEach((item) => {
|
|
41
|
+
const itemDisc = (0, util_1.GetNumber)(item.Disc);
|
|
42
|
+
const itemRecDisc = (0, util_1.GetNumber)(item.RecDisc);
|
|
43
|
+
const itemUnAmt = (0, util_1.GetNumber)(item.UnAmt);
|
|
44
|
+
totalDiscountOnItems = (0, math_operations_1.Add)(totalDiscountOnItems, itemDisc, itemRecDisc);
|
|
45
|
+
subtotalOnItems = (0, math_operations_1.Add)(subtotalOnItems, itemUnAmt);
|
|
46
|
+
// Only calculate tax if taxable
|
|
47
|
+
if (isTaxable) {
|
|
48
|
+
const itemSGST = (0, util_1.GetNumber)(item.SGST);
|
|
49
|
+
const itemCGST = (0, util_1.GetNumber)(item.CGST);
|
|
50
|
+
const itemIGST = (0, util_1.GetNumber)(item.IGST);
|
|
51
|
+
// Add individual tax amounts for items
|
|
52
|
+
totalSGSTOnItems = (0, math_operations_1.Add)(totalSGSTOnItems, itemSGST);
|
|
53
|
+
totalCGSTOnItems = (0, math_operations_1.Add)(totalCGSTOnItems, itemCGST);
|
|
54
|
+
totalIGSTOnItems = (0, math_operations_1.Add)(totalIGSTOnItems, itemIGST);
|
|
55
|
+
totalTaxOnItems = (0, math_operations_1.Add)(totalTaxOnItems, itemSGST, itemCGST, itemIGST);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// Calculate operations/labor totals with null safety
|
|
59
|
+
safeOps.forEach((op) => {
|
|
60
|
+
const opDisc = (0, util_1.GetNumber)(op.Disc);
|
|
61
|
+
const opRecDisc = (0, util_1.GetNumber)(op.RecDisc);
|
|
62
|
+
const opAmt = (0, util_1.GetNumber)(op.Amt);
|
|
63
|
+
totalDiscountOnLabor = (0, math_operations_1.Add)(totalDiscountOnLabor, opDisc, opRecDisc);
|
|
64
|
+
subtotalOnLabor = (0, math_operations_1.Add)(subtotalOnLabor, opAmt);
|
|
65
|
+
// Only calculate tax if taxable
|
|
66
|
+
if (isTaxable) {
|
|
67
|
+
const opSGST = (0, util_1.GetNumber)(op.SGST);
|
|
68
|
+
const opCGST = (0, util_1.GetNumber)(op.CGST);
|
|
69
|
+
const opIGST = (0, util_1.GetNumber)(op.IGST);
|
|
70
|
+
// Add individual tax amounts for operations/labor
|
|
71
|
+
totalSGSTOnLabor = (0, math_operations_1.Add)(totalSGSTOnLabor, opSGST);
|
|
72
|
+
totalCGSTOnLabor = (0, math_operations_1.Add)(totalCGSTOnLabor, opCGST);
|
|
73
|
+
totalIGSTOnLabor = (0, math_operations_1.Add)(totalIGSTOnLabor, opIGST);
|
|
74
|
+
totalTaxOnLabor = (0, math_operations_1.Add)(totalTaxOnLabor, opSGST, opCGST, opIGST);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// Calculate combined totals
|
|
78
|
+
totalDiscount = (0, math_operations_1.Add)(totalDiscountOnItems, totalDiscountOnLabor);
|
|
79
|
+
totalTax = (0, math_operations_1.Add)(totalTaxOnItems, totalTaxOnLabor);
|
|
80
|
+
subtotal = (0, math_operations_1.Add)(subtotalOnItems, subtotalOnLabor);
|
|
81
|
+
// Calculate combined tax breakdown totals only if taxable
|
|
82
|
+
if (isTaxable) {
|
|
83
|
+
totalSGST = (0, math_operations_1.Add)(totalSGSTOnItems, totalSGSTOnLabor);
|
|
84
|
+
totalCGST = (0, math_operations_1.Add)(totalCGSTOnItems, totalCGSTOnLabor);
|
|
85
|
+
totalIGST = (0, math_operations_1.Add)(totalIGSTOnItems, totalIGSTOnLabor);
|
|
86
|
+
}
|
|
87
|
+
// FIXED CALCULATION: Correct order of operations
|
|
88
|
+
// Step 1: Calculate net amount after discount
|
|
89
|
+
const netAmountAfterDiscount = (0, math_operations_1.Subtract)(subtotal, totalDiscount);
|
|
90
|
+
// Step 2: Add tax if taxable
|
|
91
|
+
total = isTaxable ? (0, math_operations_1.Add)(netAmountAfterDiscount, totalTax) : netAmountAfterDiscount;
|
|
92
|
+
// FIXED ROUNDING: Use Math.round instead of Math.floor
|
|
93
|
+
const roundedTotal = Math.round(total);
|
|
94
|
+
roundOff = (0, math_operations_1.Subtract)(roundedTotal, total);
|
|
95
|
+
// Update total to rounded value
|
|
96
|
+
total = roundedTotal;
|
|
97
|
+
// Base return object
|
|
98
|
+
const result = {
|
|
99
|
+
total,
|
|
100
|
+
subtotal,
|
|
101
|
+
totalDiscount,
|
|
102
|
+
roundOff,
|
|
103
|
+
subtotalOnItems,
|
|
104
|
+
subtotalOnLabor,
|
|
105
|
+
totalDiscountOnItems,
|
|
106
|
+
totalDiscountOnLabor,
|
|
107
|
+
netAmountAfterDiscount
|
|
108
|
+
};
|
|
109
|
+
// Only include tax fields if taxable
|
|
110
|
+
if (isTaxable) {
|
|
111
|
+
result.totalTax = totalTax;
|
|
112
|
+
result.totalTaxOnItems = totalTaxOnItems;
|
|
113
|
+
result.totalTaxOnLabor = totalTaxOnLabor;
|
|
114
|
+
result.totalSGST = totalSGST;
|
|
115
|
+
result.totalCGST = totalCGST;
|
|
116
|
+
result.totalIGST = totalIGST;
|
|
117
|
+
result.totalSGSTOnItems = totalSGSTOnItems;
|
|
118
|
+
result.totalCGSTOnItems = totalCGSTOnItems;
|
|
119
|
+
result.totalIGSTOnItems = totalIGSTOnItems;
|
|
120
|
+
result.totalSGSTOnLabor = totalSGSTOnLabor;
|
|
121
|
+
result.totalCGSTOnLabor = totalCGSTOnLabor;
|
|
122
|
+
result.totalIGSTOnLabor = totalIGSTOnLabor;
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Enhanced version with decimal places control
|
|
128
|
+
*/
|
|
129
|
+
function SalesTotalCalculationsWithDecimals(items = [], ops = [], isTaxable = false, decimalPlaces = 2) {
|
|
130
|
+
const result = SalesTotalCalculations(items, ops, isTaxable);
|
|
131
|
+
// Round all values to specified decimal places
|
|
132
|
+
const roundToDecimals = (num) => Math.round(num * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
|
|
133
|
+
// Base rounded result
|
|
134
|
+
const roundedResult = {
|
|
135
|
+
total: roundToDecimals(result.total),
|
|
136
|
+
subtotal: roundToDecimals(result.subtotal),
|
|
137
|
+
totalDiscount: roundToDecimals(result.totalDiscount),
|
|
138
|
+
roundOff: roundToDecimals(result.roundOff),
|
|
139
|
+
subtotalOnItems: roundToDecimals(result.subtotalOnItems),
|
|
140
|
+
subtotalOnLabor: roundToDecimals(result.subtotalOnLabor),
|
|
141
|
+
totalDiscountOnItems: roundToDecimals(result.totalDiscountOnItems),
|
|
142
|
+
totalDiscountOnLabor: roundToDecimals(result.totalDiscountOnLabor),
|
|
143
|
+
netAmountAfterDiscount: roundToDecimals(result.netAmountAfterDiscount)
|
|
144
|
+
};
|
|
145
|
+
// Only include tax fields if taxable
|
|
146
|
+
if (isTaxable) {
|
|
147
|
+
roundedResult.totalTax = roundToDecimals(result.totalTax);
|
|
148
|
+
roundedResult.totalTaxOnItems = roundToDecimals(result.totalTaxOnItems);
|
|
149
|
+
roundedResult.totalTaxOnLabor = roundToDecimals(result.totalTaxOnLabor);
|
|
150
|
+
roundedResult.totalSGST = roundToDecimals(result.totalSGST);
|
|
151
|
+
roundedResult.totalCGST = roundToDecimals(result.totalCGST);
|
|
152
|
+
roundedResult.totalIGST = roundToDecimals(result.totalIGST);
|
|
153
|
+
roundedResult.totalSGSTOnItems = roundToDecimals(result.totalSGSTOnItems);
|
|
154
|
+
roundedResult.totalCGSTOnItems = roundToDecimals(result.totalCGSTOnItems);
|
|
155
|
+
roundedResult.totalIGSTOnItems = roundToDecimals(result.totalIGSTOnItems);
|
|
156
|
+
roundedResult.totalSGSTOnLabor = roundToDecimals(result.totalSGSTOnLabor);
|
|
157
|
+
roundedResult.totalCGSTOnLabor = roundToDecimals(result.totalCGSTOnLabor);
|
|
158
|
+
roundedResult.totalIGSTOnLabor = roundToDecimals(result.totalIGSTOnLabor);
|
|
159
|
+
}
|
|
160
|
+
return roundedResult;
|
|
161
|
+
}
|