PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.1.13
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.1.13
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
easy-invoice / assets / js / payment-manager.js

payment-manager.js in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.1.13, at assets/js/payment-manager.js

273 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Payment Manager for Easy Invoice
3 * Handles payment calculations, discounts, and tax calculations
4 */
5 (function($) {
6 'use strict';
7
8 // Payment Manager object
9 window.EasyInvoicePayment = {
10 // Default settings
11 settings: {
12 discountType: 'percentage', // percentage or fixed
13 discountValue: 0,
14 taxRate: 0,
15 calculationMethod: 'before_tax', // before_tax or after_tax
16 currency: 'USD',
17 currencySymbol: '$'
18 },
19
20 // Initialize the payment manager
21 init: function() {
22
23
24 // Load settings from form fields first (preserves PHP-set values)
25 this.loadSettingsFromForm();
26
27 // Then override with localized data if available
28 if (typeof easyInvoicePayment !== 'undefined') {
29 this.settings.discountType = easyInvoicePayment.discountType || this.settings.discountType;
30 this.settings.discountValue = parseFloat(easyInvoicePayment.discountValue) || this.settings.discountValue;
31 this.settings.taxRate = parseFloat(easyInvoicePayment.taxRate) || this.settings.taxRate;
32 this.settings.calculationMethod = easyInvoicePayment.calculationMethod || this.settings.calculationMethod;
33 this.settings.currency = easyInvoicePayment.currency || this.settings.currency;
34 this.settings.currencySymbol = easyInvoicePayment.currencySymbol || this.settings.currencySymbol;
35 }
36
37 // Set up event handlers
38 this.setupEventHandlers();
39
40 // Update totals (but don't overwrite field values)
41 this.updateTotals();
42 },
43
44 // Load settings from form fields
45 loadSettingsFromForm: function() {
46 // Read values from form fields if they exist
47 var discountType = $('#discount_type').val();
48 if (discountType) {
49 this.settings.discountType = discountType;
50 }
51
52 var discountValue = parseFloat($('#discount_value').val());
53 if (!isNaN(discountValue)) {
54 this.settings.discountValue = discountValue;
55 }
56
57 var taxRate = parseFloat($('#tax_rate').val());
58 if (!isNaN(taxRate)) {
59 this.settings.taxRate = taxRate;
60 }
61
62 var calculationMethod = $('input[name="calculation_method"]:checked').val();
63 if (calculationMethod) {
64 this.settings.calculationMethod = calculationMethod;
65 }
66
67 var currency = $('#currency').val();
68 if (currency) {
69 this.settings.currency = currency;
70 }
71 },
72
73 // Set up event handlers for payment-related elements
74 setupEventHandlers: function() {
75 var self = this;
76
77 // Discount type change
78 $('#discount_type').on('change', function() {
79 self.settings.discountType = $(this).val();
80 self.updateTotals();
81 });
82
83 // Discount value change
84 $('#discount_value').on('input', function() {
85 self.settings.discountValue = parseFloat($(this).val()) || 0;
86 self.updateTotals();
87 });
88
89 // Tax rate change
90 $('#tax_rate').on('input', function() {
91 self.settings.taxRate = parseFloat($(this).val()) || 0;
92 self.updateTotals();
93 });
94
95 // Calculation method change
96 $('input[name="calculation_method"]').on('change', function() {
97 self.settings.calculationMethod = $(this).val();
98 self.updateTotals();
99 });
100
101 // Currency change
102 $('#currency_code').on('change', function() {
103 self.settings.currency = $(this).val();
104
105 // Get the currency symbol for the selected currency
106 switch($(this).val()) {
107 case 'USD':
108 self.settings.currencySymbol = '$';
109 break;
110 case 'EUR':
111 self.settings.currencySymbol = '';
112 break;
113 case 'GBP':
114 self.settings.currencySymbol = '£';
115 break;
116 default:
117 self.settings.currencySymbol = '$';
118 }
119
120 self.updateTotals();
121 });
122 },
123
124 // Update UI with current settings
125 updateUI: function() {
126 // Only set form field values if they are empty or if we have explicit settings
127 // This preserves values set by PHP/HTML
128 if (!$('#discount_type').val()) {
129 $('#discount_type').val(this.settings.discountType);
130 }
131 if (!$('#discount_value').val()) {
132 $('#discount_value').val(this.settings.discountValue);
133 }
134 if (!$('#tax_rate').val()) {
135 $('#tax_rate').val(this.settings.taxRate);
136 }
137 if (!$('input[name="calculation_method"]:checked').val()) {
138 $('input[name="calculation_method"][value="' + this.settings.calculationMethod + '"]').prop('checked', true);
139 }
140 if (!$('#currency_code').val()) {
141 $('#currency_code').val(this.settings.currency);
142 }
143
144 // Update totals
145 this.updateTotals();
146 },
147
148 // Update totals based on invoice items and settings
149 updateTotals: function() {
150 // Calculate subtotal from invoice items
151 var subtotal = 0;
152 var taxableSubtotal = 0;
153
154 // Get items from invoice builder if available
155 if (window.EasyInvoiceBuilder && typeof window.EasyInvoiceBuilder.getItems === 'function') {
156 var items = window.EasyInvoiceBuilder.getItems();
157
158 items.forEach(function(item) {
159 var baseTotal = item.quantity * item.price;
160 var adjustPercentage = parseFloat(item.adjust_percentage) || 0;
161 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
162 subtotal += itemTotal;
163
164 if (item.taxable) {
165 taxableSubtotal += itemTotal;
166 }
167 });
168 } else {
169 // Fallback: Calculate directly from DOM using dynamic field helpers
170 $('.invoice-item').each(function(index) {
171 var $item = $(this);
172
173 // Use dynamic field helpers if available
174 if (window.EasyInvoiceFieldHelpers) {
175 var quantity = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('quantity', $item)) || 0;
176 var price = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('price', $item)) || 0;
177 var adjustPercentage = parseFloat(window.EasyInvoiceFieldHelpers.getFieldValue('adjust_percentage', $item)) || 0;
178 var baseTotal = quantity * price;
179 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
180 var isTaxable = window.EasyInvoiceFieldHelpers.getFieldValue('taxable', $item) === '1';
181
182 subtotal += itemTotal;
183
184 if (isTaxable) {
185 taxableSubtotal += itemTotal;
186 }
187 } else {
188 // Fallback to hardcoded field names
189 var quantity = parseFloat($(this).find('input[name*="[quantity]"]').val()) || 0;
190 var price = parseFloat($(this).find('input[name*="[price]"]').val()) || 0;
191 var adjustPercentage = parseFloat($(this).find('input[name*="[adjust_percentage]"]').val()) || 0;
192 var baseTotal = quantity * price;
193 var itemTotal = baseTotal * (1 + adjustPercentage / 100);
194 var isTaxable = $(this).find('input[name*="[taxable]"]').is(':checked');
195
196 subtotal += itemTotal;
197
198 if (isTaxable) {
199 taxableSubtotal += itemTotal;
200 }
201 }
202 });
203 }
204
205 // Calculate discount amount
206 var discountAmount = 0;
207 if (this.settings.discountType === 'percentage') {
208 discountAmount = subtotal * (this.settings.discountValue / 100);
209 } else { // fixed amount
210 discountAmount = Math.min(this.settings.discountValue, subtotal); // Don't discount more than subtotal
211 }
212
213 // Calculate after discount amount
214 var afterDiscountAmount = subtotal - discountAmount;
215
216 // Calculate tax amount
217 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;
230 }
231 }
232
233 // Calculate total
234 var total = afterDiscountAmount + taxAmount;
235
236 // Update UI
237 $('#subtotal_value').text(this.formatCurrency(subtotal));
238 $('#discount_amount_value').text(this.formatCurrency(discountAmount));
239 $('#after_discount_value').text(this.formatCurrency(afterDiscountAmount));
240 $('#tax_amount_value').text(this.formatCurrency(taxAmount));
241 $('#total_value').text(this.formatCurrency(total));
242
243 // Update hidden fields for form submission
244 $('#subtotal_field').val(subtotal);
245 $('#discount_amount_field').val(discountAmount);
246 $('#tax_amount_field').val(taxAmount);
247 $('#total_field').val(total);
248 },
249
250 // Format currency value
251 formatCurrency: function(value) {
252 return this.settings.currencySymbol + parseFloat(value).toFixed(2);
253 },
254
255 // Get payment settings for saving
256 getPaymentSettings: function() {
257 return {
258 discountType: this.settings.discountType,
259 discountValue: this.settings.discountValue,
260 taxRate: this.settings.taxRate,
261 calculationMethod: this.settings.calculationMethod,
262 currency: this.settings.currency,
263 currencySymbol: this.settings.currencySymbol
264 };
265 }
266 };
267
268 // Initialize payment manager when document is ready
269 $(document).ready(function() {
270 EasyInvoicePayment.init();
271 });
272
273 })(jQuery);