PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.0
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.0
2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.2 All 57 releases
← All changes | assets/js/payment-manager.js +60 -23 2.1.142.4.0 View file →
@@ -8,12 +8,13 @@
8 8 // Payment Manager object
9 9 window.EasyInvoicePayment = {
10 10 // Default settings
11 11 settings: {
12 - discountType: 'percentage', // percentage or fixed
12 + discountType: 'none', // none, percentage or fixed
13 13 discountValue: 0,
14 14 taxRate: 0,
15 15 calculationMethod: 'before_tax', // before_tax or after_tax
16 + pricesIncludeTax: 'no', // yes or no
16 17 currency: 'USD',
17 18 currencySymbol: '$'
18 19 },
19 20
@@ -58,12 +59,17 @@
58 59 if (!isNaN(taxRate)) {
59 60 this.settings.taxRate = taxRate;
60 61 }
61 62
62 - var calculationMethod = $('input[name="calculation_method"]:checked').val();
63 + var calculationMethod = $('select[name="discount_calculation_method"]').val();
63 64 if (calculationMethod) {
64 65 this.settings.calculationMethod = calculationMethod;
65 66 }
67 +
68 + var pricesIncludeTax = $('select[name="prices_include_tax"]').val();
69 + if (pricesIncludeTax) {
70 + this.settings.pricesIncludeTax = pricesIncludeTax;
71 + }
66 72
67 73 var currency = $('#currency').val();
68 74 if (currency) {
69 75 this.settings.currency = currency;
@@ -92,12 +98,18 @@
92 98 self.updateTotals();
93 99 });
94 100
95 101 // Calculation method change
96 - $('input[name="calculation_method"]').on('change', function() {
102 + $('select[name="discount_calculation_method"]').on('change', function() {
97 103 self.settings.calculationMethod = $(this).val();
98 104 self.updateTotals();
99 105 });
106 +
107 + // Prices include tax change
108 + $('select[name="prices_include_tax"]').on('change', function() {
109 + self.settings.pricesIncludeTax = $(this).val();
110 + self.updateTotals();
111 + });
100 112
101 113 // Currency change
102 114 $('#currency_code').on('change', function() {
103 115 self.settings.currency = $(this).val();
@@ -156,9 +168,13 @@
156 168 var items = window.EasyInvoiceBuilder.getItems();
157 169
158 170 items.forEach(function(item) {
159 171 var baseTotal = item.quantity * item.price;
160 - var adjustPercentage = parseFloat(item.adjust_percentage) || 0;
172 + var adjustPercentage = 0;
173 + // Only apply adjust percentage if the adjust field is enabled
174 + if (window.easyInvoice && window.easyInvoice.showAdjustField) {
175 + adjustPercentage = parseFloat(item.adjust_percentage) || 0;
176 + }
161 177 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
162 178 subtotal += itemTotal;
163 179
164 180 if (item.taxable) {
@@ -166,9 +182,9 @@
166 182 }
167 183 });
168 184 } else {
169 185 // Fallback: Calculate directly from DOM using dynamic field helpers
170 - $('.invoice-item').each(function(index) {
186 + $('.invoice-item, .quote-item').each(function(index) {
171 187 var $item = $(this);
172 188
173 189 // Use dynamic field helpers if available
174 190 if (window.EasyInvoiceFieldHelpers) {
@@ -173,9 +189,13 @@
173 189 // Use dynamic field helpers if available
174 190 if (window.EasyInvoiceFieldHelpers) {
175 191 var quantity = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('quantity', $item)) || 0;
176 192 var price = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('price', $item)) || 0;
177 - var adjustPercentage = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('adjust_percentage', $item)) || 0;
193 + var adjustPercentage = 0;
194 + // Only apply adjust percentage if the adjust field is enabled
195 + if (window.easyInvoice && window.easyInvoice.showAdjustField) {
196 + adjustPercentage = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('adjust_percentage', $item)) || 0;
197 + }
178 198 var baseTotal = quantity * price;
179 199 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
180 200 var isTaxable = window.EasyInvoiceFieldHelpers.getFieldValue('taxable', $item) === '1';
181 201
@@ -187,9 +207,13 @@
187 207 } else {
188 208 // Fallback to hardcoded field names
189 209 var quantity = parseFloat($(this).find('input[name*="[quantity]"]').val()) || 0;
190 210 var price = parseFloat($(this).find('input[name*="[price]"]').val()) || 0;
191 - var adjustPercentage = parseFloat($(this).find('input[name*="[adjust_percentage]"]').val()) || 0;
211 + var adjustPercentage = 0;
212 + // Only apply adjust percentage if the adjust field is enabled
213 + if (window.easyInvoice && window.easyInvoice.showAdjustField) {
214 + adjustPercentage = parseFloat($(this).find('input[name*="[adjust_percentage]"]').val()) || 0;
215 + }
192 216 var baseTotal = quantity * price;
193 217 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
194 218 var isTaxable = $(this).find('input[name*="[taxable]"]').is(':checked');
195 219
@@ -203,9 +227,11 @@
203 227 }
204 228
205 229 // Calculate discount amount
206 230 var discountAmount = 0;
207 - if (this.settings.discountType === 'percentage') {
231 + if (this.settings.discountType === 'none') {
232 + discountAmount = 0;
233 + } else if (this.settings.discountType === 'percentage') {
208 234 discountAmount = subtotal * (this.settings.discountValue / 100);
209 235 } else { // fixed amount
210 236 discountAmount = Math.min(this.settings.discountValue, subtotal); // Don't discount more than subtotal
211 237 }
@@ -214,25 +240,36 @@
214 240 var afterDiscountAmount = subtotal - discountAmount;
215 241
216 242 // Calculate tax amount
217 243 var taxAmount = 0;
218 - if (this.settings.calculationMethod === 'before_tax') {
219 - // For before_tax: Apply discount first, then calculate tax on remaining taxable amount
220 - var discountRatio = discountAmount / subtotal;
221 - var taxableAmount = taxableSubtotal * (1 - discountRatio);
222 - taxAmount = taxableAmount * (this.settings.taxRate / 100);
223 - } else { // after_tax
224 - // For after_tax: Calculate tax first, then apply discount
225 - taxAmount = taxableSubtotal * (this.settings.taxRate / 100);
226 - // Recalculate percentage discount based on total including tax if needed
227 - if (this.settings.discountType === 'percentage') {
228 - var totalBeforeDiscount = subtotal + taxAmount;
229 - discountAmount = (totalBeforeDiscount * this.settings.discountValue) / 100;
244 + var total = 0;
245 + var pricesIncludeTax = this.settings.pricesIncludeTax === 'yes';
246 + var discountRatio = (subtotal > 0) ? (discountAmount / subtotal) : 0;
247 +
248 + if (pricesIncludeTax && this.settings.taxRate > 0) {
249 + // Tax is already included in prices: extract it from the taxable portion after discount
250 + var taxableAfterDiscount = taxableSubtotal * (1 - discountRatio);
251 + taxAmount = taxableAfterDiscount - (taxableAfterDiscount / (1 + this.settings.taxRate / 100));
252 + total = afterDiscountAmount;
253 + } else if (this.settings.taxRate > 0) {
254 + if (this.settings.calculationMethod === 'before_tax') {
255 + // Discount first, then tax on remaining taxable amount
256 + var taxableAfterDiscount = taxableSubtotal * (1 - discountRatio);
257 + taxAmount = taxableAfterDiscount * (this.settings.taxRate / 100);
258 + } else { // after_tax
259 + // Tax first on full taxable subtotal, then discount
260 + taxAmount = taxableSubtotal * (this.settings.taxRate / 100);
261 + // Recalculate percentage discount based on total including tax
262 + if (this.settings.discountType === 'percentage') {
263 + var totalBeforeDiscount = subtotal + taxAmount;
264 + discountAmount = (totalBeforeDiscount * this.settings.discountValue) / 100;
265 + afterDiscountAmount = subtotal - discountAmount;
266 + }
230 267 }
268 + total = afterDiscountAmount + taxAmount;
269 + } else {
270 + total = afterDiscountAmount;
231 271 }
232 -
233 - // Calculate total
234 - var total = afterDiscountAmount + taxAmount;
235 272
236 273 // Update UI
237 274 $('#subtotal_value').text(this.formatCurrency(subtotal));
238 275 $('#discount_amount_value').text(this.formatCurrency(discountAmount));