Plugin Directory

Changeset 2693175


Ignore:
Timestamp:
03/13/2022 09:38:10 AM (4 years ago)
Author:
sokangroup
Message:

update version => 1.2.0

Location:
sokan-integration
Files:
29 added
9 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • sokan-integration/trunk/Sokan-integration.php

    r2655228 r2693175  
    77 * Plugin Name: sokan Integration
    88 * Description:  افزونه ای برای استخراج تمامی اطلاعات ووکامرس مورد نیاز پلتفرم سکان
    9  * Version: 1.1.0
     9 * Version: 1.2.0
    1010 * Author: Sokan
    1111 * Author URI: https://Sokan.tech/
     
    1515 */
    1616
    17 
    1817defined('ABSPATH') or die('No access!');
    1918
     
    2524}
    2625
    27 require_once SKNG_PLUGIN_PATH . 'include/skng-auto-loader.php';
    28 
    29 function skng_str_trim($in)
    30 {
    31     return str_replace("'", "\'", $in);
     26/**
     27 * Loads the required classes
     28 * @return void
     29 * @since 1.1.0
     30 */
     31function skng_load_classes(){
     32    require_once SKNG_PLUGIN_PATH . 'include/classes/class-skng-api.php';
     33    require_once SKNG_PLUGIN_PATH . 'include/classes/class-skng-db.php';
     34    require_once SKNG_PLUGIN_PATH . 'include/classes/class-skng-logger.php';
     35    require_once SKNG_PLUGIN_PATH . 'include/custom/skng-custom.php';
    3236}
    3337
    3438add_action('skng_auto_sync', 'skng_auto_sync_data');
    35 add_action('skng_auto_full_sync', 'skng_auto_sync_data',10,2);
    36 
    37 function skng_auto_sync_data($entity = null,$entity_id = 0){
    38     if (!empty(get_option(SKNG_PLUGIN_NAME . '_token'))){
    39         $full_sync_style = true;
    40         require_once SKNG_PLUGIN_PATH . 'include/skng-auto-loader.php';
    41         require_once SKNG_PLUGIN_PATH . 'init/fill_data.php';
    42         require_once SKNG_PLUGIN_PATH . 'init/sync_data.php';
    43     }
     39
     40function skng_auto_sync_data(){
     41    if (!empty(get_option(SKNG_PLUGIN_NAME . '_token')) and function_exists('skng_load_classes')){
     42        skng_load_classes();
     43        require_once SKNG_PLUGIN_PATH . 'job/sync_data.php';
     44    }
     45}
     46
     47if (function_exists('skng_load_classes')){
     48    skng_load_classes();
    4449}
    4550
     
    4752{
    4853
    49 
     54    /**
     55     * register function called everytime admin page is loaded
     56     * add action for adding sokan item menu to admin panel
     57     * add filter for adding sokan setting button in plugin list page
     58     * @return void
     59     * @since 1.0.0
     60     */
    5061    function skng_register()
    5162    {
     
    5364        add_filter("plugin_action_links_" . plugin_basename(__FILE__), array($this, 'skng_settings_link'));
    5465        $this->skng_add_hooks();
    55 
    56     }
    57 
    58 
     66    }
     67
     68    /**
     69     * Create sokan setting button on plugin page list
     70     * @return array
     71     * @since 1.0.0
     72     */
    5973    function skng_settings_link($links)
    6074    {
     
    6680    /**
    6781     * Create sokan menu item in wordPress menu panel
    68      *
    69      * @return void
    70      * @since 1.0.0
    71      *
    72      */
    73 
     82     * @return void
     83     * @since 1.0.0
     84     */
    7485    function skng_add_admin_pages()
    7586    {
     
    8596    }
    8697
     98    /**
     99     * called when sokan integration icon in admin panel clicked
     100     * show sokan integration admin page view
     101     * @return void
     102     * @since 1.0.0
     103     */
    87104    function skng_admin_index()
    88105    {
     
    91108    }
    92109
    93 
    94110    /**
    95111     * called When admin activates the plugin
     112     * check if woocommerce plugin installed and activated on store
     113     * job new daily job for sync
     114     * create log table
    96115     * rewrite saved rules if exists
    97116     * @return void
    98117     * @since 1.0.0
    99      *
    100118     */
    101119    function skng_activate()
    102120    {
    103 
    104121
    105122        if (!is_plugin_active('woocommerce/woocommerce.php')
    106123            and current_user_can('activate_plugins')) {
    107             wp_die('برای فعال سازی پلاگین سکان لطفا اول پلاگین ووکامرس خود را فعال کنید. <br><a href="' . admin_url('plugins.php') . '">&laquo;بازگشت به صفحه افزونه ها</a>');
     124            wp_die('برای فعال سازی پلاگین سکان لطفا ابتدا پلاگین ووکامرس خود را فعال کنید. <br><a href="' . admin_url('plugins.php') . '">&laquo;بازگشت به صفحه افزونه ها</a>');
    108125        }
    109126
    110127        if ( ! wp_next_scheduled ( 'skng_auto_sync' ) ) {
    111             $test = wp_schedule_event( time() , 'daily', 'skng_auto_sync' );
    112         }
    113 
    114         // create middle tables
    115         require_once SKNG_PLUGIN_PATH . 'init/create_tables.php';
    116 
    117         // create token value in options
    118         if (!get_option(SKNG_PLUGIN_NAME . '_token'))
     128            wp_schedule_event( time() , 'daily', 'skng_auto_sync' );
     129        }
     130
     131        $this->skng_drop_old_tables();
     132        $this->skng_create_log_table();
     133
     134        if (!get_option(SKNG_PLUGIN_NAME . '_token')) {
     135
    119136            update_option(SKNG_PLUGIN_NAME . '_token', '');
    120         if (!get_option(SKNG_PLUGIN_NAME . '_sale_status'))
    121137            update_option(SKNG_PLUGIN_NAME . '_sale_status', 'wc-completed');
    122         if (!get_option(SKNG_PLUGIN_NAME . '_sale_status_fa'))
    123138            update_option(SKNG_PLUGIN_NAME . '_sale_status_fa', 'تکمیل شده');
    124         if (!get_option(SKNG_PLUGIN_NAME . '_refunded_status'))
    125139            update_option(SKNG_PLUGIN_NAME . '_refunded_status', 'wc-refunded');
    126         if (!get_option(SKNG_PLUGIN_NAME . '_custom_weight'))
    127             update_option(SKNG_PLUGIN_NAME . '_custom_weight', 'وزن-محصول');
    128         if (!get_option(SKNG_PLUGIN_NAME . '_sync_date'))
    129140            update_option(SKNG_PLUGIN_NAME . '_sync_date', '');
    130141
     142        }
     143
    131144        flush_rewrite_rules();
    132145    }
     
    134147
    135148    /**
    136      *called When admin deactivates the plugin
    137      * rewrite saved rules
    138      * @return void
    139      * @since 1.0.0
    140      *
     149     * called When admin deactivates the plugin
     150     * rewrite saved rules and disable daily sync
     151     * @return void
     152     * @since 1.0.0
    141153     */
    142154    function skng_deactivate()
     
    145157        wp_unschedule_event( $timestamp, 'skng_auto_sync' );
    146158        flush_rewrite_rules();
    147 
    148     }
    149 
    150     /**
    151      * init hooks for when any of requested data added or changes then sync it
    152      *
     159    }
     160
     161    /**
     162     * Add hooks to track changes in data
    153163     * @return Void
    154164     * @since 1.0.0
    155      *
    156165     */
    157166    function skng_add_hooks()
    158167    {
    159         $com = str_replace('wc-', '', get_option(SKNG_PLUGIN_NAME . '_sale_status'));
    160         $ref = str_replace('wc-', '', get_option(SKNG_PLUGIN_NAME . '_refunded_status'));
     168        $complete_status = str_replace('wc-', '', get_option(SKNG_PLUGIN_NAME . '_sale_status'));
     169        $refund_status = str_replace('wc-', '', get_option(SKNG_PLUGIN_NAME . '_refunded_status'));
    161170        add_action('edit_product_cat', array($this, 'skng_category_hook'), 10 , 1);
    162171        add_action('create_product_cat', array($this, 'skng_category_hook'), 10 , 1);
    163172        add_action('woocommerce_new_product', array($this, 'skng_product_hook'), 10 , 1);
    164173        add_action('woocommerce_update_product', array($this, 'skng_product_hook'), 10 , 1);
    165         add_action('woocommerce_order_status_' . $com, array($this, 'skng_order_status_hook'), 10 , 1);
    166         add_action('woocommerce_order_status_' . $ref, array($this, 'skng_order_status_hook'), 10 , 1);
     174        add_action('woocommerce_order_status_' . $complete_status, array($this, 'skng_order_status_hook'), 10 , 1);
     175        add_action('woocommerce_order_status_' . $refund_status, array($this, 'skng_order_status_hook'), 10 , 1);
    167176    }
    168177
    169178    /**
    170179     * called when any woocommerce order added or changes
    171      * save new or edited order in temp table
    172      * then sync order with sokan api
    173      *
     180     * and schedule new sync job for 40 second later run in background
    174181     * @since 1.0.0
    175182     * param is new or edited order id
     
    177184    function skng_order_status_hook($order_id)
    178185    {
    179         wp_schedule_single_event(time() + 40, 'skng_auto_full_sync' , array('order' , $order_id));
    180     }
     186        wp_schedule_single_event(time() + 40, 'skng_auto_sync');
     187    }
     188
     189    /**
     190     * called when any woocommerce product added or changes
     191     * and schedule new sync job run in background
     192     * @since 1.0.0
     193     * param is new or edited product id
     194     */
    181195    function skng_product_hook($product_id)
    182196    {
    183         wp_schedule_single_event(time(), 'skng_auto_full_sync' ,  array('product' , $product_id));
    184     }
     197        wp_schedule_single_event(time(), 'skng_auto_sync');
     198    }
     199
     200    /**
     201     * called when any woocommerce category added or changes
     202     * and schedule new sync job run in background
     203     * @since 1.0.0
     204     * param is new or edited category id
     205     */
    185206    function skng_category_hook($category_id)
    186207    {
    187         wp_schedule_single_event(time(), 'skng_auto_full_sync' ,  array('category',$category_id));
    188     }
     208        wp_schedule_single_event(time(), 'skng_auto_sync');
     209    }
     210
     211    /**
     212     * create log table if not exist
     213     * this function called once on installing plugin
     214     * @since 1.0.0
     215     */
     216    function skng_create_log_table(){
     217
     218        global $wpdb;
     219        $collate = '';
     220
     221        if ($wpdb->has_cap('collation')) {
     222            $collate = $wpdb->get_charset_collate();
     223        }
     224
     225        $log_table_name = "{$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_logs";
     226
     227        $wpdb->query(" CREATE TABLE IF NOT EXISTS `$log_table_name` (
     228                    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     229                    `entity` varchar(255) ,
     230                    `object_id` varchar(100) unique,
     231                    `error` TEXT(2000)  ,
     232                    `payload` TEXT(2000) ,
     233                    `date` datetime DEFAULT NULL,
     234                    PRIMARY KEY (`id`)
     235                )  $collate
     236            ");
     237    }
     238
     239    /**
     240     * delete old table that in new version doest exist
     241     * this function called once on installing plugin
     242     * @since 1.1.0
     243     */
     244    function skng_drop_old_tables(){
     245
     246        if ( is_admin() ) {
     247            global $wpdb;
     248            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_logs" );
     249            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_brands" );
     250            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_customers" );
     251            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_invoieces" );
     252            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_productcats" );
     253            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_products" );
     254            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_region" );
     255        }
     256    }
     257
    189258}
    190259
     
    194263}
    195264
    196 
    197265// activation
    198 register_activation_hook(__FILE__, array($Integration, 'skng_activate'));
     266register_activation_hook(__FILE__, [$Integration, 'skng_activate']);
    199267
    200268// deactivation
    201 register_deactivation_hook(__FILE__, array($Integration, 'skng_deactivate'));
    202 
     269register_deactivation_hook(__FILE__, [$Integration, 'skng_deactivate']);
     270
     271
     272add_action('wp_ajax_skng_sokan_sync', 'skng_sokan_sync' );
    203273
    204274/**
     
    208278 * @since 1.0.0
    209279 */
    210 add_action('wp_ajax_skng_sokan_sync', 'skng_sokan_sync' );
    211 
    212280function skng_sokan_sync()
    213281{
    214     $item = '';
    215     $full_sync_style = true;
    216     if (isset($_POST['item'])){
    217         $_item = sanitize_text_field($_POST['item']);
    218         if (!empty($_item)){
    219             $item = $_item;
    220             $full_sync_style = false;
    221         }
    222     }
    223     switch ($item) {
    224         case 'fill':
    225             require_once SKNG_PLUGIN_PATH."init/fill_data.php";
    226             break;
    227         case 'sync':
    228             require_once SKNG_PLUGIN_PATH."init/sync_data.php";
    229             break;
    230         case 'custom_code':
    231             skng_get_custom_code();
    232             break;
    233         default:
    234             # code...
    235             break;
    236     }
     282
     283    if (!isset($_POST['item'])){
     284        wp_die();
     285    }
     286
     287    $item = sanitize_text_field($_POST['item']);
     288
     289    if ($item == 'sync'){
     290        require_once SKNG_PLUGIN_PATH."job/sync_data.php";
     291    }  elseif ($item == 'custom_code' and class_exists('Skng_Sokan_logger')){
     292        (new Skng_Sokan_logger())->skng_get_custom_code();
     293    }
     294
    237295    wp_die();
    238296}
  • sokan-integration/trunk/admin.php

    r2655227 r2693175  
    22global $wpdb;
    33
    4 
    5 
    6 $token_error = '';
    7 $wp_cron_error = '';
    8 
    9 $api_url_select = array(
    10     'ارسال به نسخه آزمایشی' => "https://api-lab.sokan.tech",
    11     'ارسال به نسخه دمو' => "https://api-demo.sokan.tech",
    12     'ارسال به نسخه اپ' => "https://api-app.sokan.tech",
    13 );
    14 
    15 $all_attr_label = $wpdb->get_results("SELECT `attribute_name` , `attribute_label`
    16 FROM `{$wpdb->prefix}woocommerce_attribute_taxonomies`  ", ARRAY_A);
    17 
    18 update_option("custom_code" , json_encode($_POST));
    19 if (isset($_GET['item'])){
     4$db = new Skng_Sokan_db($wpdb);
     5$api_url_select = $db->skng_all_api_urls();
     6$login_error = '';
     7$last_date = 'همگام سازی نشده';
     8
     9if (isset($_GET['item'])) {
    2010
    2111    $item = sanitize_text_field($_GET['item']);
    22     if ($item == 'reset_all'){
    23         update_option(SKNG_PLUGIN_NAME.'_sync_date' , '');
    24         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_brands");
    25         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_customers");
    26         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_invoices");
    27         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_logs");
    28         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_productcats");
    29         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_products");
    30         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_region");
    31     }elseif ($item == 'reset_log'){
    32         $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_logs");
    33     }
    34 }else if (isset($_POST)){
    35 
    36     if (isset($_POST[SKNG_PLUGIN_NAME . '_token'])) {
    37         $token = sanitize_text_field($_POST[SKNG_PLUGIN_NAME . '_token']);
    38         if (empty($token)){
    39             update_option(SKNG_PLUGIN_NAME . '_token', $token);
    40         }else{
    41             update_option(SKNG_PLUGIN_NAME . '_token', $token);
    42             $brand = new Skng_Brand($wpdb);
    43             $res = $brand->skng_send_request("");
    44             if ($res['http_response_code'] == 401){
    45                 update_option(SKNG_PLUGIN_NAME . '_token', '');
    46                 $token_error = 'کلید دسترسی معتبر نیست';
    47             }
    48         }
    49     }
    50 
    51     if (isset($_POST['api_url'])) {
    52         $url = sanitize_text_field($_POST['api_url']);
    53         $cleaned_url = esc_url($url);
    54         if (!empty($cleaned_url) and in_array($cleaned_url , $api_url_select)){
    55             update_option(SKNG_PLUGIN_NAME . '_api_url', $cleaned_url);
     12    if ($item == 'reset_all') {
     13        $db->skng_reset_sync_date();
     14    } elseif ($item == 'logout') {
     15        update_option(SKNG_PLUGIN_NAME . '_token', '');
     16    }
     17}
     18
     19if (isset($_POST)) {
     20
     21    if (isset($_POST[SKNG_PLUGIN_NAME . '_username'])) {
     22
     23
     24        $url = esc_url(sanitize_text_field($_POST['api_url']));
     25        if (!empty($url) and in_array($url, $api_url_select)) {
     26            update_option(SKNG_PLUGIN_NAME . '_api_url', $url);
     27        }
     28
     29        $api = new Skng_Sokan_api();
     30
     31        $body = [
     32            'username' => sanitize_text_field($_POST[SKNG_PLUGIN_NAME . '_username']),
     33            'password' => sanitize_text_field($_POST[SKNG_PLUGIN_NAME . '_password'])
     34        ];
     35
     36        $result = $api->skng_api_request('token', json_encode($body));
     37
     38        if ($api->isSuccess($result)) {
     39            $response = json_decode($result['result'], true);
     40            update_option(SKNG_PLUGIN_NAME . '_token', $response['token']);
     41        } elseif ($api->isServerError($result)) {
     42
     43            $logger = new Skng_Sokan_logger();
     44            $logger->skng_logger([
     45                'entity' => "LoginException",
     46                'errors' => [json_encode($result)]
     47            ]);
     48            $login_error = 'مشکلی در ورود به حساب کاربری به وجود آمده لطفا با پشتیبانی تماس بگیرید';
     49
     50        } else {
     51
     52            $login_error = 'نام کاربری یا رمز عبور اشتباه است';
     53
    5654        }
    5755    }
    5856
    5957    if (isset($_POST['sale_status_select'])) {
    60         $data = sanitize_text_field($_POST['sale_status_select']);
    61         if (!empty($data)){
    62             $option = explode(",", $data);
    63             if (in_array($option[1] , wc_get_order_statuses())){
     58
     59        $complete_status = sanitize_text_field($_POST['sale_status_select'] ?? '');
     60        $refunded_status = sanitize_text_field($_POST['refunded_status_select'] ?? '');
     61
     62        if (!empty($complete_status) and !empty($refunded_status)) {
     63            $option = explode(",", $complete_status);
     64            if (in_array($option[1], wc_get_order_statuses())) {
    6465                update_option(SKNG_PLUGIN_NAME . '_sale_status', $option[0]);
    6566                update_option(SKNG_PLUGIN_NAME . '_sale_status_fa', $option[1]);
     67                update_option(SKNG_PLUGIN_NAME . '_refunded_status', $refunded_status);
    6668            }
    6769        }
    6870    }
    69 
    70     if (isset($_POST['refunded_status_select'])) {
    71         $data = sanitize_text_field($_POST['refunded_status_select']);
    72         if (!empty($data)){
    73             update_option(SKNG_PLUGIN_NAME . '_refunded_status', $data);
    74         }
    75     }
    76 
    77     if (isset($_POST['weight_select'])) {
    78         $data = sanitize_text_field($_POST['weight_select']);
    79         if (!empty($data)){
    80             update_option(SKNG_PLUGIN_NAME . '_custom_weight', $data);
    81         }
    82     }
    83 
    84     if (isset($_POST['brand_select'])) {
    85         $data = sanitize_text_field($_POST['brand_select']);
    86         if (!empty($data)){
    87             update_option(SKNG_PLUGIN_NAME . '_custom_brand', $data);
    88         }
    89     }
    90 
    9171}
    9272
     73$token = get_option(SKNG_PLUGIN_NAME . '_token');
     74$api_url = get_option(SKNG_PLUGIN_NAME . '_api_url');
     75$sale_status = get_option(SKNG_PLUGIN_NAME . '_sale_status');
     76$refunded_status = get_option(SKNG_PLUGIN_NAME . '_refunded_status');
     77
     78if (!empty($date = get_option(SKNG_PLUGIN_NAME . '_sync_date'))) {
     79
     80    $last_date = round((time() - strtotime($date)) / (60 * 60 * 24));
     81
     82    if ($last_date < 1) {
     83        $last_date = "امروز" . " ( " . $date . " )";
     84    } else {
     85        $last_date = $last_date . " روز قبل " . " ( " . $date . " )";
     86    }
     87}
     88
    9389?>
    9490
    95 
    96 <?php
    97 $token = get_option(SKNG_PLUGIN_NAME.'_token');
    98 $api_url = get_option(SKNG_PLUGIN_NAME.'_api_url');
    99 $sale_status = get_option(SKNG_PLUGIN_NAME.'_sale_status');
    100 $sale_status_fa = get_option(SKNG_PLUGIN_NAME.'_sale_status_fa');
    101 $refunded_status = get_option(SKNG_PLUGIN_NAME.'_refunded_status');
    102 $custom_brand = get_option(SKNG_PLUGIN_NAME.'_custom_brand');
    103 $custom_weight = get_option(SKNG_PLUGIN_NAME.'_custom_weight');
    104 $date = get_option(SKNG_PLUGIN_NAME.'_sync_date');
    105 
    106 $last_date = 'همگام سازی نشده';
    107 if (!empty($date)){
    108     $now = time();
    109     $your_date = strtotime($date);
    110     $last_date = round(($now - $your_date) / (60 * 60 * 24));
    111 
    112     if ($last_date < 1){
    113         $last_date = "امروز" . " ( ".$date." )";
    114     }else{
    115         $last_date = $last_date." روز قبل " . " ( ".$date." )";
    116     }
    117 }
    118 
    119 
    120 $logs =  $wpdb->get_results("SELECT detail FROM {$wpdb->prefix}" . SKNG_PLUGIN_NAME . "_logs" , ARRAY_A);
    121 $log_count = count($logs);
    122 
    123 
    124 ?>
    125 
    12691<div class="wrap">
    127     <h1>سکان</h1>
    128     <p style="display: <?php  echo empty($wp_cron_error) ? esc_html('none') : esc_html('unset') ;?> ; color: #f31b1b" ><?php echo esc_html($wp_cron_error)?></p>
    129 
    130     <form method="post" action="admin.php?page=sokan_integration">
    131 
    132         <label>کد دسترسی:</label>
    133         <br/>
    134         <input type="text" class="regular-text" name="<?php echo esc_attr(SKNG_PLUGIN_NAME."_token") ?>"
    135                value="<?php echo esc_html($token); ?>"
    136                placeholder="لطفا کد دسترسی خود را از پنل سکان دریافت کرده و اینجا وارد کنید."/>
    137         <p style="display: <?php  echo empty($token_error) ? esc_html('none') : esc_html('unset') ;?> ; color: #f31b1b" ><?php echo esc_html($token_error)?></p>
    138         <br/><br/>
    139         <label>آدرس ارسال اطلاعات:</label><br/>
    140         <select name="api_url" >
    141             <?php foreach($api_url_select as $key => $value){ ?>
    142                 <option <?php echo esc_html($api_url)==esc_html($value)? 'selected':'' ?>
    143                         value="<?php echo esc_attr($value);?>"><?php echo esc_html($key);?></option>
    144             <?php } ?>
    145         </select>
    146         <br/><br/>
    147         <label>وضعیت سفارش های تکمیل شده : </label><br/>
    148         <select name="sale_status_select" >
    149             <?php foreach(wc_get_order_statuses() as $key => $value){ ?>
    150                 <option <?php echo esc_html($sale_status)==esc_html($key)? 'selected':'' ?>
    151                         value="<?php echo esc_attr("$key,$value");?>"><?php echo esc_html($value);?></option>
    152             <?php } ?>
    153         </select>
    154         <br/><br/>
    155         <label>وضعیت سفارش های مرجوع شده : </label><br/>
    156         <select name="refunded_status_select"  >
    157             <?php foreach(wc_get_order_statuses() as $key => $value){ ?>
    158                 <option <?php echo esc_html($refunded_status)==esc_html($key)? 'selected':'' ?>
    159                         value="<?php echo esc_attr($key);?>"><?php echo esc_html($value);?></option>
    160             <?php } ?>
    161         </select>
    162 
    163         <br/><br/>
    164         <label>نام ویژگی استفاده شده برای برند محصولات:</label><br/>
    165         <select name="brand_select" >
    166             <option   value="">هیچکدام</option>
    167             <?php foreach($all_attr_label as $value){ ?>
    168                 <option <?php echo esc_html($custom_brand)==esc_html($value['attribute_name'])? 'selected':'' ?>
    169                         value="<?php echo esc_attr($value['attribute_name']);?>"><?php echo esc_html($value['attribute_label']);?></option>
    170             <?php } ?>
    171         </select>
    172 
    173         <br/><br/>
    174         <label>نام ویژگی استفاده شده برای وزن محصولات:</label><br/>
    175         <select name="weight_select" >
    176             <option   value="">هیچکدام</option>
    177             <?php foreach($all_attr_label as $value){ ?>
    178                 <option <?php echo esc_html($custom_weight)==esc_html($value['attribute_name'])? 'selected':'' ?>
    179                         value="<?php echo esc_attr($value['attribute_name']);?>"><?php echo esc_html($value['attribute_label']);?></option>
    180             <?php } ?>
    181         </select>
    182 
    183         <?php submit_button(); ?>
    184     </form>
     92
     93    <a href="https://sokan.tech" target="_blank">
     94        <img class="mt-12" src="<?php echo plugin_dir_url(__FILE__) . 'assets/images/sokan-logo.png'; ?>" alt="logo">
     95    </a>
    18596
    18697    <hr/>
    18798
    188     <div style="display: <?php  echo empty($token) ? esc_html('none') : esc_html('unset') ;?>"  >
    189         <h2 id="title">آخرین همگام سازی : <?php echo esc_html($last_date)?></h2>
    190         <p id="message">برای شروع استخراج داده و همگام سازی  روی دکمه شروع عملیات کلیک کنید</p><br/>
    191        <div id="counter" style="display: none">
    192            <div>تعداد کل : <span id="all">0</span></div>
    193            <div style="font-weight:600">تعداد همگام سازی شده: <span id="synced">0</span></div>
    194            <div>تعداد همگام سازی نشده: <span id="remaining">0</span></div>
    195 
    196            <br/>
    197            <div id="progress-bar" class="progress-bar">
    198                <div id="progress" class="progress"></div>
    199            </div>
    200            <br/>
    201        </div>
    202 
    203         <div id="loader" class="loader"></div>
    204         <br/>
    205 
    206 
    207         <div>
    208             <button id="ajaxsync" class="button-primary">شروع عملیات </button>
    209             <button id="stopajaxsync" class="button-primary" style="background-color:#ce1e1e ; display: none" >توقف عملیات</button>
    210         </div>
    211 
    212         <br/>
    213 
    214         <div id="error"></div>
    215 
     99    <div id="skng_login" class="mt-12 mb-12">
     100        <div style="display: <?php echo empty($token) ? esc_html('unset') : esc_html('none'); ?>">
     101            <h2>ورود به حساب کاربری سکان</h2>
     102            <form method="post" action="admin.php?page=sokan_integration">
     103
     104                <label>پنل:</label>
     105                <select name="api_url">
     106                    <?php foreach ($api_url_select as $key => $value) { ?>
     107                        <option <?php echo esc_html($api_url) == esc_html($value) ? 'selected' : '' ?>
     108                                value="<?php echo esc_attr($value); ?>"><?php echo esc_html($key); ?>
     109                        </option>
     110                    <?php } ?>
     111                </select>
     112                <br/>
     113                <br>
     114
     115                <input type="text" class="regular-text" name="<?php echo esc_attr(SKNG_PLUGIN_NAME . "_username") ?>"
     116                       placeholder="نام کاربری"/>
     117                <br/>
     118                <br>
     119                <input type="text" class="regular-text" name="<?php echo esc_attr(SKNG_PLUGIN_NAME . "_password") ?>"
     120                       placeholder="رمز عبور"/>
     121
     122                <p class="error-text"> <?php echo $login_error; ?></p>
     123
     124                <?php submit_button("ورود"); ?>
     125
     126                <p>
     127                    حساب کاربری ندارید ؟<a href="https://sokan.tech/request-demo/" target="_blank"> درخواست دمو </a>
     128                </p>
     129            </form>
     130        </div>
     131        <div style="display: <?php echo empty($token) ? esc_html('none') : esc_html('unset'); ?>">
     132
     133            <h2>فروشگاه به پلتفرم <a href="<?php echo esc_html(str_replace('api-', '', $api_url)) ?>" target="_blank">سکان</a>
     134                متصل شد!</h2>
     135
     136            <ul class="mt-8">
     137                <li>با خروج از حساب کاربری همگام سازی داده های فروشگاه با سکان متوقف خواهد شد.</li>
     138                <li>با ورود دوباره همگام سازی داده ها از سر گرفته خواهد شد.</li>
     139            </ul>
     140
     141            <a
     142                    href="admin.php?page=sokan_integration&item=logout"
     143                    class="button-primary mt-8 mb-12"
     144                    style="background-color:#ce1e1e">خروج از حساب کاربری
     145            </a>
     146
     147        </div>
    216148    </div>
    217149
    218     <div  style="display: <?php  echo empty($token) ? esc_html('unset') : esc_html('none') ;?>">
    219         <h2>برای شروع عملیات همگام سازی لطفا کلید دسترسی پنل سکان را در تنظیمات بالا وارد کرده و گزینه ذخیره تغییرات را بزنید.</h2>
     150    <hr/>
     151
     152    <div style="display: <?php echo empty($token) ? esc_html('none') : esc_html('unset'); ?>">
     153
     154        <div id="skng_setting" class="mt-12">
     155            <h2>تنظیمات همگام سازی</h2>
     156            <form method="post" action="admin.php?page=sokan_integration">
     157                <label>وضعیت سفارش های تکمیل شده : </label>
     158                <select name="sale_status_select">
     159                    <?php foreach (wc_get_order_statuses() as $key => $value) { ?>
     160                        <option <?php echo esc_html($sale_status) == esc_html($key) ? 'selected' : '' ?>
     161                                value="<?php echo esc_attr("$key,$value"); ?>"><?php echo esc_html($value); ?>
     162                        </option>
     163                    <?php } ?>
     164                </select>
     165                <br/>
     166                <br/>
     167                <label>وضعیت سفارش های مرجوع شده : </label>
     168                <select name="refunded_status_select">
     169                    <?php foreach (wc_get_order_statuses() as $key => $value) { ?>
     170                        <option <?php echo esc_html($refunded_status) == esc_html($key) ? 'selected' : '' ?>
     171                                value="<?php echo esc_attr($key); ?>"><?php echo esc_html($value); ?>
     172                        </option>
     173                    <?php } ?>
     174                </select>
     175                <?php submit_button("ذخیره تنظیمات"); ?>
     176            </form>
     177        </div>
     178
     179        <hr/>
     180
     181        <div id="skng_sync">
     182            <h2>همگام سازی داده ها</h2>
     183            <h3 id="title"> تاریخ آخرین سفارش همگام سازی شده : <strong
     184                        id="sync-date"><?php echo esc_html($last_date) ?></strong></h3>
     185            <h4 id="sync-date"></h4>
     186            <ul class="mt-8">
     187                <li>2- عملیات بر اساس تاریخ سفارشات ثبت شده می باشد و <strong>تاریخ نمایش داده شده تاریخ آخرین فاکتور
     188                        تکمیل شده در فروشگاه شماست</strong>.
     189                </li>
     190                <li>1- بعد از شروع تا اتمام عملیات و نمایش <strong>"پایان همگام سازی"</strong> این صفحه را باز نگه دارید
     191                    در غیر اینصورت عملیات متوقف و همگام سازی چند ساعت بعد به صورت خودکار انجام خواهد گرفت.
     192                </li>
     193                <li>3- بسته به تعداد سفارشات ثبت شده در فروشگاه شما عملیات اولیه همگام سازی ممکن است 20 دقیقه یا بیشتر
     194                    طول بکشد.
     195                </li>
     196                <li>4- بعد از همگام سازی اولیه و بروزرسانی شدن تاریخ نمایش داده شده بالا ، به صورت
     197                    <strong>خودکار</strong> داده های جدید یا بروزرسانی شده در پس زمینه با <strong>سکان</strong> همگام
     198                    سازی خواهد شد.
     199                </li>
     200            </ul>
     201            <br>
     202            <div id="message"></div>
     203            <a id="panel"
     204               href="<?php echo esc_html(str_replace('api-', '', $api_url)) ?>"
     205               target="_blank"
     206               class="button-primary mt-8"
     207               style="display: none">مشاهده پنل سکان
     208            </a>
     209            <div id="loader" class="loader mt-12"></div>
     210            <br/>
     211            <div class="mb-12">
     212                <button id="ajaxsync" class="button-primary">شروع عملیات</button>
     213                <button id="stopajaxsync" class="button-primary" style="background-color:#ce1e1e ; display: none">توقف
     214                    عملیات
     215                </button>
     216            </div>
     217            <br/>
     218            <br/>
     219
     220        </div>
     221
     222        <hr/>
     223
     224        <div id="skng_reset_log" class="mt-8">
     225            <h2>بازنشانی تاریخ همگام سازی</h2>
     226            <ul class="mt-8 mb-12 ">
     227                <li>1- پاک کردن آخرین تاریخ همگام سازی و خطاهای ثبت شده.</li>
     228                <li>2- تاریخ همگام سازی به حالت پیشفرض <strong>"همگام سازی نشده"</strong> تنظیم و عملیات همگام سازی از
     229                    <strong>اولین فاکتور</strong> ثبت شده شروع خواهد شد.
     230                </li>
     231                <li>3- <strong>این عمل داده های موجود در پنل سکان را پاک نخواهد کرد و صرفا داده های قدیمی دوباره ارسال
     232                        خواهند شد</strong>.
     233                </li>
     234            </ul>
     235            <br/>
     236            <a href="admin.php?page=sokan_integration&item=reset_all" class="button-primary"
     237               style="background-color:#ce1e1e">بازنشانی</a>
     238        </div>
     239
    220240    </div>
    221 
    222 
    223     <hr/>
    224     <br>
    225     <div style="display: <?php  echo $log_count == 0 ? esc_html('none') : esc_html('unset') ;?>" >
    226         <div>تعداد سطرهای خطا :  <span><?php echo esc_html($log_count);?></span></div>
    227         <label>لیست خطا ها : </label><br/>
    228         <select>
    229             <?php foreach($logs as $key => $value){ ?>
    230                 <option value="<?php echo esc_html($key);?>"><?php echo esc_html($value['detail']);?></option>
    231             <?php } ?>
    232         </select>
    233         <br/>
    234         <a href="admin.php?page=sokan_integration&item=reset_log" class="button-primary" style="background-color:#ce1e1e ; margin-top: 6px">پاک کردن خطاها</a>
    235         <br/>
    236         <br>
    237     </div>
    238     <br>
    239     <br>
    240     <div style="display: <?php  echo empty($token) ? esc_html('none') : esc_html('unset') ;?>"  >
    241         <a href="admin.php?page=sokan_integration&item=reset_all" class="button-primary" style="background-color:#ce1e1e">پاک کردن داده های استخراج شده</a>
    242         <p>تمامی داده های استخراج شده پاک خواهد شد و می توانید دوباره عملیات همگام سازی را شروع کنید</p><br/>
    243     </div>
    244 
    245241
    246242    <script>
    247243        const $ = jQuery;
    248244        let sync_locked = true;
    249         let fill_locked = true;
    250 
    251         setProgress(0,0);
    252 
    253         function setProgress(all,synced){
    254             var progress = all==0?0:parseInt(synced/all*100) ;
    255             $('#progress').css({width:(progress+"%")})
    256         }
     245
    257246        const data = {
    258247            'action': 'skng_sokan_sync',
    259             'item': 'fill'
     248            'item': 'sync'
    260249        };
    261250
    262         function fill_data(){
    263             if (!fill_locked){
    264                 $('#error').html('');
    265                 jQuery.post('admin-ajax.php', data, function(response) {
    266                     if (!fill_locked){
    267                         let res = JSON.parse(response)
    268                         if (res['success']){
    269                             if (res['finish']){
    270                                 sync_data()
    271                                 $('#message').html('').hide();
    272                                 $('#counter').hide();
    273                                 $('#title').html("همگام سازی داده ها با سکان لطفا صبر کنید . . .");
    274                             }else {
    275                                 $('#message').html(res['message']).show();
    276                                 fill_data();
    277                             }
    278 
    279                         }else {
    280                             const error = "خطا در انجام عملیات لطفا دوباره تلاش کنید";
    281                             $('#error').html('<textarea>'+error+'</textarea>');
    282                             reset_view()
     251        function sync_data() {
     252            if (!sync_locked) {
     253                jQuery.post('admin-ajax.php', data, function (response) {
     254                    let res = JSON.parse(response)
     255                    if (res['stop']) {
     256                        $('#message').html('<h2>' + res['message'] + '<h2/>');
     257                        $('#loader').fadeOut(200);
     258                        $('#panel').show();
     259                        $('#ajaxsync').hide();
     260                        $('#stopajaxsync').hide();
     261                        sync_locked = true;
     262                    } else {
     263                        if (!sync_locked) {
     264                            $('#message')
     265                                .append('<br>')
     266                                .append(res['message'])
     267                                .append("   ===>  ")
     268                                .append(res['state']);
     269                            $('#sync-date').html(res['date']);
    283270                        }
     271                        sync_data();
    284272                    }
    285                 }).fail(function(response) {
    286                     const error = "خطا در انجام عملیات لطفا دوباره تلاش کنید";
    287                     $('#error').html('<textarea>'+error+'</textarea>');
    288                     reset_view()
    289                 });
    290             }
    291         }
    292 
    293         function sync_data(){
    294             if(!sync_locked){
    295 
    296                 const data = {
    297                     'action': 'skng_sokan_sync',
    298                     'item': 'sync'
    299                 };
    300 
    301                 $('#error').html('');
    302                 jQuery.post('admin-ajax.php', data, function(response) {
    303                    if (!fill_locked){
    304                        let res = JSON.parse(response)
    305                        $('#title').html(res['message']);
    306                        if (typeof res['has_count'] != 'undefined'){
    307                            $('#counter').show();
    308                            $('#all').html(res['all']);
    309                            $('#synced').html(res['synced']);
    310                            $('#remaining').html(res['remaining']);
    311                            $('#title').html(res['message']);
    312                            setProgress(res['all'],res['synced']);
    313                            let err = JSON.stringify(res['error']);
    314                            if (err !== ""){
    315                                $('#error').html('<textarea>'+err+'</textarea>');
    316                                // $('#loader').fadeOut(200);
    317                            }
    318                        }
    319 
    320                        if (typeof res['full_sync'] != 'undefined'){
    321                            $('#message').html("کل اطلاعات با موفقیت همگام سازی شد").show();
    322                            $('#title').html("تکمیل همگام سازی!");
    323                            $('#loader').fadeOut(200);
    324                            $('#counter').hide();
    325                            $('#stopajaxsync').hide();
    326                            return;
    327                        }
    328 
    329                        if (res['stop']){
    330                            $('#message').html("برای شروع استخراج داده و همگام سازی  روی دکمه شروع عملیات کلیک کنید").show();
    331                            $('#loader').fadeOut(200);
    332                            $('#counter').hide();
    333                        }else {
    334                            sync_data();
    335                        }
    336                    }
    337                 }).fail(function(response) {
    338                     $('#error').html('<textarea>'+JSON.stringify(response)+'</textarea>');
     273                }).fail(function (response) {
     274                    alert('<textarea>' + JSON.stringify(response) + '</textarea>');
    339275                    $('#loader').fadeOut(200);
    340276                });
     
    342278        }
    343279
    344         function reset_view(){
    345             $('#message').html("برای شروع استخراج داده و همگام سازی  روی دکمه شروع عملیات کلیک کنید").show();
    346             $('#loader').fadeOut(200);
    347             $('#title').html("همگام سازی داده ها");
    348             $('#counter').hide();
    349             $('#ajaxsync').show();
    350         }
    351 
    352         function get_custom_code(){
     280        $(document).ready(function () {
     281
     282            $('#ajaxsync').click(function () {
     283                sync_locked = false;
     284                $('#message').html("در حال همگام سازی داده ها لطفا صبر کنید ...").show();
     285                $('#loader').fadeIn(200);
     286                $(this).hide();
     287                $('#stopajaxsync').show();
     288                sync_data();
     289            });
     290
     291            $('#stopajaxsync').click(function () {
     292                sync_locked = true;
     293                $(this).hide();
     294                $('#message').html("برای شروع استخراج داده و همگام سازی  روی دکمه شروع عملیات کلیک کنید").show();
     295                $('#loader').fadeOut(200);
     296                $('#ajaxsync').show();
     297            });
     298
    353299            const data = {
    354300                'action': 'skng_sokan_sync',
    355301                'item': 'custom_code'
    356302            };
    357             jQuery.post('admin-ajax.php', data, function(response) {})
    358         }
    359 
    360         $('#ajaxsync').click(function(){
    361             sync_locked = false;
    362             fill_locked = false;
    363             $('#message').html("در حال استخراج اطلاعات لطفا صبر کنید ...").show();
    364             $('#loader').fadeIn(200);
    365             $(this).hide();
    366             $('#stopajaxsync').show();
    367             fill_data();
     303            jQuery.post('admin-ajax.php', data, function (response) {
     304            })
     305
    368306        });
    369307
    370         $('#stopajaxsync').click(function(){
    371             sync_locked = true;
    372             fill_locked = true;
    373             $(this).hide();
    374             reset_view()
    375         });
    376 
    377         get_custom_code();
    378 
    379308    </script>
    380309
     
    382311
    383312<style>
    384     .progress-bar {
    385         width: 100%;
    386         height: 20px;
    387         border-radius: 10px;
    388         position: relative;
    389         background-color: #ddd;
    390         border: 1px solid #aaa;
    391     }
    392 
    393     .progress {
    394         transition: all .2s;
    395         background-color: #00d05d;
    396         position: absolute;
    397         top: 0px;
    398         left: 0px;
    399         width: 0%;
    400         height: 100%;
    401         border-radius: 10px;
    402     }
    403 
    404     #error {
    405         overflow: scroll;
    406         word-wrap: break-word;
    407     }
    408 
    409     #error textarea {
    410         width: 100%;
    411         direction: ltr;
    412         border: 1px solid #ef6969;
    413         color: #ef6969;
    414         min-height: 100px;
    415 
     313
     314    .mt-12 {
     315        margin-top: 12px;
     316    }
     317
     318    .mt-8 {
     319        margin-top: 8px;
     320    }
     321
     322    .mb-12 {
     323        margin-bottom: 12px;
     324    }
     325
     326    .error-text {
     327        color: red;
    416328    }
    417329
     
    435347        }
    436348    }
     349
    437350</style>
    438351
  • sokan-integration/trunk/include/custom/skng-custom.php

    r2655227 r2693175  
     1<?php
     2
     3add_filter('skng_get_all_orders_filter' , 'skng_complete_filter_invoice');
     4function skng_complete_filter_invoice($invoices): array
     5{
     6
     7    if (count($invoices) == 0){
     8        return $invoices;
     9    }
     10
     11    global $wpdb;
     12
     13    $final_order_status    = get_option( SKNG_PLUGIN_NAME . '_sale_status' );
     14    $refunded_order_status = get_option( SKNG_PLUGIN_NAME . '_refunded_status' );
     15
     16    $parent_orders = $wpdb->get_results("
     17                      SELECT do.order_id
     18                      FROM  {$wpdb->prefix}wc_order_stats AS do
     19                      WHERE do.status IN ('$final_order_status' , '$refunded_order_status')           
     20                      ", ARRAY_A);
     21
     22    $parent_order_ids = array_column($parent_orders , 'order_id');
     23   
     24    foreach ($invoices as $key => $value){
     25        if (!in_array($value['id'] , $parent_order_ids)){
     26            unset($invoices[$key]);
     27        }
     28    }
     29
     30    return $invoices;
     31}
  • sokan-integration/trunk/readme.txt

    r2655235 r2693175  
    55Tested up to: 5.8
    66Donate link: http://sokan.tech/
    7 Stable tag: 1.1.0
     7Stable tag: 1.2.0
    88Requires PHP: 7.0
    99License: GPLv2 or later
     
    1313
    1414== Description ==
    15 &#x202b;این پلاگین جهت استخراج اطلاعات فروشگاه های ووکامرسی برای سکان توسعه داده شده است.
    16 &#x202b;هدف این پلاگین ارسال داده های فروش ووکامرس برای پنل سکان برای آنالیز فروش می باشد.
    17 ## نیازمندی ها
    18 * وردپرس نسخه ۵.۲.۰ به بالا
    19 * ووکامرس نسخه ۴.۰.۰ به بالا
    20 * &#x202b;با فرض این که فروشگاه ووکامرسی شما فعال است، کافیست مراحل زیر را طی نمایید. نصب این پلاگین هیچ تفاوتی با پلاگین های معمول در وردپرس ندارد و به راحتی می توانید آن را نصب نمایید.
    21     * انتخاب گزینه آپلود پلاگین و یا جستجو در لیست پلاگین های نمایش داده شده
    22         * &#x202b;در صورتی که در قسمت جستجو توانستید پلاگین سکان را با نام "ارسال اطلاعات فروش ووکامرس برای سکان" پیدا کنید، کافیست روی گزینه نصب کلیک کنید تا پلاگین برای شما نصب شود.
    23         * &#x202b;با ورود به سایت سکان کلید حساب کاربری خود را دریافت کنید.
    24         * &#x202b;در صفحه راه اندازی پلاگین اطلاعات مورد نیاز را تنظیم کنید .
    25         * &#x202b;گزینه همگام سازی اطلاعات را کلیک کنید و منتظر تکمیل فرایند بمانید.
     15&#x202b;سکان،پلتفرم تحلیل داده مشتریان.
     16&#x202b;سکان اولین پلتفرم برای تحلیل داده مشتریان و بازاریابی داده محور (Data-driven Marketing) است.
     17&#x202b;ما داده‌های مشتریان شما را با هوش مصنوعی به‌سرعت تحلیل می‌کنیم و به‌شکل یک گزارش کاربردی در اختیارتان می‌گذاریم.
    2618
    27 &#x202b;لطفا در هر مرحله از نصب که مشکلی داشتید و یا با خطایی که متعلق به پلاگین سکان بود، مواجه شدید به پشتیبانی سکان اطلاع دهید.
    28 ## خروجی
    29 &#x202b;در حال حاضر پلاگین استخراج محصولات ووکامرس اطلاعات زیر را استخراج می کند:
    30 * همه محصولات ثبت شده در ووکامرس
    31 * برند های ثبت شده
    32 * لیست شهر ها و استان های دارای فاکتور
    33 * لیست همه مشتری ها
    34 * لیست همه فاکتور های فروش
    35 * لیست دسته بندی ها
     19## تحلیل رفتار مشتریان (Customer Analytics)
     20مشتریان شما اطلاعاتی با خود به‌همراه دارند. با تحلیل مشتریان و شکستن قفل این اطلاعات می‌توانید وارد ذهن مشتری شوید و خواسته‌های او را از قبل بدانید! تحلیل مشتریان به شما کمک می‌کند تا با برگزاری کمپین‌های هدفمند، رضایت مشتریان و مدیران کسب‌وکار را به‌دست بیاورید.
     21
     22* تقسیم‌بندی مشتریان با روش RFM
     23* رصد تغییر رفتار خرید مشتریان (RFM Transition)
     24* محاسبه نرخ بازگشت مشتریان جدید (New Customer Retention)
     25* محاسبه سهم مشتریان جدید از فروش (New Customer Share)
     26* محاسبه ارزش طول عمر مشتری (Customer Lifetime Value)
     27* خوشه‌بندی مشتریان (Customer Clustering)
     28
     29## تحلیل فروش محصولات (Product Performance Analytics)
     30هر محصول حرف‌های ناگفته دارد! اینکه چقدر پرطرفدار یا کم‌طرفدار است یا در کنار کدام محصول، بهتر به فروش می‌رسد؟ با تحلیل محصول می‌توانید آمار دقیقی از تعامل مشتریان با محصولات خود به‌دست بیاورید. این تحلیل حتی در چیدمان فروشگاه نیز به شما کمک می‌کند!
     31
     32* تحلیل عملکرد محصولات (Product Performance)
     33* تحلیل سبد خرید مشتریان (Customer Basket)
     34
     35## تحلیل‌های پیش‌بینی کننده (Predictive & Prescriptive Analytics)
     36حتما شنیده‌اید که می‌گویند: ملتی که تاریخ نخوانده باشد، مجبور به تکرار آن است! ما هم به این جمله باور داریم و در سکان، امکانی را ایجاد کرده‌ایم تا الگوی رفتار خرید مشتریانتان را در گذشته پیدا کنید و با ارائه پیشنهادهای موثر، از ریزش آنها جلوگیری کنید.
     37
     38* پیش‌بینی ریزش مشتری (Churn Prediction)
     39* تحلیل فاصله بین هر خرید (Time Between Purchase)
     40* دسته کردن محصولات (Product Bundling)
     41
     42## نظارت بر شاخص‌های کلیدی عملکرد(KPI Monitoring)
     43 کافیست روی گوی تحلیل توصیفی دست بکشید تا در آن گذشته را شفاف بینید! با مشخص کردن شاخص‌های عملکرد می‌توانید روند فعالیت کسب‌وکار خود را در بازه‌های زمانی دلخواه، مقایسه کنید. تمام این امکانات در یک محیط گرافیکی ساده و کاملا کاربردی ارائه می‌شود.
     44
     45* نمای کلی وضعیت کسب‌وکار (Overview)
     46* تحلیل روندها (Trends Analytics)
     47* تحلیل‌های پیشرفته‌ با فیلترهای متنوع
     48* دریافت خروجی آسان گزارش‌ها با فرمت‌ CSV یا PNG
     49
     50
     51## نحوه نصب و اتصال
     52* پلاگین را در بخش افزونه های پنل مدیریت خود جستجو کنید و گزینه نصب و فعال سازی را بزنید
     53* بعد از فعال سازی از منو کناری گزینه سکان را انتخاب کنید و با اطلاعات حساب کاربری سکان وارد شوید
     54* گزینه همگام سازی را بزنید تا اطلاعات فروشگاه شما برای سکان ارسال شود
     55* بعد از فعال سازی و ورود به حساب کاربری داده های فروشگاه شما به صورت خودکار با سکان همگام سازی می شود
    3656
    3757
     
    5171== Screenshots ==
    5272<ol>
    53     <li>تصویر محیط همگام سازی داده ها</li>
     73<li>screenShot-1</li>
     74<li>screenShot-2</li>
     75<li>screenShot-3</li>
     76<li>screenShot-4</li>
    5477</ol>
    5578
    5679== Changelog ==
    5780
     81= 1.2.0 =
     82* تغییر نحوه استخراج داده ها و بهبود عملکرد
     83* اضافه شدن لاگ ثبت خطاهای پیش آمده در روند همگام سازی
     84
    5885= 1.1.0 =
    5986* اضافه شدن همگام سازی خودکار
    60 
    6187
    6288= 1.0.0 =
     
    6490
    6591== Upgrade Notice ==
     92
     93= 1.2.0 =
     94* جداول میانی برای استخراج داده حذف شد و داده ها مستقیم از جداول ووکامرس استخراج و به سکان ارسال می شود
     95* اضافه شدن لاگ ثبت خطاهای پیش آمده در روند همگام سازی
    6696
    6797= 1.1.0 =
  • sokan-integration/trunk/uninstall.php

    r2681702 r2693175  
    11<?php
    22/**
    3 * @package SokanIntegration
    4 */
     3 * @package SokanIntegration
     4 */
    55
    66defined( 'ABSPATH' ) or die( 'No access!' );
    7 
    87
    98/**
     
    1110 * @since 1.0.0
    1211 */
    13 
    1412global $wpdb;
    15 
    16 
    17 
    18 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '%sokan%';" );
    19 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_brands" );
    20 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_customers" );
    21 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_invoices" );
    22 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_logs" );
    23 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_productcats" );
    24 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_products" );
    25 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sokan_integration_region" );
    26 
    27 
    28 
    29 
     13$log = "{$wpdb->prefix}".SKNG_PLUGIN_NAME."_logs";
     14$wpdb->query( "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '%sokan%';" );
     15$wpdb->query( "DROP TABLE IF EXISTS '$log'" );
    3016wp_cache_flush();
    31 
    32 
    33 
    34 
    35 
    36 
    37 
Note: See TracChangeset for help on using the changeset viewer.