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:
dwindown
2026-04-17 17:00:47 +07:00
parent 0446eb1064
commit 35569923a5
6 changed files with 1014 additions and 153 deletions

View File

@@ -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 didnt 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) {