softseti-sale-calculator-library 4.0.1 → 4.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "softseti-sale-calculator-library",
3
- "version": "4.0.1",
3
+ "version": "4.1.1",
4
4
  "description": "Sales calculation engine by Softseti",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -1,9 +1,7 @@
1
1
  // src/rules/RuleEngine.js
2
- const { ZenEngine } = require('@gorules/zen-engine');
3
-
4
2
  class RuleEngine {
5
- constructor() {
6
- this.engine = new ZenEngine();
3
+ constructor(zenEngine) {
4
+ this.engine = zenEngine ? new zenEngine() : null;
7
5
  this.ruleCache = new Map();
8
6
  }
9
7
 
@@ -15,6 +13,10 @@ class RuleEngine {
15
13
  */
16
14
  async evaluateRule(ruleContent, context) {
17
15
  try {
16
+ // Verificar si el motor está disponible
17
+ if (!this.engine) {
18
+ throw new Error('Rule engine not initialized. ZenEngine dependency not provided.');
19
+ }
18
20
 
19
21
  const decision = this.engine.createDecision(ruleContent);
20
22
  const result = await decision.safeEvaluate(context);
@@ -34,16 +36,17 @@ class RuleEngine {
34
36
  * @returns {Promise<Array>} Array of rule execution results
35
37
  */
36
38
  async executeRules(rules, context) {
39
+ if (!this.engine || !rules || rules.length === 0) {
40
+ return [];
41
+ }
42
+
37
43
  const results = [];
38
44
 
39
45
  for (const rule of rules) {
40
46
  try {
41
47
  const result = await this.evaluateRule(rule.rule_content, context);
42
- results.push(
43
- result
44
- );
48
+ results.push(result);
45
49
  } catch (error) {
46
-
47
50
  results.push({
48
51
  ruleId: rule.id,
49
52
  success: false,
@@ -19,6 +19,8 @@ let useRounding = false;
19
19
 
20
20
  let preprocessedSale = {};
21
21
 
22
+ let zenEngineDependency = null;
23
+
22
24
  /**
23
25
  * Sales Calculation Engine (V1)
24
26
  * @author softseti
@@ -39,13 +41,13 @@ let preprocessedSale = {};
39
41
  * - settings: GlobalSettings
40
42
  */
41
43
 
42
- function init(params) {
44
+ function init(params, dependencies = {}) {
43
45
  products = params.products || {};
44
46
  productTaxes = params.product_taxes || {};
45
47
  taxes = params.taxes || {};
46
48
  wholesaleLevels = params.wholesale_levels || {};
47
49
  settings = params.settings || {};
48
- // Set currencies convertion
50
+ // Set currencies conversion
49
51
  exchangeRates = params.exchange_rates || {};
50
52
  currencyConverterRates = params.currency_converter_rates || {};
51
53
  currencies = params.currencies || {};
@@ -56,6 +58,11 @@ function init(params) {
56
58
 
57
59
  useRounding = params.use_rounding !== undefined ? params.use_rounding : false;
58
60
 
61
+ // Store dependencies
62
+ if (dependencies.zenEngine) {
63
+ zenEngineDependency = dependencies.zenEngine;
64
+ }
65
+
59
66
  // Start engine
60
67
  initializeRuleSystem(businessRules);
61
68
 
@@ -67,20 +74,19 @@ function init(params) {
67
74
 
68
75
  function initializeRuleSystem(businessRules) {
69
76
  try {
70
- ruleEngine = new RuleEngine();
77
+ ruleEngine = new RuleEngine(zenEngineDependency);
71
78
  ruleManager = new RuleManager();
72
79
 
73
- if (businessRules && Object.keys(businessRules).length > 0) {
74
-
80
+ if (businessRules && Object.keys(businessRules).length > 0) {
75
81
  ruleManager.loadRules(businessRules);
76
- console.log('Sistema de reglas inicializado correctamente');
82
+ console.log('Rule system initialized successfully');
77
83
 
78
84
  } else {
79
- console.warn('No se encontraron reglas de negocio para cargar');
85
+ console.warn('No business rules found to load');
80
86
  }
81
87
  } catch (error) {
82
- console.error('Error al inicializar el sistema de reglas:', error);
83
- // Fallback: continuar sin reglas
88
+ console.error('Error initializing rule system:', error);
89
+ // Fallback: without rules
84
90
  ruleEngine = null;
85
91
  ruleManager = null;
86
92
  }
@@ -94,10 +100,10 @@ function initializeRuleSystem(businessRules) {
94
100
  function validateSaleStructure(sale) {
95
101
  const required = ['receipt_type_key', 'company_id', 'branch_id', 'dwSaleProducts'];
96
102
  if (required.some(field => !sale[field])) {
97
- throw new Error("Estructura de venta inválida");
103
+ throw new Error("Invalid sale structure");
98
104
  }
99
105
  if (Object.keys(products).length === 0) {
100
- throw new Error("Productos no cargados");
106
+ throw new Error("Products not loaded");
101
107
  }
102
108
  }
103
109
 
@@ -279,7 +285,7 @@ function calcDwSaleProductPrice(saleProduct, sale) {
279
285
 
280
286
  const saleCurrency = sale.currency_iso;
281
287
 
282
- // Convertion currency
288
+ // Currency conversion
283
289
  if (productCurrency && saleCurrency && productCurrency !== saleCurrency) {
284
290
  return exchange(
285
291
  basePrice,
@@ -287,7 +293,7 @@ function calcDwSaleProductPrice(saleProduct, sale) {
287
293
  saleCurrency
288
294
  );
289
295
  }
290
- // If not exist exchange and convert rate return the basePrice.
296
+ // If no exchange or conversion rate exists, return the basePrice.
291
297
  return basePrice;
292
298
  }
293
299
 
@@ -319,7 +325,7 @@ async function getApplicableProductTaxes(saleProduct, productSum, sale) {
319
325
  // GET General Taxes
320
326
  const generalTaxes = getGeneralTaxes(sale);
321
327
 
322
- // Combination for taxes
328
+ // Combine all applicable taxes
323
329
  const taxes = [...specificTaxes, ...generalTaxes];
324
330
 
325
331
  // Get rules for taxes
@@ -472,14 +478,14 @@ function getTaxReceiptTypeKey(receiptType) {
472
478
  function exchange(amount, fromCurrency, toCurrency) {
473
479
  if (fromCurrency === toCurrency) return roundCurrency(amount);
474
480
 
475
- // GET EXANGE RATE
481
+ // GET EXCHANGE RATE
476
482
  const exchangeRateModel = findExchangeRate(fromCurrency, toCurrency);
477
483
 
478
484
  if (exchangeRateModel) {
479
485
  return roundCurrency(applyExchangeStrategy(amount, exchangeRateModel));
480
486
  }
481
487
 
482
- // GET CURRENCY CONVERTER RATE WHEN NOT EXIST THE EXANGE RATE
488
+ // GET CURRENCY CONVERTER RATE WHEN NO EXCHANGE RATE EXISTS
483
489
  const currencyConverterRateModel = findCurrencyConverterRate(fromCurrency, toCurrency);
484
490
 
485
491
  if (!currencyConverterRateModel) {
@@ -706,7 +712,7 @@ function appliedWholesaleLevels(sale) {
706
712
  }
707
713
 
708
714
  const result = [];
709
- let levelCounter = 1; // Para generar IDs secuenciales como en el ejemplo
715
+ let levelCounter = 1; // For generating sequential IDs as in the example
710
716
 
711
717
  sale.dwSaleProducts.forEach(product => {
712
718
  const productData = products[product.product_id];
@@ -995,30 +1001,6 @@ function getConsolidatedTaxes(sale) {
995
1001
  .sort((a, b) => b.amount - a.amount);
996
1002
  }
997
1003
 
998
- /**
999
- * Rounds or truncates currency values based on configuration
1000
- * @param {number} value - Value to process
1001
- * @param {boolean} overrideRounding - Optional override for rounding behavior
1002
- * @returns {number} Processed value
1003
- *
1004
- function roundCurrency(value, overrideRounding) {
1005
- if (typeof value !== 'number' || isNaN(value)) {
1006
- return 0;
1007
- }
1008
-
1009
- // Determine rounding behavior (parameter override > global setting > default false)
1010
- const shouldRound = overrideRounding !== undefined ? overrideRounding : useRounding;
1011
-
1012
- if (shouldRound) {
1013
- // Use rounding (comportamiento original)
1014
- return Math.round(value * roundingFactor) / roundingFactor;
1015
- } else {
1016
- // Use truncation (comportamiento por defecto - sin redondeo)
1017
- return Math.trunc(value * roundingFactor) / roundingFactor;
1018
- }
1019
- }
1020
- */
1021
-
1022
1004
  /**
1023
1005
  * Rounds or truncates currency values based on configuration
1024
1006
  * @param {number} value - Value to process
@@ -1073,4 +1055,4 @@ module.exports = {
1073
1055
  getApplicableProductTaxes, // Async
1074
1056
  exchange
1075
1057
  }
1076
- };
1058
+ };