docs: add comprehensive audit report and architectural recommendation
Checkpoint before implementation. Includes audit findings (FINDINGS.md), architectural recommendation (RECOMMENDATION.md), and existing code changes to Form, Order, Render, and form-action.js from recent development. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,9 @@ jQuery(function($){
|
||||
return valid;
|
||||
}
|
||||
|
||||
// Optional safety: guard for bad inputs to price_format
|
||||
function price_format(nStr) {
|
||||
nStr = parseFloat(nStr).toFixed(formipay.decimal_digits) + '';
|
||||
nStr = isNaN(parseFloat(nStr)) ? 0 : parseFloat(nStr); nStr = nStr.toFixed(formipay.decimal_digits) + '';
|
||||
var x = nStr.split('.');
|
||||
var x1 = x[0];
|
||||
var x2 = x.length > 1 ? formipay.decimal_symbol + x[1] : '';
|
||||
@@ -34,7 +35,7 @@ jQuery(function($){
|
||||
return formipay.currency + ' ' + x1 + x2;
|
||||
}
|
||||
|
||||
$('.product-price-row').find('td').html(price_format($('#product_price').val()));
|
||||
// Removed unconditional product price write: in static-products mode there is no #product_price and this forced a 0.
|
||||
$('.formipay-payment-option-group:first-child').find('input').trigger('click');
|
||||
|
||||
// PAGE BREAK
|
||||
@@ -220,7 +221,7 @@ jQuery(function($){
|
||||
form_inputs.append('nonce', formipay_form.nonce);
|
||||
form_inputs.append('data[qty]', $('.formipay-qty-input').val());
|
||||
form_inputs.append('form_id', form_id);
|
||||
form_inputs.append('currency', 'IDR');
|
||||
form_inputs.append('currency', formipay.currency_code || 'IDR');
|
||||
|
||||
var $valid = true; // Initialize as true
|
||||
|
||||
@@ -374,27 +375,54 @@ jQuery(function($){
|
||||
$(document).on('formipayCalculateAjaxSuccess', function(event, res, form, action) {
|
||||
|
||||
if(action == 'calculate') {
|
||||
form.find('.formipay-item-row:not(.formipay-product-row):not(.formipay-total-row):not(.formipay-grand-total-row)').remove();
|
||||
var product_price = res.items[0].subtotal;
|
||||
var grand_total = res.total;
|
||||
form.find('td.product_price').html(price_format(product_price));
|
||||
form.find('td.grand_total').html(price_format(grand_total));
|
||||
var button_text = form.find('.formipay-submit-button').data('button-text');
|
||||
form.find('.formipay-submit-button').html(button_text + ' - ' + price_format(grand_total));
|
||||
$.each(res.items, function(index, item){
|
||||
if(index > 0){
|
||||
var qty = '';
|
||||
if('qty' in item && item.qty > 1){
|
||||
qty = ' x '+item.qty;
|
||||
}
|
||||
$('table#formipay-review-order').find('.formipay-total-row').before(`
|
||||
<tr class="formipay-item-row `+item.context+`">
|
||||
<th>`+item.item+qty+`</th>
|
||||
<td>`+price_format(item.subtotal)+`</td>
|
||||
</tr>
|
||||
`);
|
||||
|
||||
// If backend returns structured items, rebuild dynamic rows
|
||||
if(res && Array.isArray(res.items)){
|
||||
// Remove previously injected rows (keep total/grand-total rows)
|
||||
form.find('.formipay-item-row:not(.formipay-total-row):not(.formipay-grand-total-row)').remove();
|
||||
|
||||
// If server provides totals
|
||||
if(typeof res.total !== 'undefined'){
|
||||
form.find('td.grand_total').html(price_format(res.total));
|
||||
}
|
||||
});
|
||||
|
||||
// If server provides per-line subtotals
|
||||
if(res.items.length){
|
||||
// If server distinguishes a primary product subtotal, reflect it
|
||||
// but do not rely on index 0 always being product
|
||||
res.items.forEach(function(item, index){
|
||||
var qty = '';
|
||||
if('qty' in item && item.qty > 1){ qty = ' x ' + item.qty; }
|
||||
|
||||
// If context is 'product' and there is a dedicated product row, update it
|
||||
if(item.context === 'product' && form.find('tr.formipay-product-row').length === 1 && index === 0){
|
||||
form.find('td.product_price').html(price_format(item.subtotal));
|
||||
return; // skip duplicate append below
|
||||
}
|
||||
|
||||
// Append any extra dynamic items before the total row
|
||||
form.find('table#formipay-review-order .formipay-total-row').before(
|
||||
'<tr class="formipay-item-row '+(item.context||'')+'">\n' +
|
||||
' <th>'+ item.item + qty +'</th>\n' +
|
||||
' <td>'+ price_format(item.subtotal) +'</td>\n' +
|
||||
'</tr>'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Update button from new grand total
|
||||
var grand_html = form.find('td.grand_total').text();
|
||||
form.find('.formipay-submit-button').html(button_text + ' - ' + grand_html);
|
||||
} else {
|
||||
// Backend didn’t send calculable payload; keep server-rendered table intact
|
||||
var grand_html = form.find('td.grand_total').text();
|
||||
if(grand_html){
|
||||
form.find('.formipay-submit-button').html(button_text + ' - ' + grand_html);
|
||||
} else {
|
||||
// Fallback: no grand total cell; do nothing
|
||||
}
|
||||
}
|
||||
}else if(action == 'checkout'){
|
||||
var form_id = form.data('form-id');
|
||||
if(res.success) {
|
||||
|
||||
Reference in New Issue
Block a user