feat: migrate shipping to form-level and integrate flags.json as single source of truth
Shipping Migration: - Move shipping configuration from product-level to form-level - Add form shipping tab in form settings (no_shipping, flat_rate, free_shipping) - Update FlatRate to register at form level instead of product level - Update checkout logic to read from form settings - Support percentage-based flat rate calculation - Simplify shipping method IDs (flat_rate, free_shipping) Currency Flags Integration: - Add formipay_get_all_currency_flags() to read from admin/assets/json/flags.json - Remove hardcoded CURRENCY_FLAGS emoji map from VariationField.js - Create CurrencyFlag component to render base64 flag images - Localize currency_flags to window.formipayProductDetails - Update shipping info display in admin order details Benefits: - Form-level shipping prevents multiplying shipping costs per product - Single source of truth for currency flags (flags.json) - Better support for future cart system - Consistent with e-commerce standards
This commit is contained in:
@@ -15,8 +15,9 @@ class FlatRate extends Shipping {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'formipay/product-config/tab:shipping/method', [$this, 'add_shipping_method'], 15 );
|
||||
add_filter( 'formipay/product-config/tab:shipping', [$this, 'add_shipping_settings'], 15 );
|
||||
// Register flat rate as a form-level shipping method
|
||||
add_filter( 'formipay/form-settings/tab:shipping/method', [$this, 'add_shipping_method'], 15 );
|
||||
add_filter( 'formipay/form-settings/tab:shipping', [$this, 'add_shipping_settings'], 15 );
|
||||
|
||||
// Add to order details
|
||||
add_filter( 'formipay/order/order-details', [$this, 'add_shipping_to_order_details'], 99, 3 );
|
||||
@@ -33,113 +34,133 @@ class FlatRate extends Shipping {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add flat rate settings to form shipping configuration
|
||||
* These fields are shown when "Flat Rate" is selected as the shipping method
|
||||
*/
|
||||
public function add_shipping_settings($fields) {
|
||||
|
||||
// Get global currencies configuration
|
||||
$global_currencies = get_global_currency_array();
|
||||
|
||||
// Basic flat rate fields (type and label)
|
||||
$flat_rate_fields = array(
|
||||
$this->shipping_method.'_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Flat Rate Setup', 'formipay' ),
|
||||
'description' => __( 'Configure flat rate shipping cost for this form', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
'key' => 'shipping_enabled',
|
||||
'value' => 'flat_rate'
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->shipping_method.'_type' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Type', 'formipay' ),
|
||||
'options' => array(
|
||||
'fixed' => __( 'Fixed', 'formipay' ),
|
||||
'percentage' => __( 'Percentage', 'formipay' )
|
||||
'fixed' => __( 'Fixed Amount', 'formipay' ),
|
||||
'percentage' => __( 'Percentage of Order Total', 'formipay' )
|
||||
),
|
||||
'value' => 'fixed',
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
'key' => 'shipping_enabled',
|
||||
'value' => 'flat_rate'
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
),
|
||||
$this->shipping_method.'_amount' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Amount', 'formipay' ),
|
||||
'value' => '10',
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
),
|
||||
$this->shipping_method.'_label' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Label', 'formipay' ),
|
||||
'description' => __( 'This will be shown in Order Review and Order Details', 'formipay' ),
|
||||
'value' => __( 'Shipping Fee', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
// Add per-currency amount fields
|
||||
foreach ($global_currencies as $currency) {
|
||||
// Get the currency code (first part of triple) - this is used for meta key suffix
|
||||
$currency_code = formipay_get_currency_data_by_value($currency['currency'], 'symbol');
|
||||
|
||||
$step = ($currency['decimal_digits'] ?? 2) > 0 ? pow(10, -($currency['decimal_digits'] ?? 2)) : 1;
|
||||
$is_last = ($currency === end($global_currencies));
|
||||
|
||||
$flat_rate_fields[$this->shipping_method.'_amount_'.$currency_code] = array(
|
||||
'type' => 'number',
|
||||
'label' => sprintf(__( 'Amount (%s)', 'formipay' ), $currency_code),
|
||||
'description' => $is_last ? __( 'Shipping cost for this form (not per-product)', 'formipay' ) : '',
|
||||
'step' => $step,
|
||||
'min' => 0,
|
||||
'placeholder' => $is_last ? __( 'Enter Amount...', 'formipay' ) : __( 'Auto', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'shipping_enabled',
|
||||
'value' => 'flat_rate'
|
||||
),
|
||||
'group' => $is_last ? 'ended' : null,
|
||||
);
|
||||
}
|
||||
|
||||
// Merge fields into the main fields array
|
||||
foreach($flat_rate_fields as $key => $value){
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add shipping cost to order details
|
||||
*
|
||||
* @param array $details Order details array
|
||||
* @param int $form_id Product/form ID
|
||||
* @param array $order_data Order data from submission
|
||||
* @return array Updated order details
|
||||
*/
|
||||
public function add_shipping_to_order_details( $details, $form_id, $order_data ) {
|
||||
|
||||
if( formipay_get_post_meta($form_id, 'product_type') == 'physical' && formipay_get_post_meta($form_id, 'shipping_method')){
|
||||
if ( formipay_get_post_meta($form_id, 'product_type') == 'physical' && formipay_get_post_meta($form_id, 'shipping_method') == 'flat_rate' ) {
|
||||
|
||||
$amount = floatval( formipay_price_format( formipay_get_post_meta( $form_id, 'flat_rate_amount' ) ) );
|
||||
$flat_rate_type = formipay_get_post_meta($form_id, 'flat_rate_type');
|
||||
$flat_rate_label = formipay_get_post_meta($form_id, 'flat_rate_label');
|
||||
|
||||
if( formipay_get_post_meta($form_id, 'flat_rate_type') == 'percentage' ) {
|
||||
$price = floatval( formipay_get_post_meta($form_id, 'product_price') );
|
||||
$calculate = $price * $amount / 100;
|
||||
// Get the selected currency from request (same way Order class does it)
|
||||
$currency = isset($_REQUEST['currency']) ? sanitize_text_field( wp_unslash($_REQUEST['currency']) ) : (string) formipay_default_currency('code');
|
||||
|
||||
// Get flat rate amount - check for currency-specific first, then fallback to base
|
||||
$flat_rate_amount = formipay_get_post_meta($form_id, 'flat_rate_amount_' . $currency);
|
||||
if (empty($flat_rate_amount)) {
|
||||
$flat_rate_amount = formipay_get_post_meta($form_id, 'flat_rate_amount');
|
||||
}
|
||||
|
||||
$amount = floatval( formipay_price_format($flat_rate_amount) );
|
||||
|
||||
// For percentage-based, calculate from actual product price paid
|
||||
if ( $flat_rate_type == 'percentage' ) {
|
||||
// Find the actual product price from order details (already currency-aware)
|
||||
$product_price = 0;
|
||||
foreach ($details as $item) {
|
||||
if (isset($item['context']) && $item['context'] == 'product') {
|
||||
// Use the first product's amount (already in selected currency)
|
||||
$product_price = floatval($item['amount']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no product found in details, fallback to lookup by currency
|
||||
if ($product_price == 0) {
|
||||
$regular_key = 'setting_product_price_regular_' . $currency;
|
||||
$sale_key = 'setting_product_price_sale_' . $currency;
|
||||
$regular_price = formipay_get_post_meta($form_id, $regular_key);
|
||||
$sale_price = formipay_get_post_meta($form_id, $sale_key);
|
||||
$product_price = ($sale_price !== '' && $sale_price !== null) ? floatval($sale_price) : floatval($regular_price);
|
||||
}
|
||||
|
||||
$calculate = $product_price * $amount / 100;
|
||||
$amount = floatval($calculate);
|
||||
}
|
||||
|
||||
$details[] = [
|
||||
'item' => formipay_get_post_meta($form_id, 'flat_rate_label'),
|
||||
'item' => $flat_rate_label,
|
||||
'amount' => $amount,
|
||||
'subtotal' => $amount
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
return $details;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user