This commit is contained in:
14 changed files with 987 additions and 0 deletions

124
inc/class-orders-sync.php Normal file
View File

@@ -0,0 +1,124 @@
<?php
if (!defined('ABSPATH')) exit;
class WZHF_Orders_Sync {
const SWEEPER_HOOK = 'wzhf_paid_sweeper_event';
public static function bootstrap(){
add_action('woocommerce_payment_complete',array(__CLASS__,'on_paid'),20);
add_action('woocommerce_checkout_order_processed',array(__CLASS__,'on_processed'),20,3);
add_action('woocommerce_new_order',array(__CLASS__,'on_new_order'),20,1);
add_action('woocommerce_order_status_changed',array(__CLASS__,'on_status_changed'),20,4);
add_action('woocommerce_order_status_processing', array(__CLASS__,'on_status_processing'), 20, 1);
add_action('woocommerce_order_status_completed', array(__CLASS__,'on_status_completed'), 20, 1);
add_action(self::SWEEPER_HOOK, array(__CLASS__,'run_sweeper'));
add_action('update_option_'.WZHF_OPT, array(__CLASS__,'maybe_reschedule_sweeper'), 10, 3);
self::maybe_reschedule_sweeper(null, wzhf_get_option(), WZHF_OPT);
}
public static function maybe_reschedule_sweeper($old, $new, $name){
$mode = isset($new['trigger_mode']) ? $new['trigger_mode'] : 'processed';
$enabled = ($mode === 'paid');
$ts = wp_next_scheduled(self::SWEEPER_HOOK);
if($enabled){
if($ts) wp_clear_scheduled_hook(self::SWEEPER_HOOK);
wp_schedule_event(time()+120, 'wzhf_5min', self::SWEEPER_HOOK);
} else {
if($ts) wp_clear_scheduled_hook(self::SWEEPER_HOOK);
}
}
private static function should_send_now($order){
$mode=wzhf_get_option('trigger_mode','processed');
if($mode==='processed') return true;
if($mode==='paid') return $order->is_paid();
return false;
}
public static function on_processed($order_id,$posted,$order){
if(!self::should_send_now($order)) return;
WZHF_Logger::log('trigger:on_processed', array('order_id'=>$order_id));
self::create_sales_order($order_id);
}
public static function on_paid($order_id){
if(wzhf_get_option('trigger_mode','processed')!=='paid') return;
WZHF_Logger::log('trigger:on_paid', array('order_id'=>$order_id));
self::create_sales_order($order_id);
}
public static function on_new_order($order_id){
$order = wc_get_order($order_id); if(!$order) return;
$mode = wzhf_get_option('trigger_mode','processed');
if($mode==='processed' || ($mode==='paid' && $order->is_paid())){
WZHF_Logger::log('trigger:on_new_order', array('order_id'=>$order_id, 'is_paid'=>$order->is_paid()));
self::create_sales_order($order_id);
}
}
public static function on_status_changed($order_id,$old_status,$new_status,$order){
if(wzhf_get_option('trigger_mode','processed')!=='paid') return;
if(in_array($new_status, array('processing','completed'))){
WZHF_Logger::log('trigger:on_status_changed', array('order_id'=>$order_id,'from'=>$old_status,'to'=>$new_status));
self::create_sales_order($order_id);
}
}
public static function on_status_processing($order_id){
if(wzhf_get_option('trigger_mode','processed')!=='paid') return;
WZHF_Logger::log('trigger:on_status_processing', array('order_id'=>$order_id));
self::create_sales_order($order_id);
}
public static function on_status_completed($order_id){
if(wzhf_get_option('trigger_mode','processed')!=='paid') return;
WZHF_Logger::log('trigger:on_status_completed', array('order_id'=>$order_id));
self::create_sales_order($order_id);
}
public static function run_sweeper(){
if(wzhf_get_option('trigger_mode','processed')!=='paid') return;
$z = new WZHF_Zoho(); if(!$z->is_connected()) return;
WZHF_Logger::log('sweeper:start');
$args = array(
'status' => array('processing','completed'),
'limit' => 25,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
);
$ids = wc_get_orders($args);
global $wpdb; $map=$wpdb->prefix.'wzhf_orders';
foreach((array)$ids as $order_id){
$already=$wpdb->get_var($wpdb->prepare("SELECT zoho_salesorder_id FROM $map WHERE wc_order_id=%d",$order_id));
if($already) continue;
WZHF_Logger::log('sweeper:create', array('order_id'=>$order_id));
self::create_sales_order($order_id);
}
WZHF_Logger::log('sweeper:end', array('count'=>count($ids)));
}
public static function create_sales_order($order_id){
$order=wc_get_order($order_id); if(!$order) return;
WZHF_Logger::log('SO create:start', array('order_id'=>$order_id));
global $wpdb; $map=$wpdb->prefix.'wzhf_orders';
$exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s",$map));
if(!$exists){
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset = $wpdb->get_charset_collate();
dbDelta("CREATE TABLE {$map} (wc_order_id BIGINT UNSIGNED NOT NULL, zoho_salesorder_id VARCHAR(64) NOT NULL, PRIMARY KEY (wc_order_id), KEY zoho_salesorder_id (zoho_salesorder_id)) $charset;");
}
$already=$wpdb->get_var($wpdb->prepare("SELECT zoho_salesorder_id FROM $map WHERE wc_order_id=%d",$order_id));
if($already){ WZHF_Logger::log('SO create:skip-existing', array('order_id'=>$order_id,'so'=>$already)); return; }
$z=new WZHF_Zoho(); if(!$z->is_connected()){ WZHF_Logger::log('Zoho not connected; skip'); return; }
$settings=array('create_missing'=>wzhf_sanitize_bool(wzhf_get_option('create_missing','0')));
list($so,$err)=$z->create_sales_order_from_wc($order,$settings);
if($so){
$wpdb->insert($map,array('wc_order_id'=>$order_id,'zoho_salesorder_id'=>$so['salesorder_id']));
$order->add_order_note('Zoho SO создан: '.$so['salesorder_id']);
if(wzhf_sanitize_bool(wzhf_get_option('set_status_after_so','0'))){
$target=wzhf_get_option('status_after_so','processing');
$order->update_status($target,'Статус обновлён после создания SO');
}
} else {
$order->add_order_note('Ошибка создания Zoho SO');
WZHF_Logger::log('SO create failed',array('order_id'=>$order_id,'err'=>$err));
}
}
}