Files
WooNooW/includes/Compat/CustomerSettingsProvider.php
Dwindi Ramadhana 100f9cce55 feat: implement multiple saved addresses with modal selector in checkout
- Add AddressController with full CRUD API for saved addresses
- Implement address management UI in My Account > Addresses
- Add modal-based address selector in checkout (Tokopedia-style)
- Hide checkout forms when saved address is selected
- Add search functionality in address modal
- Auto-select default addresses on page load
- Fix variable products to show 'Select Options' instead of 'Add to Cart'
- Add admin toggle for multiple addresses feature
- Clean up debug logs and fix TypeScript errors
2025-12-26 01:16:11 +07:00

201 lines
5.5 KiB
PHP

<?php
/**
* Customer Settings Provider
*
* Provides customer-related settings including VIP qualification criteria.
*
* @package WooNooW
*/
namespace WooNooW\Compat;
class CustomerSettingsProvider {
/**
* Get customer settings
*
* @return array
*/
public static function get_settings() {
return [
// General
'auto_register_members' => get_option('woonoow_auto_register_members', 'no') === 'yes',
'multiple_addresses_enabled' => get_option('woonoow_multiple_addresses_enabled', 'yes') === 'yes',
// VIP Customer Qualification
'vip_min_spent' => floatval(get_option('woonoow_vip_min_spent', 1000)),
'vip_min_orders' => intval(get_option('woonoow_vip_min_orders', 10)),
'vip_timeframe' => get_option('woonoow_vip_timeframe', 'all'), // all, 30, 90, 365
'vip_require_both' => get_option('woonoow_vip_require_both', 'yes') === 'yes',
'vip_exclude_refunded' => get_option('woonoow_vip_exclude_refunded', 'yes') === 'yes',
];
}
/**
* Update customer settings
*
* @param array $settings
* @return bool
*/
public static function update_settings($settings) {
$updated = true;
// General settings
if (isset($settings['auto_register_members'])) {
$updated = $updated && update_option('woonoow_auto_register_members', $settings['auto_register_members'] ? 'yes' : 'no');
}
if (isset($settings['multiple_addresses_enabled'])) {
$updated = $updated && update_option('woonoow_multiple_addresses_enabled', $settings['multiple_addresses_enabled'] ? 'yes' : 'no');
}
// VIP settings
if (isset($settings['vip_min_spent'])) {
$updated = $updated && update_option('woonoow_vip_min_spent', floatval($settings['vip_min_spent']));
}
if (isset($settings['vip_min_orders'])) {
$updated = $updated && update_option('woonoow_vip_min_orders', intval($settings['vip_min_orders']));
}
if (isset($settings['vip_timeframe'])) {
$timeframe = in_array($settings['vip_timeframe'], ['all', '30', '90', '365'])
? $settings['vip_timeframe']
: 'all';
$updated = $updated && update_option('woonoow_vip_timeframe', $timeframe);
}
if (isset($settings['vip_require_both'])) {
$updated = $updated && update_option('woonoow_vip_require_both', $settings['vip_require_both'] ? 'yes' : 'no');
}
if (isset($settings['vip_exclude_refunded'])) {
$updated = $updated && update_option('woonoow_vip_exclude_refunded', $settings['vip_exclude_refunded'] ? 'yes' : 'no');
}
return $updated;
}
/**
* Check if a customer is VIP based on current settings
*
* @param int $customer_id
* @return bool
*/
public static function is_vip_customer($customer_id) {
if (!$customer_id || $customer_id <= 0) {
return false;
}
$settings = self::get_settings();
// Build query args
$query_args = [
'customer_id' => $customer_id,
'status' => ['wc-completed', 'wc-processing'],
'limit' => -1, // Get all orders
];
// Apply timeframe filter
if ($settings['vip_timeframe'] !== 'all') {
$days = intval($settings['vip_timeframe']);
$query_args['date_created'] = '>' . date('Y-m-d', strtotime("-{$days} days"));
}
// Exclude refunded orders if setting is enabled
if ($settings['vip_exclude_refunded']) {
$query_args['status'] = array_diff($query_args['status'], ['wc-refunded']);
}
// Get orders
$orders = wc_get_orders($query_args);
// Calculate totals
$total_spent = 0;
$order_count = count($orders);
foreach ($orders as $order) {
$total_spent += floatval($order->get_total());
}
// Check qualification
$meets_spent = $total_spent >= $settings['vip_min_spent'];
$meets_orders = $order_count >= $settings['vip_min_orders'];
if ($settings['vip_require_both']) {
// Must meet both criteria
return $meets_spent && $meets_orders;
} else {
// Must meet at least one criterion
return $meets_spent || $meets_orders;
}
}
/**
* Get VIP customer stats for a customer
*
* @param int $customer_id
* @return array
*/
public static function get_vip_stats($customer_id) {
if (!$customer_id || $customer_id <= 0) {
return [
'is_vip' => false,
'total_spent' => 0,
'order_count' => 0,
'meets_spent' => false,
'meets_orders' => false,
];
}
$settings = self::get_settings();
// Build query args
$query_args = [
'customer_id' => $customer_id,
'status' => ['wc-completed', 'wc-processing'],
'limit' => -1,
];
// Apply timeframe filter
if ($settings['vip_timeframe'] !== 'all') {
$days = intval($settings['vip_timeframe']);
$query_args['date_created'] = '>' . date('Y-m-d', strtotime("-{$days} days"));
}
// Exclude refunded if enabled
if ($settings['vip_exclude_refunded']) {
$query_args['status'] = array_diff($query_args['status'], ['wc-refunded']);
}
// Get orders
$orders = wc_get_orders($query_args);
// Calculate totals
$total_spent = 0;
$order_count = count($orders);
foreach ($orders as $order) {
$total_spent += floatval($order->get_total());
}
// Check criteria
$meets_spent = $total_spent >= $settings['vip_min_spent'];
$meets_orders = $order_count >= $settings['vip_min_orders'];
$is_vip = $settings['vip_require_both']
? ($meets_spent && $meets_orders)
: ($meets_spent || $meets_orders);
return [
'is_vip' => $is_vip,
'total_spent' => $total_spent,
'order_count' => $order_count,
'meets_spent' => $meets_spent,
'meets_orders' => $meets_orders,
'required_spent' => $settings['vip_min_spent'],
'required_orders' => $settings['vip_min_orders'],
];
}
}