/**
* Plugin Name: Arta Accounting Stock Sync
* Plugin URI: https://artadigitalstore.com
* Description: همگامسازی سریع با گزارشگیری دقیق از تغییرات کالاها.
* Version: 1.6.6
* Author: Arta Digital
*/
if (!defined('ABSPATH')) exit;
// ساخت جداول
function arta_sync_ensure_table() {
global $wpdb;
$log_table = $wpdb->prefix . 'arta_sync_logs';
$detail_table = $wpdb->prefix . 'arta_sync_details';
$wpdb->query("CREATE TABLE IF NOT EXISTS `$log_table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sync_time` datetime NOT NULL,
`ip_address` varchar(45),
`total_received` int(11) DEFAULT 0,
`total_updated` int(11) DEFAULT 0,
`total_skipped` int(11) DEFAULT 0,
`execution_time` varchar(20),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$wpdb->query("CREATE TABLE IF NOT EXISTS `$detail_table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`log_id` bigint(20) NOT NULL,
`sku` varchar(100),
`change_note` text,
PRIMARY KEY (`id`),
INDEX (`log_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
}
add_action('init', 'arta_sync_ensure_table');
// تابع حذف لاگهای قدیمی بر اساس روز مشخص شده
function arta_sync_cleanup_old_logs() {
global $wpdb;
$days = intval(get_option('arta_sync_retention_days', 30));
if ($days > 0) {
$log_table = $wpdb->prefix . 'arta_sync_logs';
$detail_table = $wpdb->prefix . 'arta_sync_details';
// شناسایی لاگهای قدیمیتر از بازه مشخص شده
$old_log_ids = $wpdb->get_col($wpdb->prepare(
"SELECT id FROM `$log_table` WHERE sync_time < DATE_SUB(NOW(), INTERVAL %d DAY)",
$days
));
if (!empty($old_log_ids)) {
$ids_placeholder = implode(',', array_map('intval', $old_log_ids));
// حذف جزئیات مربوطه
$wpdb->query("DELETE FROM `$detail_table` WHERE log_id IN ($ids_placeholder)");
// حذف لاگهای اصلی
$wpdb->query("DELETE FROM `$log_table` WHERE id IN ($ids_placeholder)");
}
}
}
// ثبت کرونجاب روزانه برای پاکسازی خودکار لاگها
add_action('arta_daily_log_cleanup_event', 'arta_sync_cleanup_old_logs');
if (!wp_next_scheduled('arta_daily_log_cleanup_event')) {
wp_schedule_event(time(), 'daily', 'arta_daily_log_cleanup_event');
}
function arta_handle_bulk_stock_update(WP_REST_Request $request) {
global $wpdb;
// پاکسازی سریع لاگهای قدیمی قبل از عملیات
arta_sync_cleanup_old_logs();
$start_time = microtime(true);
$items = $request->get_json_params();
if (empty($items)) return new WP_REST_Response(['message' => 'Empty data'], 400);
// ۱. ثبت در جدول اصلی و گرفتن ID
$wpdb->insert($wpdb->prefix . 'arta_sync_logs', [
'sync_time' => current_time('mysql'),
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'Unknown',
'total_received' => count($items)
]);
$log_id = $wpdb->insert_id;
$updated = 0; $skipped = 0; $details_batch = [];
// بارگذاری SKUها
$raw_skus = $wpdb->get_results("SELECT post_id, meta_value as sku FROM {$wpdb->postmeta} WHERE meta_key = '_sku' AND meta_value != ''");
$sku_map = []; foreach ($raw_skus as $row) $sku_map[trim($row->sku)] = $row->post_id;
foreach ($items as $item) {
$sku = trim(strval($item['code'] ?? ''));
if (!isset($sku_map[$sku])) { $skipped++; continue; }
$product_id = $sku_map[$sku];
$price_rial = isset($item['PriceSale1']) ? floatval($item['PriceSale1']) : null;
$qty = isset($item['qty']) ? intval($item['qty']) : null;
$note = "";
if ($qty !== null) {
update_post_meta($product_id, '_stock', max(0, $qty));
update_post_meta($product_id, '_stock_status', ($qty > 0 ? 'instock' : 'outofstock'));
$note .= "موجودی: $qty ";
}
if ($price_rial !== null) {
$toman = $price_rial / 10;
update_post_meta($product_id, '_regular_price', $toman);
update_post_meta($product_id, '_price', $toman);
$note .= "قیمت: $toman ";
}
if ($note) {
$updated++;
$details_batch[] = "($log_id, '$sku', '$note')";
}
}
// ذخیره جزئیات به صورت گروهی برای سرعت بالا
if (!empty($details_batch)) {
$wpdb->query("INSERT INTO {$wpdb->prefix}arta_sync_details (log_id, sku, change_note) VALUES " . implode(',', $details_batch));
}
$wpdb->update($wpdb->prefix . 'arta_sync_logs', ['total_updated' => $updated, 'total_skipped' => $skipped, 'execution_time' => round(microtime(true) - $start_time, 2).'s'], ['id' => $log_id]);
return new WP_REST_Response(['success' => true, 'updated' => $updated], 200);
}
// ثبت اندپوینت و منو
add_action('rest_api_init', function () {
register_rest_route('arta/v1', '/update-stock', ['methods' => 'POST', 'callback' => 'arta_handle_bulk_stock_update', 'permission_callback' => '__return_true']);
});
add_action('admin_menu', function () {
add_menu_page('گزارش سینک', 'گزارش سینک', 'manage_options', 'arta-sync-logs', 'arta_render_sync_logs_page', 'dashicons-update');
});
function arta_render_sync_logs_page() {
global $wpdb;
$log_table = $wpdb->prefix . 'arta_sync_logs';
// ذخیره تنظیمات نگهداری لاگ
if (isset($_POST['save_retention_days'])) {
check_admin_referer('arta_save_retention_action', 'arta_retention_nonce');
$days = max(1, intval($_POST['retention_days']));
update_option('arta_sync_retention_days', $days);
arta_sync_cleanup_old_logs();
echo '
تنظیمات با موفقیت ذخیره و لاگهای قدیمی پاکسازی شدند.
';
}
// اگر کاربر روی مشاهده جزئیات کلیک کرد
if (isset($_GET['view_id'])) {
$id = intval($_GET['view_id']);
$details = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}arta_sync_details WHERE log_id = %d", $id));
echo '
';
if (!empty($details)) {
foreach ($details as $d) echo "
$d->sku
$d->change_note
";
} else {
echo '
موردی یافت نشد.
';
}
echo '
';
return;
}
// صفحه لیست اصلی
if (isset($_POST['clear'])) {
$wpdb->query("TRUNCATE TABLE `$log_table`");
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}arta_sync_details");
echo '
تمامی لاگها با موفقیت پاک شدند.
';
}
$retention_days = intval(get_option('arta_sync_retention_days', 30));
$logs = $wpdb->get_results("SELECT * FROM `$log_table` ORDER BY id DESC LIMIT 50");
echo '
سعی میکنیم هر روز قیمت های سایت را بر اساس نرخ های اعلامی بروز نماییم ، با اینحال قبل از ثبت سفارش ترجیجا تماس بگیرید تا اگر قیمت یا موجودی تغییر داشت مطلع شوید.
سعی میکنیم هر روز قیمت های سایت را بر اساس نرخ های اعلامی بروز نماییم ، با اینحال قبل از ثبت سفارش ترجیجا تماس بگیرید تا اگر قیمت یا موجودی تغییر داشت مطلع شوید.
به دلیل تغییر قیمت و موجودی فروشندگان، بصورت موقت امکان خرید از سایت غیرفعال میباشد، در این مدت شما میتوانید از طریق تماس یا پیام رسان ها جهت استعلام قیمت و موجودی با ما در ارتباط باشید.