diff --git a/.gitignore b/.gitignore
index 496ee2ca6..c92743d55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,12 @@
-.DS_Store
\ No newline at end of file
+.DS_Store
+node_modules
+coverage
+.env
+*.log
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
\ No newline at end of file
diff --git a/includes/Coupon.php b/includes/Coupon.php
index d05938e8b..0cc410d27 100644
--- a/includes/Coupon.php
+++ b/includes/Coupon.php
@@ -612,6 +612,9 @@ class Coupon {
$args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
}
+ // Handle status filtering (active/inactive)
+ $status_filter = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : 'all';
+
$get_coupons = get_posts($args);
$global_currencies = get_global_currency_array();
@@ -619,13 +622,19 @@ class Coupon {
if(!empty($get_coupons)){
foreach($get_coupons as $key => $coupon){
- $active = true;
+ $is_active = formipay_get_post_meta($coupon->ID, 'active') == 'on';
+
+ // Apply status filter
+ if ($status_filter !== 'all') {
+ if ($status_filter === 'active' && !$is_active) continue;
+ if ($status_filter === 'inactive' && $is_active) continue;
+ }
$date_limit = formipay_get_post_meta($coupon->ID, 'date_limit');
$type = formipay_get_post_meta($coupon->ID, 'type');
$amount_meta_key = "amount_$type";
-
+
if($type == 'fixed'){
$amount_value = [];
foreach($global_currencies as $currency){
@@ -646,23 +655,21 @@ class Coupon {
$amount_value = floatval(formipay_get_post_meta($coupon->ID, $amount_meta_key));
}
-
- if($active){
- $coupons[] = [
- 'ID' => $coupon->ID,
- 'code' => get_the_title($coupon->ID),
- 'value' => $amount_value,
- 'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')),
- 'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'),
- 'usages' => [
- 'used' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
- 'limit' => (intval(formipay_get_post_meta($coupon->ID, 'use_limit')) > 0) ? formipay_get_post_meta($coupon->ID, 'use_limit') : '∞'
- ],
- 'date_limit' => false !== $date_limit ? formipay_date('Y-m-d', intval(formipay_get_post_meta($coupon->ID, 'date_limit')) / 1000) : 'none',
- 'status' => (formipay_get_post_meta($coupon->ID, 'active') == 'on') ? 'Active' : 'Inactive'
- ];
- }
+
+ $coupons[] = [
+ 'ID' => $coupon->ID,
+ 'code' => get_the_title($coupon->ID),
+ 'amount' => $amount_value,
+ 'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')),
+ 'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'),
+ 'usage_count' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
+ 'usages' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
+ 'date_limit' => false !== $date_limit ? formipay_date('Y-m-d', intval(formipay_get_post_meta($coupon->ID, 'date_limit')) / 1000) : 'none',
+ 'active' => $is_active ? 'on' : 'off',
+ 'post_status' => $is_active ? 'active' : 'inactive',
+ 'status' => $is_active ? 'active' : 'inactive'
+ ];
}
}
diff --git a/includes/Order.php b/includes/Order.php
index a3cfb2e52..2976aeddc 100644
--- a/includes/Order.php
+++ b/includes/Order.php
@@ -646,7 +646,7 @@ class Order {
// React admin
printf(
- '
',
+ '',
esc_attr($page)
);
@@ -933,21 +933,31 @@ class Order {
// Process filtered orders
if (!empty($get_filtered_orders)) {
- foreach ($get_filtered_orders as $key => $order) {
+ foreach ($get_filtered_orders as $key => $order) {
$currency = explode(':::', formipay_get_post_meta($order->form_id, 'product_currency'));
- $code = !empty($currency[0]) ? $currency[0] : '';
- // Prepare order data
+ $code = !empty($currency[0]) ? $currency[0] : '';
+
+ // Keep status as-is (with hyphens) to match STATUS_COLORS keys
+ $status = $order->status;
+
+ // Transform form_data to the structure expected by OrderListItem
+ $raw_form_data = maybe_unserialize($order->form_data);
+ $transformed_form_data = [];
+ if (is_array($raw_form_data)) {
+ foreach ($raw_form_data as $field_key => $field_value) {
+ $transformed_form_data[] = [
+ 'name' => $field_key,
+ 'value' => is_array($field_value) && isset($field_value['value']) ? $field_value['value'] : $field_value,
+ ];
+ }
+ }
+
$orders[] = [
- 'ID' => $order->id,
- 'form' => get_the_title($order->form_id),
- 'date' => $order->created_date,
- 'payment_gateway' => ucwords(str_replace('_', ' ', $order->payment_gateway)),
- 'status' => ucwords(str_replace('-', ' ', $order->status)),
- 'total' => [
- 'flag' => formipay_get_flag_by_currency($code),
- 'name' => $code,
- 'value' => formipay_price_format($order->total, $order->form_id),
- ]
+ 'id' => $order->id,
+ 'created_date' => $order->created_date,
+ 'form_data' => $transformed_form_data,
+ 'total_formatted' => formipay_price_format($order->total, $order->form_id),
+ 'status' => $status,
];
}
}
diff --git a/includes/Product.php b/includes/Product.php
index d232e9756..c10b20ba5 100644
--- a/includes/Product.php
+++ b/includes/Product.php
@@ -161,7 +161,7 @@ class Product {
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
],
],
- 'nonce' => wp_create_nonce('formipay-admin-product-page')
+ 'nonce' => wp_create_nonce('formipay-admin')
] );
}
@@ -590,7 +590,7 @@ class Product {
public function formipay_tabledata_products() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
@@ -668,26 +668,66 @@ class Product {
$total_products = $query->found_posts;
// Process results
+ $global_currencies = get_global_currency_array();
$products = [];
foreach ($product_ids as $product_id) {
$product = get_post($product_id);
-
+
$currency = explode(':::', get_post_meta($product_id, 'product_currency', true));
$categories = wp_get_post_terms($product_id, 'formipay-product-category', ['fields' => 'names']);
-
+
+ // Build multi-currency prices array
+ $prices = [];
+ foreach ($global_currencies as $curr) {
+ $curr_raw = $curr['currency'];
+ $curr_parts = explode(':::', $curr_raw);
+ $curr_code = $curr_parts[0] ?? '';
+ $symbol = formipay_get_currency_data_by_value($curr_raw, 'symbol');
+
+ $regular_price = get_post_meta($product_id, 'setting_product_price_regular_' . $symbol, true);
+ $sale_price = get_post_meta($product_id, 'setting_product_price_sale_' . $symbol, true);
+
+ // Only add if we have at least a regular price
+ if (!empty($regular_price)) {
+ // Format price using this currency's own formatting rules
+ $decimal_digits = intval($curr['decimal_digits'] ?? 2);
+ $decimal_symbol = $curr['decimal_symbol'] ?? '.';
+ $thousand_separator = $curr['thousand_separator'] ?? ',';
+
+ $formatted_regular = $symbol . ' ' . number_format(floatval($regular_price), $decimal_digits, $decimal_symbol, $thousand_separator);
+ $formatted_sale = !empty($sale_price) ? $symbol . ' ' . number_format(floatval($sale_price), $decimal_digits, $decimal_symbol, $thousand_separator) : '';
+
+ $prices[] = [
+ 'currency' => $curr_code,
+ 'symbol' => $symbol,
+ 'flag' => formipay_get_flag_by_currency($curr_raw),
+ 'regular_price' => $formatted_regular,
+ 'sale_price' => $formatted_sale,
+ 'has_sale' => !empty($sale_price),
+ ];
+ }
+ }
+
+ // Fallback to single price if no multi-currency prices set
+ if (empty($prices)) {
+ $fallback_price = get_post_meta($product_id, 'price', true);
+ $prices[] = [
+ 'currency' => $currency[0] ?? 'USD',
+ 'symbol' => $currency[2] ?? '$',
+ 'flag' => formipay_get_flag_by_currency($currency[0] ?? ''),
+ 'regular_price' => formipay_price_format($fallback_price, $product_id),
+ 'sale_price' => '',
+ 'has_sale' => false,
+ ];
+ }
+
$products[] = [
'ID' => $product_id,
'title' => $product->post_title,
'category' => implode(', ', $categories),
'type' => formipay_get_post_meta($product_id, 'product_type'),
'stock' => formipay_get_post_meta($product_id, 'stock') ?: '∞',
- 'price' => [
- 'flag' => formipay_get_flag_by_currency($currency[0] ?? ''),
- 'name' => formipay_price_format(
- get_post_meta($product_id, 'price', true),
- $product_id
- )
- ],
+ 'prices' => $prices,
'status' => $product->post_status,
];
}
@@ -710,7 +750,7 @@ class Product {
public function formipay_create_product_post() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
@@ -745,7 +785,7 @@ class Product {
public function formipay_product_get_currencies() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
@@ -773,7 +813,7 @@ class Product {
public function formipay_delete_product() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
@@ -801,7 +841,7 @@ class Product {
public function formipay_bulk_delete_product() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
@@ -847,7 +887,7 @@ class Product {
public function formipay_duplicate_product() {
- check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
+ check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
diff --git a/src/admin/api/client.js b/src/admin/api/client.js
index 82e8dba3e..edb36bd91 100644
--- a/src/admin/api/client.js
+++ b/src/admin/api/client.js
@@ -103,8 +103,8 @@ export const customersApi = {
* Products API
*/
export const productsApi = {
- list: (params = {}) => ajaxRequest('formipay_tabledata_products', params),
- get: (productId) => ajaxRequest('formipay_get_product', { post_id: productId }),
+ list: (params = {}) => ajaxRequest('formipay-tabledata-products', params),
+ get: (productId) => ajaxRequest('formipay-get-product', { post_id: productId }),
getVariables: (productId) => ajaxRequest('get_product_variables', { post_id: productId }),
};
diff --git a/src/admin/components/orders/OrderList.js b/src/admin/components/orders/OrderList.js
index c35eff601..0bf0bd7f7 100644
--- a/src/admin/components/orders/OrderList.js
+++ b/src/admin/components/orders/OrderList.js
@@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n';
import { useState, useCallback, useEffect } from '@wordpress/element';
import { SearchControl, SelectControl, Button } from '@wordpress/components';
import { Icon } from '@wordpress/icons';
-import list from '@wordpress/icons/build/list';
+import * as Icons from '@wordpress/icons';
import { ordersApi } from '../../api/client';
import OrderListItem from './OrderListItem';
import './OrderList.css';
@@ -37,9 +37,14 @@ export default function OrderList({ onSelectOrder }) {
offset: pagination.offset,
})
.then(result => {
- if (result.data) {
- setOrders(result.data.results || []);
- setTotal(result.data.total || 0);
+ console.log('Orders API response:', result);
+ // Handle both response formats: with or without data wrapper
+ const data = result.data || result;
+ if (data) {
+ setOrders(data.results || []);
+ setTotal(data.total || 0);
+ } else {
+ console.error('Unexpected response structure:', result);
}
})
.catch(error => {
@@ -86,7 +91,7 @@ export default function OrderList({ onSelectOrder }) {
-
+
{ __('Orders', 'formipay') }
diff --git a/src/admin/components/orders/OrderListItem.js b/src/admin/components/orders/OrderListItem.js
index 835c3c456..55d6eb2e5 100644
--- a/src/admin/components/orders/OrderListItem.js
+++ b/src/admin/components/orders/OrderListItem.js
@@ -4,7 +4,7 @@
import { __ } from '@wordpress/i18n';
import { Icon } from '@wordpress/icons';
-import seen from '@wordpress/icons/build/visible';
+import * as Icons from '@wordpress/icons';
import './OrderListItem.css';
const STATUS_COLORS = {
@@ -79,7 +79,7 @@ export default function OrderListItem({ order, onSelect }) {
className="button button-small"
onClick={onSelect}
>
-
+
{ __('View', 'formipay') }