Spaces:
Sleeping
Sleeping
Commit
·
409f62b
1
Parent(s):
c280f45
add: proper roundoff
Browse files- .eslintrc.json +12 -0
- script.js +22 -8
- style.css +4 -1
- tests/test.js +47 -1
.eslintrc.json
CHANGED
@@ -21,6 +21,18 @@
|
|
21 |
"semi": [
|
22 |
"error",
|
23 |
"always"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
]
|
25 |
}
|
26 |
}
|
|
|
21 |
"semi": [
|
22 |
"error",
|
23 |
"always"
|
24 |
+
],
|
25 |
+
"no-unused-vars": [
|
26 |
+
"error",
|
27 |
+
{
|
28 |
+
"args": "all",
|
29 |
+
"argsIgnorePattern": "^_",
|
30 |
+
"caughtErrors": "all",
|
31 |
+
"caughtErrorsIgnorePattern": "^_",
|
32 |
+
"destructuredArrayIgnorePattern": "^_",
|
33 |
+
"varsIgnorePattern": "^_",
|
34 |
+
"ignoreRestSiblings": true
|
35 |
+
}
|
36 |
]
|
37 |
}
|
38 |
}
|
script.js
CHANGED
@@ -103,16 +103,13 @@ if (typeof document !== 'undefined') {
|
|
103 |
amount: parseFloat(row.querySelector('.item-amount').textContent) || 0
|
104 |
});
|
105 |
});
|
106 |
-
const subtotal
|
107 |
-
|
108 |
-
const total = subtotal + igstAmount + freightCharges;
|
109 |
// convert total to words (Rupees and Paise)
|
110 |
-
const rupeePart = Math.floor(
|
111 |
-
const paisePart = Math.round((
|
112 |
const rupeeWords = numberToWords(rupeePart);
|
113 |
const paiseWords = paisePart > 0 ? numberToWords(paisePart) : '';
|
114 |
-
const rOff = 0; // Or get from a form field if you add one
|
115 |
-
const finalTotal = total - rOff;
|
116 |
|
117 |
let html = `
|
118 |
<div class="quotation-print">
|
@@ -234,7 +231,24 @@ if (typeof document !== 'undefined') {
|
|
234 |
});
|
235 |
}
|
236 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
// Export for testing (Node.js)
|
238 |
if (typeof module !== 'undefined' && module.exports) {
|
239 |
-
module.exports = { numberToWords };
|
240 |
}
|
|
|
103 |
amount: parseFloat(row.querySelector('.item-amount').textContent) || 0
|
104 |
});
|
105 |
});
|
106 |
+
const { subtotal, igstAmount, _total, rOff, finalTotal } = calculateQuotation(items, igstRate, freightCharges);
|
107 |
+
|
|
|
108 |
// convert total to words (Rupees and Paise)
|
109 |
+
const rupeePart = Math.floor(finalTotal);
|
110 |
+
const paisePart = Math.round((finalTotal - rupeePart) * 100);
|
111 |
const rupeeWords = numberToWords(rupeePart);
|
112 |
const paiseWords = paisePart > 0 ? numberToWords(paisePart) : '';
|
|
|
|
|
113 |
|
114 |
let html = `
|
115 |
<div class="quotation-print">
|
|
|
231 |
});
|
232 |
}
|
233 |
|
234 |
+
function calculateQuotation(items, igstRate, freightCharges) {
|
235 |
+
const subtotal = items.reduce((sum, i) => sum + i.amount, 0);
|
236 |
+
const igstAmount = (subtotal * igstRate) / 100;
|
237 |
+
const total = subtotal + igstAmount + freightCharges;
|
238 |
+
const totalBeforeRoundOff = total;
|
239 |
+
const finalTotal = Math.round(totalBeforeRoundOff);
|
240 |
+
const rOff = totalBeforeRoundOff - finalTotal;
|
241 |
+
|
242 |
+
return {
|
243 |
+
subtotal,
|
244 |
+
igstAmount,
|
245 |
+
total,
|
246 |
+
rOff,
|
247 |
+
finalTotal
|
248 |
+
};
|
249 |
+
}
|
250 |
+
|
251 |
// Export for testing (Node.js)
|
252 |
if (typeof module !== 'undefined' && module.exports) {
|
253 |
+
module.exports = { numberToWords, calculateQuotation };
|
254 |
}
|
style.css
CHANGED
@@ -90,7 +90,10 @@ button {
|
|
90 |
}
|
91 |
|
92 |
.company-details {
|
93 |
-
|
|
|
|
|
|
|
94 |
}
|
95 |
|
96 |
.quotation-title h1 {
|
|
|
90 |
}
|
91 |
|
92 |
.company-details {
|
93 |
+
margin: 0;
|
94 |
+
font-size: 24px;
|
95 |
+
color: #036;
|
96 |
+
font-family: Arial, Helvetica, sans-serif;
|
97 |
}
|
98 |
|
99 |
.quotation-title h1 {
|
tests/test.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
const assert = require('assert');
|
2 |
-
const { numberToWords } = require('../script.js');
|
3 |
|
4 |
// Test cases for Indian number-to-words conversion (Crore/Lakh system)
|
5 |
const cases = [
|
@@ -31,3 +31,49 @@ cases.forEach(({ num, expected }) => {
|
|
31 |
});
|
32 |
|
33 |
console.log('✅ All numberToWords tests passed');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
const assert = require('assert');
|
2 |
+
const { numberToWords, calculateQuotation } = require('../script.js');
|
3 |
|
4 |
// Test cases for Indian number-to-words conversion (Crore/Lakh system)
|
5 |
const cases = [
|
|
|
31 |
});
|
32 |
|
33 |
console.log('✅ All numberToWords tests passed');
|
34 |
+
|
35 |
+
// --- Tests for calculateQuotation ---
|
36 |
+
|
37 |
+
const calculationCases = [
|
38 |
+
{
|
39 |
+
name: 'Basic case with one item',
|
40 |
+
items: [{ amount: 100 }],
|
41 |
+
igstRate: 18,
|
42 |
+
freightCharges: 50,
|
43 |
+
expected: { subtotal: 100, igstAmount: 18, total: 168, finalTotal: 168, rOff: 0 }
|
44 |
+
},
|
45 |
+
{
|
46 |
+
name: 'Multiple items',
|
47 |
+
items: [{ amount: 100 }, { amount: 250.50 }],
|
48 |
+
igstRate: 18,
|
49 |
+
freightCharges: 50,
|
50 |
+
expected: { subtotal: 350.50, igstAmount: 63.09, total: 463.59, finalTotal: 464, rOff: -0.41 }
|
51 |
+
},
|
52 |
+
{
|
53 |
+
name: 'No IGST or freight',
|
54 |
+
items: [{ amount: 500 }],
|
55 |
+
igstRate: 0,
|
56 |
+
freightCharges: 0,
|
57 |
+
expected: { subtotal: 500, igstAmount: 0, total: 500, finalTotal: 500, rOff: 0 }
|
58 |
+
},
|
59 |
+
{
|
60 |
+
name: 'Rounding down',
|
61 |
+
items: [{ amount: 99.20 }],
|
62 |
+
igstRate: 10, // 9.92
|
63 |
+
freightCharges: 0, // total = 109.12
|
64 |
+
expected: { subtotal: 99.20, igstAmount: 9.92, total: 109.12, finalTotal: 109, rOff: 0.12 }
|
65 |
+
}
|
66 |
+
];
|
67 |
+
|
68 |
+
calculationCases.forEach(({ name, items, igstRate, freightCharges, expected }) => {
|
69 |
+
const actual = calculateQuotation(items, igstRate, freightCharges);
|
70 |
+
// Need to compare floating point numbers with a tolerance
|
71 |
+
Object.keys(expected).forEach(key => {
|
72 |
+
assert(
|
73 |
+
Math.abs(actual[key] - expected[key]) < 0.001,
|
74 |
+
`[${name}] ${key} => ${actual[key]} (expected ${expected[key]})`
|
75 |
+
);
|
76 |
+
});
|
77 |
+
});
|
78 |
+
|
79 |
+
console.log('✅ All calculateQuotation tests passed');
|