Plugin Directory

Changeset 2735651


Ignore:
Timestamp:
06/01/2022 12:46:53 PM (4 years ago)
Author:
sokangroup
Message:

version 1.5.2

Location:
sokan-integration
Files:
18 added
3 edited

Legend:

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

    r2733673 r2735651  
    77 * Plugin Name: sokan Integration
    88 * Description:  افزونه ای برای استخراج تمامی اطلاعات ووکامرس مورد نیاز پلتفرم سکان
    9  * Version: 1.5.1
     9 * Version: 1.5.2
    1010 * Author: Sokan
    1111 * Author URI: https://Sokan.tech/
  • sokan-integration/trunk/include/classes/class-skng-db.php

    r2733685 r2735651  
    88class Skng_Sokan_db {
    99
    10     /**
    11     * @var Wpdb
    12     * @since 1.1.0
    13     */
    14     private wpdb $db;
    15 
    16     /**
    17     * array of filter for extract data from woocommerce tables
    18     * @var array
    19     * @since 1.2.0
    20     */
    21     private array $filters;
    22 
    23     /**
    24     * array of customer and region key name for search in woocommerce tables
    25     * @var array
    26     * @since 1.2.0
    27     */
    28     private array $order_attr = [
    29         'user_id'    => '_customer_user',
    30         'first_name' => '_billing_first_name',
    31         'last_name'  => '_billing_last_name',
    32         'city'       => '_billing_city',
    33         'state'      => '_billing_state',
    34         'country'    => '_billing_country',
    35         'phone'      => '_billing_phone',
    36         'email'      => '_billing_email',
    37     ];
    38 
    39     /**
    40     * array of region Code and name for replacing
    41     * @var array
    42     * @since 1.2.0
    43     */
    44     private array $states = array(
    45         'KHZ' => 'خوزستان',
    46         'THR' => 'تهران',
    47         'ILM' => 'ایلام',
    48         'BHR' => 'بوشهر',
    49         'ADL' => 'اردبیل',
    50         'ESF' => 'اصفهان',
    51         'YZD' => 'یزد',
    52         'KRH' => 'کرمانشاه',
    53         'KRN' => 'کرمان',
    54         'HDN' => 'همدان',
    55         'GZN' => 'قزوین',
    56         'ZJN' => 'زنجان',
    57         'LRS' => 'لرستان',
    58         'ABZ' => 'البرز',
    59         'EAZ' => 'آذربایجان شرقی',
    60         'WAZ' => 'آذربایجان غربی',
    61         'CHB' => 'چهارمحال و بختیاری',
    62         'SKH' => 'خراسان جنوبی',
    63         'RKH' => 'خراسان رضوی',
    64         'NKH' => 'خراسان شمالی',
    65         'SMN' => 'سمنان',
    66         'FRS' => 'فارس',
    67         'QHM' => 'قم',
    68         'KRD' => 'کردستان',
    69         'KBD' => 'کهگیلویه و بویراحمد',
    70         'GLS' => 'گلستان',
    71         'GIL' => 'گیلان',
    72         'MZN' => 'مازندران',
    73         'MKZ' => 'مرکزی',
    74         'HRZ' => 'هرمزگان',
    75         'SBN' => 'سیستان و بلوچستان',
    76     );
    77 
    78     public function __construct( $wpdp ) {
    79         $this->db         = $wpdp;
    80         $this->filters    = [
    81             'log_table'         => "{$wpdp->prefix}" . SKNG_PLUGIN_NAME . "_logs",
    82             'update_date'       => get_option( SKNG_PLUGIN_NAME . "_sync_date" ),
    83             'complete_status'   => get_option( SKNG_PLUGIN_NAME . '_sale_status' ),
    84             'refunded_status'   => get_option( SKNG_PLUGIN_NAME . '_refunded_status' ),
    85             'api_limitation'    => get_option( SKNG_PLUGIN_NAME . '_api_limitation' ),
    86             'customer_identity' => get_option( SKNG_PLUGIN_NAME . '_customer_identity' )
    87         ];
    88         $this->order_attr = apply_filters( "skng_set_orders_attr", $this->order_attr );
    89     }
    90 
    91     /**
    92     * return all available sokan api urls
    93     * @return array
    94     * @since 1.2.0
    95     */
    96     public function webServiceUrls(): array {
    97         return [
    98             'ارسال به نسخه آزمایشی' => "https://api-lab.sokan.tech/",
    99             'ارسال به نسخه دمو'     => "https://api-demo.sokan.tech/",
    100             'ارسال به نسخه اپ'      => "https://api-app.sokan.tech/",
    101         ];
    102     }
    103 
    104     /**
    105     * return all available customer identity value
    106     * @return array
    107     * @since 1.4.0
    108     */
    109     public function customerIdentities(): array {
    110         return [
    111             'شماره تلفن مشتریان'         => "phone",
    112             'کد کاربری مشتریان'          => "id",
    113             'نام و نام خانوادگی مشتریان' => "name",
    114         ];
    115     }
    116 
    117     /**
    118     * return all available sync mode
    119     * @return array
    120     * @since 1.4.0
    121     */
    122     public function syncModes(): array {
    123         return [
    124             'در پس زمینه (30 ثانیه بعد از تغییر وضعیت سفارش)' => "async",
    125             'همزمان با تغییر وضعیت سفارش'                     => "sync",
    126         ];
    127     }
    128 
    129     /**
    130     * reset last sync date and clear log table
    131     * @return void
    132     * @since 1.2.0
    133     */
    134     public function resetSyncDate() {
    135         $logTable = $this->filters['log_table'];
    136         update_option( SKNG_PLUGIN_NAME . '_sync_date', '' );
    137         $this->db->query( "TRUNCATE TABLE $logTable" );
    138     }
    139 
    140     /**
    141     * return all products and their brands and categories list
    142     *
    143     * @param $ids
    144     *
    145     * @return array
    146     * @since 1.3.0
    147     */
    148     public function getProducts( $ids ): array {
    149         $data = $this->db->get_results(
    150             "
     10    /**
     11    * @var Wpdb
     12    * @since 1.1.0
     13    */
     14    private wpdb $db;
     15
     16    /**
     17    * array of filter for extract data from woocommerce tables
     18    * @var array
     19    * @since 1.2.0
     20    */
     21    private array $filters;
     22
     23    /**
     24    * array of customer and region key name for search in woocommerce tables
     25    * @var array
     26    * @since 1.2.0
     27    */
     28    private array $order_attr = [
     29        'user_id'    => '_customer_user',
     30        'first_name' => '_billing_first_name',
     31        'last_name'  => '_billing_last_name',
     32        'city'       => '_billing_city',
     33        'state'      => '_billing_state',
     34        'country'    => '_billing_country',
     35        'phone'      => '_billing_phone',
     36        'email'      => '_billing_email',
     37    ];
     38
     39    /**
     40    * array of region Code and name for replacing
     41    * @var array
     42    * @since 1.2.0
     43    */
     44    private array $states = array(
     45        'KHZ' => 'خوزستان',
     46        'THR' => 'تهران',
     47        'ILM' => 'ایلام',
     48        'BHR' => 'بوشهر',
     49        'ADL' => 'اردبیل',
     50        'ESF' => 'اصفهان',
     51        'YZD' => 'یزد',
     52        'KRH' => 'کرمانشاه',
     53        'KRN' => 'کرمان',
     54        'HDN' => 'همدان',
     55        'GZN' => 'قزوین',
     56        'ZJN' => 'زنجان',
     57        'LRS' => 'لرستان',
     58        'ABZ' => 'البرز',
     59        'EAZ' => 'آذربایجان شرقی',
     60        'WAZ' => 'آذربایجان غربی',
     61        'CHB' => 'چهارمحال و بختیاری',
     62        'SKH' => 'خراسان جنوبی',
     63        'RKH' => 'خراسان رضوی',
     64        'NKH' => 'خراسان شمالی',
     65        'SMN' => 'سمنان',
     66        'FRS' => 'فارس',
     67        'QHM' => 'قم',
     68        'KRD' => 'کردستان',
     69        'KBD' => 'کهگیلویه و بویراحمد',
     70        'GLS' => 'گلستان',
     71        'GIL' => 'گیلان',
     72        'MZN' => 'مازندران',
     73        'MKZ' => 'مرکزی',
     74        'HRZ' => 'هرمزگان',
     75        'SBN' => 'سیستان و بلوچستان',
     76    );
     77
     78    public function __construct( $wpdp ) {
     79        $this->db         = $wpdp;
     80        $this->filters    = [
     81            'log_table'         => "{$wpdp->prefix}" . SKNG_PLUGIN_NAME . "_logs",
     82            'update_date'       => get_option( SKNG_PLUGIN_NAME . "_sync_date" ),
     83            'complete_status'   => get_option( SKNG_PLUGIN_NAME . '_sale_status' ),
     84            'refunded_status'   => get_option( SKNG_PLUGIN_NAME . '_refunded_status' ),
     85            'api_limitation'    => get_option( SKNG_PLUGIN_NAME . '_api_limitation' ),
     86            'customer_identity' => get_option( SKNG_PLUGIN_NAME . '_customer_identity' )
     87        ];
     88        $this->order_attr = apply_filters( "skng_set_orders_attr", $this->order_attr );
     89    }
     90
     91    /**
     92    * return all available sokan api urls
     93    * @return array
     94    * @since 1.2.0
     95    */
     96    public function webServiceUrls(): array {
     97        return [
     98            'ارسال به نسخه آزمایشی' => "https://api-lab.sokan.tech/",
     99            'ارسال به نسخه دمو'     => "https://api-demo.sokan.tech/",
     100            'ارسال به نسخه اپ'      => "https://api-app.sokan.tech/",
     101        ];
     102    }
     103
     104    /**
     105    * return all available customer identity value
     106    * @return array
     107    * @since 1.4.0
     108    */
     109    public function customerIdentities(): array {
     110        return [
     111            'شماره تلفن مشتریان'         => "phone",
     112            'کد کاربری مشتریان'          => "id",
     113            'نام و نام خانوادگی مشتریان' => "name",
     114        ];
     115    }
     116
     117    /**
     118    * return all available sync mode
     119    * @return array
     120    * @since 1.4.0
     121    */
     122    public function syncModes(): array {
     123        return [
     124            'در پس زمینه (30 ثانیه بعد از تغییر وضعیت سفارش)' => "async",
     125            'همزمان با تغییر وضعیت سفارش'                     => "sync",
     126        ];
     127    }
     128
     129    /**
     130    * reset last sync date and clear log table
     131    * @return void
     132    * @since 1.2.0
     133    */
     134    public function resetSyncDate() {
     135        $logTable = $this->filters['log_table'];
     136        update_option( SKNG_PLUGIN_NAME . '_sync_date', '' );
     137        $this->db->query( "TRUNCATE TABLE $logTable" );
     138    }
     139
     140    /**
     141    * return all products and their brands and categories list
     142    *
     143    * @param $ids
     144    *
     145    * @return array
     146    * @since 1.3.0
     147    */
     148    public function getProducts( $ids ): array {
     149        $data = $this->db->get_results(
     150            "
    151151           SELECT ID as id , post_title  ,
    152152           {$this->db->prefix}terms.term_id ,
     
    170170           ORDER BY {$this->db->prefix}term_taxonomy.parent DESC
    171171            "
    172             , ARRAY_A
    173         );
    174 
    175         $categories = $this->db->get_results(
    176             "
     172            , ARRAY_A
     173        );
     174
     175        $categories = $this->db->get_results(
     176            "
    177177           SELECT * FROM `{$this->db->prefix}term_taxonomy`
    178178           JOIN `{$this->db->prefix}terms`
     
    180180           WHERE `{$this->db->prefix}term_taxonomy`.taxonomy = 'product_cat' 
    181181            ", ARRAY_A
    182         );
    183 
    184         $products       = [];
    185         $categories_ids = array_column( $categories, 'term_id' );
    186         $data           = apply_filters( "skng_before_validate_product_attr", $data );
    187         foreach ( $data as $item ) {
    188             $product_id                      = $item['id'];
    189             $products[ $product_id ]['name'] = $item['post_title'];
    190             if ( $item['taxonomy'] == 'product_cat' ) {
    191                 if ( isset( $products[ $product_id ]['categories'] ) ) continue;
    192 
    193                 $parent = $item['parent'];
    194                 $cats   = [ $item['name'] ];
    195                 for ( $x = 0; $x <= 8; $x ++ ) {
    196                     $key = array_search( $parent, $categories_ids );
     182        );
     183
     184        $products       = [];
     185        $categories_ids = array_column( $categories, 'term_id' );
     186        $data           = apply_filters( "skng_before_validate_product_attr", $data );
     187        foreach ( $data as $item ) {
     188            $product_id                      = $item['id'];
     189            $products[ $product_id ]['name'] = $item['post_title'];
     190            if ( $item['taxonomy'] == 'product_cat' ) {
     191                if ( isset( $products[ $product_id ]['categories'] ) ) continue;
     192
     193                $parent = $item['parent'];
     194                $cats   = [ $item['name'] ];
     195                for ( $x = 0; $x <= 8; $x ++ ) {
     196                    $key = array_search( $parent, $categories_ids );
    197197                    if ($key === false) break;
    198198                    array_push( $cats, $categories[ $key ]['name'] );
    199199                    $parent = $categories[ $key ]['parent'];
    200                 }
    201                 $products[ $product_id ]['categories'] = array_reverse( $cats );
    202             }
    203             if ( strpos( $item['taxonomy'], "brand" ) != false or strpos( $item['taxonomy'], "برند" ) != false ) {
    204                 $products[ $product_id ]['brand'] = $item['name'];
    205                 continue;
    206             }
    207             if ( strpos( $item['taxonomy'], "weight" ) != false or strpos( $item['taxonomy'], "وزن" ) != false ) {
    208                 $products[ $product_id ]['weight'] = $item['name'];
    209             }
    210         }
    211 
    212         return apply_filters( "skng_get_all_product_filter", $products );
    213     }
    214 
    215 
    216     /**
    217     * return all deleted product names
    218     *
    219     * @param $ids
    220     *
    221     * @return array
    222     * @since 1.5.0
    223     */
    224     public function getDeletedProducts( $ids ): array {
    225         $ids      = implode( "','", $ids );
    226         $products = $this->db->get_results(
    227             "SELECT * FROM  `{$this->db->prefix}woocommerce_order_items`
     200                }
     201                $products[ $product_id ]['categories'] = array_reverse( $cats );
     202            }
     203            if ( strpos( $item['taxonomy'], "brand" ) != false or strpos( $item['taxonomy'], "برند" ) != false ) {
     204                $products[ $product_id ]['brand'] = $item['name'];
     205                continue;
     206            }
     207            if ( strpos( $item['taxonomy'], "weight" ) != false or strpos( $item['taxonomy'], "وزن" ) != false ) {
     208                $products[ $product_id ]['weight'] = $item['name'];
     209            }
     210        }
     211
     212        return apply_filters( "skng_get_all_product_filter", $products );
     213    }
     214
     215
     216    /**
     217    * return all deleted product names
     218    *
     219    * @param $ids
     220    *
     221    * @return array
     222    * @since 1.5.0
     223    */
     224    public function getDeletedProducts( $ids ): array {
     225        $ids      = implode( "','", $ids );
     226        $products = $this->db->get_results(
     227            "SELECT * FROM  `{$this->db->prefix}woocommerce_order_items`
    228228                   WHERE  `{$this->db->prefix}woocommerce_order_items`.order_item_id
    229229                   IN ('$ids')",
    230             ARRAY_A
    231         );
    232         $result   = [];
    233         foreach ( $products as $product ) {
    234             $result[ $product['order_item_id'] ] = $product['order_item_name'];
    235         }
    236 
    237         return $result;
    238     }
    239 
    240     /**
    241     * return all order based on filters
    242     * @return array invoices
    243     * return list of invoices
    244     * @since 1.1.0
    245     */
    246     public function getAllOrders(): array {
    247         $date              = $this->filters['update_date'];
    248         $ref_status        = $this->filters['refunded_status'];
    249         $customer_identity = $this->filters['customer_identity'];
    250 
    251         if ( count( $ids = $this->getAvailableOrderIds() ) == 0 ) {
    252             return [ 'order' => [], 'date' => $date ];
    253         }
    254 
    255         $all_invoices = $this->getOrderData( $ids );
    256         $new_orders   = [];
    257         $product_ids  = [];
    258 
    259         foreach ( $all_invoices as $order_key => $value ) {
    260 
    261             $date           = $value['modified_date'] ?? $date;
    262             $order_date     = $value['post_date'] ?? $date;
    263             $first_name     = $value[ $this->order_attr['first_name'] ] ?? "مشتری";
    264             $last_name      = $value[ $this->order_attr['last_name'] ] ?? "نامشخص";
    265             $customer_name  = trim( trim( $first_name, " " ) . " " . trim( $last_name, " " ), " " );
    266             $customer_phone = $this->convertToEnNumbers( $value[ $this->order_attr['phone'] ] ?? "" );
    267 
    268             if ( preg_match( '/^(?:98|\+98|0098|0|\+980|00980)?9[0-9]{9}/', $customer_phone, $_phone, PREG_OFFSET_CAPTURE ) ) {
    269                 $_phone         = $_phone[0][0];
    270                 $_phone         = str_replace( "+980", '+98', $_phone );
    271                 $_phone         = str_replace( "00980", '+98', $_phone );
    272                 $customer_phone = preg_replace( '/^(?:98|\+98|0098|0)/', "0", $_phone );
    273             }
    274 
    275             $customer_id = $value[ $this->order_attr['user_id'] ] ?? ( empty( $customer_phone ) ? $customer_name : $customer_phone );
    276 
    277             if ( $customer_identity == 'phone' and ! empty( $customer_phone ) ) {
    278                 $customer_id = trim( str_replace( "0", "", $customer_phone ), " " );
    279             } elseif ( $customer_identity == 'name' and $customer_name != "مشتری نامشخص" ) {
    280                 $customer_id = $customer_name;
    281             } elseif ( $customer_id == 0 ) {
    282                 $customer_id = $customer_name != "مشتری نامشخص" ? $customer_name : $order_key;
    283             }
    284 
    285             $state = $value[ $this->order_attr['state'] ] ?? "نامشخص";
    286             $city  = $value[ $this->order_attr['city'] ] ?? "نامشخص";
    287 
    288             if ( ! isset( $value['items'] ) and isset( $value['_order_total'] ) ) {
    289                 $value['items'][ $value['_order_total'] ]['_fee_amount'] = $value['_order_total'];
    290             } elseif ( ! isset( $value['items'] ) ) {
    291                 continue;
    292             }
    293 
    294             foreach ( $value['items'] as $item_key => $item ) {
    295 
    296                 $qty          = $item['_qty'] ?? 1;
    297                 $qty          = abs( $qty );
    298                 $discount     = 0;
    299                 $unit_price   = 0;
    300                 $total        = 0;
    301                 $product_id   = 'Undefined Product';
    302                 $product_type = 'SERVICE';
    303 
    304                 if ( isset( $item['_line_subtotal'] ) ) {
    305 
    306                     if ( $item['_line_subtotal'] > 0 ) {
    307                         $unit_price = $item['_line_subtotal'] / $qty;
    308                     } else {
    309                         $unit_price = $item['_line_total'] / $qty;
    310                     }
    311                     if ( $item['_line_total'] != 0 ) {
    312                         $total = $item['_line_total'] / $qty;
    313                     }
    314                     $discount     = ( $unit_price - $total ) * $qty;
    315                     $product_type = 'PRODUCT';
    316 
    317                     if ( ! empty( $item['_product_id'] ) ) {
    318                         $product_id                 = $item['_product_id'];
    319                         $product_ids[ $product_id ] = $product_id;
    320                     }
    321                 } else if ( isset( $item['cost'] ) ) {
    322 
    323                     $unit_price = (int) $item['cost'];
    324                     $product_id = 'هزینه ارسال';
    325 
    326                 } else if ( isset( $item['_fee_amount'] ) ) {
    327                     $unit_price = (int) $item['_fee_amount'];
    328                 }
    329 
    330                 $weight = $item['pa_weight'] ?? 0;
    331 
    332                 $order = [
    333                     'item_id'       => (string) $item_key,
    334                     'invoice_id'    => (string) $order_key,
    335                     'date'          => (string) $order_date,
    336                     'unit_price'    => abs( (int) $unit_price ),
    337                     'type'          => "SALES",
    338                     'quantity'      => (int) $qty,
    339                     'discount'      => (int) $discount,
    340                     'weight'        => (int) $weight,
    341                     'customer_id'   => $customer_id,
    342                     'customer_name' => $customer_name,
    343                     'region0'       => "ایران",
    344                     'region1'       => $this->getRegionName( $state ),
    345                     'region2'       => $this->getRegionName( $city ),
    346                     'sku_id'        => $product_id,
    347                     'product_name'  => $product_id,
    348                     'product_type'  => $product_type
    349                 ];
    350 
    351                 if ( preg_match( '/^(?:98|\+98|0098|0)?9[0-9]{9}$/', $customer_phone ) ) {
    352                     $order['customer_phone_number'] = $customer_phone;
    353                 }
    354 
    355                 array_push( $new_orders, $order );
    356 
    357                 if ( $value['status'] == $ref_status ) {
    358                     $refund_order             = $order;
    359                     $refund_order['item_id']  = $refund_order['item_id'] . "_refunded";
    360                     $refund_order['quantity'] = - $refund_order['quantity'];
    361                     $refund_order['discount'] = - $refund_order['discount'];
    362                     $refund_order['type']     = "RETURN";
    363                     array_push( $new_orders, $refund_order );
    364                 }
    365             }
    366         }
    367 
    368         $all_products = $this->getProducts( $product_ids );
    369         $order_ids    = [];
    370         foreach ( $new_orders as $key => $order_item ) {
    371 
    372             if ( isset( $all_products[ $order_item['sku_id'] ] ) ) {
    373 
    374                 $product                            = $all_products[ $order_item['sku_id'] ];
    375                 $new_orders[ $key ]['product_name'] = $product['name'];
    376 
    377                 if ( isset( $product['brand'] ) ) {
    378                     $new_orders[ $key ]['product_brand0'] = $product['brand'];
    379                 }
    380                 if ( isset( $product['categories'] ) ) {
    381                     foreach ( $product['categories'] as $cat_key => $name ) {
    382                         $new_orders[ $key ][ 'product_category' . $cat_key ] = $name;
    383                     }
    384                 }
    385                 if ( $order_item['weight'] == 0 and isset( $product['weight'] ) ) {
    386                     $new_orders[ $key ]['weight'] = (int) $product['weight'];
    387                 }
    388             } elseif ( $order_item['sku_id'] == 'Undefined Product' and $order_item['sku_id'] != 'هزینه ارسال' ) {
    389                 $order_ids[ $key ] = strval( $order_item['item_id'] );
    390             }
    391         }
    392 
    393         if ( count( $order_ids ) > 0 ) {
    394             $deletedProduct = $this->getDeletedProducts( $order_ids );
    395             foreach ( $deletedProduct as $id => $name ) {
    396                 $key = array_search( $id, array_column( $new_orders, 'item_id' ) );
    397                 if ( $key >= 0 ) {
    398                     $new_orders[ $key ]['sku_id']            = $name;
    399                     $new_orders[ $key ]['product_name']      = $name;
    400                     $new_orders[ $key ]['product_category0'] = 'محصولات حذف شده';
    401                 }
    402             }
    403         }
    404 
    405         $orders_for_sync = array_merge( $this->getErrorLogs(), $new_orders );
    406 
    407         return [ 'order' => $orders_for_sync, 'date' => $date ];
    408     }
    409 
    410     /**
    411     * Each time a data is not synchronized with the sokan, it is logged
    412     * @return void
    413     * @since 1.1.0
    414     */
    415     public function saveErrors( $errors ) {
    416         $logTable = $this->filters['log_table'];
    417         $this->db->query( " INSERT ignore INTO `$logTable`(`entity_id`,`error`,`payload`) VALUES " . implode( ',', $errors ) . ";" );
    418     }
    419 
    420     /**
    421     * get all error logs saved on db for sync again
    422     * @return array
    423     * @since 1.1.0
    424     */
    425     private function getErrorLogs(): array {
    426         $logTable = $this->filters['log_table'];
    427         $result   = [];
    428         $res      = $this->db->get_results( " SELECT * FROM `$logTable` ORDER BY `date`", ARRAY_A );
    429 
    430         if ( count( $res ) == 0 ) {
    431             return $result;
    432         }
    433 
    434         foreach ( $res as $log ) {
    435             if ( ! empty( $log['payload'] ) ) {
    436                 array_push( $result, json_decode( $log['payload'], true ) );
    437             }
    438         }
    439         $this->db->query( "TRUNCATE TABLE $logTable" );
    440 
    441         return $result;
    442     }
    443 
    444     /**
    445     * get list of order ids for sync based on date and status filters
    446     * @return array
    447     * @since 1.2.0
    448     */
    449     private function getAvailableOrderIds(): array {
    450 
    451         $date           = $this->filters['update_date'];
    452         $com_status     = $this->filters['complete_status'];
    453         $ref_status     = $this->filters['refunded_status'];
    454         $api_limitation = $this->filters['api_limitation'];
    455 
    456         $ids = $this->db->get_results(
    457             "SELECT `{$this->db->prefix}posts`.ID as id FROM `{$this->db->prefix}posts`
     230            ARRAY_A
     231        );
     232        $result   = [];
     233        foreach ( $products as $product ) {
     234            $result[ $product['order_item_id'] ] = $product['order_item_name'];
     235        }
     236
     237        return $result;
     238    }
     239
     240    /**
     241    * return all order based on filters
     242    * @return array invoices
     243    * return list of invoices
     244    * @since 1.1.0
     245    */
     246    public function getAllOrders(): array {
     247        $date              = $this->filters['update_date'];
     248        $ref_status        = $this->filters['refunded_status'];
     249        $customer_identity = $this->filters['customer_identity'];
     250
     251        if ( count( $ids = $this->getAvailableOrderIds() ) == 0 ) {
     252            return [ 'order' => [], 'date' => $date ];
     253        }
     254
     255        $all_invoices = $this->getOrderData( $ids );
     256        $new_orders   = [];
     257        $product_ids  = [];
     258
     259        foreach ( $all_invoices as $order_key => $value ) {
     260
     261            $date           = $value['modified_date'] ?? $date;
     262            $order_date     = $value['post_date'] ?? $date;
     263            $first_name     = $value[ $this->order_attr['first_name'] ] ?? "مشتری";
     264            $last_name      = $value[ $this->order_attr['last_name'] ] ?? "نامشخص";
     265            $customer_name  = trim( trim( $first_name, " " ) . " " . trim( $last_name, " " ), " " );
     266            $customer_phone = $this->convertToEnNumbers( $value[ $this->order_attr['phone'] ] ?? "" );
     267
     268            if ( preg_match( '/^(?:98|\+98|0098|0|\+980|00980)?9[0-9]{9}/', $customer_phone, $_phone, PREG_OFFSET_CAPTURE ) ) {
     269                $_phone         = $_phone[0][0];
     270                $_phone         = str_replace( "+980", '+98', $_phone );
     271                $_phone         = str_replace( "00980", '+98', $_phone );
     272                $customer_phone = preg_replace( '/^(?:98|\+98|0098|0)/', "0", $_phone );
     273            }
     274
     275            $customer_id = $value[ $this->order_attr['user_id'] ] ?? ( empty( $customer_phone ) ? $customer_name : $customer_phone );
     276
     277            if ( $customer_identity == 'phone' and ! empty( $customer_phone ) ) {
     278                $customer_id = trim( str_replace( "0", "", $customer_phone ), " " );
     279            } elseif ( $customer_identity == 'name' and $customer_name != "مشتری نامشخص" ) {
     280                $customer_id = $customer_name;
     281            } elseif ( $customer_id == 0 ) {
     282                $customer_id = $customer_name != "مشتری نامشخص" ? $customer_name : $order_key;
     283            }
     284
     285            $state = $value[ $this->order_attr['state'] ] ?? "نامشخص";
     286            $city  = $value[ $this->order_attr['city'] ] ?? "نامشخص";
     287
     288            if ( ! isset( $value['items'] ) and isset( $value['_order_total'] ) ) {
     289                $value['items'][ $value['_order_total'] ]['_fee_amount'] = $value['_order_total'];
     290            } elseif ( ! isset( $value['items'] ) ) {
     291                continue;
     292            }
     293
     294            foreach ( $value['items'] as $item_key => $item ) {
     295
     296                $qty          = $item['_qty'] ?? 1;
     297                $qty          = abs( $qty );
     298                $discount     = 0;
     299                $unit_price   = 0;
     300                $total        = 0;
     301                $product_id   = 'Undefined Product';
     302                $product_type = 'SERVICE';
     303
     304                if ( isset( $item['_line_subtotal'] ) ) {
     305
     306                    if ( $item['_line_subtotal'] > 0 ) {
     307                        $unit_price = $item['_line_subtotal'] / $qty;
     308                    } else {
     309                        $unit_price = $item['_line_total'] / $qty;
     310                    }
     311                    if ( $item['_line_total'] != 0 ) {
     312                        $total = $item['_line_total'] / $qty;
     313                    }
     314                    $discount     = ( $unit_price - $total ) * $qty;
     315                    $product_type = 'PRODUCT';
     316
     317                    if ( ! empty( $item['_product_id'] ) ) {
     318                        $product_id                 = $item['_product_id'];
     319                        $product_ids[ $product_id ] = $product_id;
     320                    }
     321                } else if ( isset( $item['cost'] ) ) {
     322
     323                    $unit_price = (int) $item['cost'];
     324                    $product_id = 'هزینه ارسال';
     325
     326                } else if ( isset( $item['_fee_amount'] ) ) {
     327                    $unit_price = (int) $item['_fee_amount'];
     328                }
     329
     330                $weight = $item['pa_weight'] ?? 0;
     331
     332                $order = [
     333                    'item_id'       => (string) $item_key,
     334                    'invoice_id'    => (string) $order_key,
     335                    'date'          => (string) $order_date,
     336                    'unit_price'    => abs( (int) $unit_price ),
     337                    'type'          => "SALES",
     338                    'quantity'      => (int) $qty,
     339                    'discount'      => (int) $discount,
     340                    'weight'        => (int) $weight,
     341                    'customer_id'   => $customer_id,
     342                    'customer_name' => $customer_name,
     343                    'region0'       => "ایران",
     344                    'region1'       => $this->getRegionName( $state ),
     345                    'region2'       => trim( $city, " " ),
     346                    'sku_id'        => $product_id,
     347                    'product_name'  => $product_id,
     348                    'product_type'  => $product_type
     349                ];
     350
     351                if ( preg_match( '/^(?:98|\+98|0098|0)?9[0-9]{9}$/', $customer_phone ) ) {
     352                    $order['customer_phone_number'] = $customer_phone;
     353                }
     354
     355                array_push( $new_orders, $order );
     356
     357                if ( $value['status'] == $ref_status ) {
     358                    $refund_order             = $order;
     359                    $refund_order['item_id']  = $refund_order['item_id'] . "_refunded";
     360                    $refund_order['quantity'] = - $refund_order['quantity'];
     361                    $refund_order['discount'] = - $refund_order['discount'];
     362                    $refund_order['type']     = "RETURN";
     363                    array_push( $new_orders, $refund_order );
     364                }
     365            }
     366        }
     367
     368        $all_products = $this->getProducts( $product_ids );
     369        $order_ids    = [];
     370        foreach ( $new_orders as $key => $order_item ) {
     371
     372            if ( isset( $all_products[ $order_item['sku_id'] ] ) ) {
     373
     374                $product                            = $all_products[ $order_item['sku_id'] ];
     375                $new_orders[ $key ]['product_name'] = $product['name'];
     376
     377                if ( isset( $product['brand'] ) ) {
     378                    $new_orders[ $key ]['product_brand0'] = $product['brand'];
     379                }
     380                if ( isset( $product['categories'] ) ) {
     381                    foreach ( $product['categories'] as $cat_key => $name ) {
     382                        $new_orders[ $key ][ 'product_category' . $cat_key ] = $name;
     383                    }
     384                }
     385                if ( $order_item['weight'] == 0 and isset( $product['weight'] ) ) {
     386                    $new_orders[ $key ]['weight'] = (int) $product['weight'];
     387                }
     388            } elseif ( $order_item['sku_id'] == 'Undefined Product' and $order_item['sku_id'] != 'هزینه ارسال' ) {
     389                $order_ids[ $key ] = strval( $order_item['item_id'] );
     390            }
     391        }
     392
     393        if ( count( $order_ids ) > 0 ) {
     394            $deletedProduct = $this->getDeletedProducts( $order_ids );
     395            foreach ( $deletedProduct as $id => $name ) {
     396                $key = array_search( $id, array_column( $new_orders, 'item_id' ) );
     397                if ( $key >= 0 ) {
     398                    $new_orders[ $key ]['sku_id']            = $name;
     399                    $new_orders[ $key ]['product_name']      = $name;
     400                    $new_orders[ $key ]['product_category0'] = 'محصولات حذف شده';
     401                }
     402            }
     403        }
     404
     405        $orders_for_sync = array_merge( $this->getErrorLogs(), $new_orders );
     406
     407        return [ 'order' => $orders_for_sync, 'date' => $date ];
     408    }
     409
     410    /**
     411    * Each time a data is not synchronized with the sokan, it is logged
     412    * @return void
     413    * @since 1.1.0
     414    */
     415    public function saveErrors( $errors ) {
     416        $logTable = $this->filters['log_table'];
     417        $this->db->query( " INSERT ignore INTO `$logTable`(`entity_id`,`error`,`payload`) VALUES " . implode( ',', $errors ) . ";" );
     418    }
     419
     420    /**
     421    * get all error logs saved on db for sync again
     422    * @return array
     423    * @since 1.1.0
     424    */
     425    private function getErrorLogs(): array {
     426        $logTable = $this->filters['log_table'];
     427        $result   = [];
     428        $res      = $this->db->get_results( " SELECT * FROM `$logTable` ORDER BY `date`", ARRAY_A );
     429
     430        if ( count( $res ) == 0 ) {
     431            return $result;
     432        }
     433
     434        foreach ( $res as $log ) {
     435            if ( ! empty( $log['payload'] ) ) {
     436                array_push( $result, json_decode( $log['payload'], true ) );
     437            }
     438        }
     439        $this->db->query( "TRUNCATE TABLE $logTable" );
     440
     441        return $result;
     442    }
     443
     444    /**
     445    * get list of order ids for sync based on date and status filters
     446    * @return array
     447    * @since 1.2.0
     448    */
     449    private function getAvailableOrderIds(): array {
     450
     451        $date           = $this->filters['update_date'];
     452        $com_status     = $this->filters['complete_status'];
     453        $ref_status     = $this->filters['refunded_status'];
     454        $api_limitation = $this->filters['api_limitation'];
     455
     456        $ids = $this->db->get_results(
     457            "SELECT `{$this->db->prefix}posts`.ID as id FROM `{$this->db->prefix}posts`
    458458                   WHERE `{$this->db->prefix}posts`.post_status IN ('$com_status' , '$ref_status')
    459459                   AND `{$this->db->prefix}posts`.post_modified > '$date'
    460460                   GROUP BY `{$this->db->prefix}posts`.ID
    461461                   ORDER BY `{$this->db->prefix}posts`.post_modified LIMIT  $api_limitation ",
    462             ARRAY_A
    463         );
    464 
    465         return apply_filters( "skng_get_all_order_ids_filter", array_column( $ids, 'id' ) );
    466     }
    467 
    468     /**
    469     * get order data of given id list
    470     *
    471     * @param $ids
    472     *
    473     * @return array
    474     * @since 1.2.0
    475     */
    476     private function getOrderData( $ids ): array {
    477 
    478         $attr_copy = $this->order_attr;
    479         array_push( $attr_copy, '_order_total' );
    480         $attr = implode( "','", $attr_copy );
    481 
    482         $all = $this->db->get_results( "
     462            ARRAY_A
     463        );
     464
     465        return apply_filters( "skng_get_all_order_ids_filter", array_column( $ids, 'id' ) );
     466    }
     467
     468    /**
     469    * get order data of given id list
     470    *
     471    * @param $ids
     472    *
     473    * @return array
     474    * @since 1.2.0
     475    */
     476    private function getOrderData( $ids ): array {
     477
     478        $attr_copy = $this->order_attr;
     479        array_push( $attr_copy, '_order_total' );
     480        $attr = implode( "','", $attr_copy );
     481
     482        $all = $this->db->get_results( "
    483483         (SELECT `{$this->db->prefix}woocommerce_order_items`.order_item_id as item_id ,
    484484         `{$this->db->prefix}woocommerce_order_items`.order_id as order_id,
     
    513513          ", ARRAY_A );
    514514
    515         $all_invoices = [];
    516         foreach ( $all as $value ) {
    517 
    518             if ( in_array( $value['meta_key'], $this->order_attr ) ) {
    519                 if ( ! ctype_space( $value['meta_value'] ) and ! empty( $value['meta_value'] ) ) {
    520                     $all_invoices[ $value['order_id'] ][ $value['meta_key'] ] = $value['meta_value'];
    521                 }
    522                 continue;
    523             }
    524 
    525             $all_invoices[ $value['order_id'] ]['modified_date'] = $value['modified_date'];
    526             $all_invoices[ $value['order_id'] ]['post_date']     = $value['post_date'];
    527             $all_invoices[ $value['order_id'] ]['status']        = $value['order_status'];
    528 
    529             if ( $value['meta_key'] == '_order_total' ) {
    530                 $all_invoices[ $value['order_id'] ]['_order_total'] = $value['meta_value'];
    531                 continue;
    532             }
    533 
    534             $all_invoices[ $value['order_id'] ]['items'][ $value['item_id'] ][ $value['meta_key'] ] = $value['meta_value'];
    535 
    536         }
    537 
    538         return apply_filters( "skng_get_all_order_data_filter", $all_invoices );
    539     }
    540 
    541     /**
    542      * return persian name of given state key
    543      *
    544      * @param $state
    545      *
    546      * @return string
    547      * @since 1.2.0
    548      */
    549     private function getRegionName( $state ): string {
    550         $symbols = array(
    551             "استان",
    552             "شهرستان",
    553             "مقدس",
    554             "شهر",
    555             "روستا",
    556             ",",
    557             ".",
    558             "،",
    559             '!',
    560             '"',
    561             '#',
    562             '$',
    563             '%',
    564             '&',
    565             '(',
    566             ')',
    567             '*',
    568             '+',
    569             ',',
    570             '-',
    571             '.',
    572             '/',
    573             ':',
    574             ';',
    575             '<',
    576             '>',
    577             '=',
    578             '?',
    579             '@',
    580             '[',
    581             ']',
    582             '^',
    583             '_',
    584             '{',
    585             '}',
    586             '|',
    587             '~',
    588             '`'
    589         );
    590         $state   = str_replace( $symbols, "", $state );
    591 
    592         if ( isset( $this->states[ $state ] ) ) {
    593             return trim( $this->states[ $state ], " " );
    594         }
    595 
    596         return trim( $state, " " );
    597     }
    598 
    599     private function convertToEnNumbers( $string ) {
    600         if ( empty( $string ) ) {
    601             return "";
    602         }
    603         $string  = str_replace( ' ', '', $string );
    604         $persian = [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ];
    605         $english = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
    606         $string  = str_replace( $persian, $english, $string );
    607 
    608         return filter_var( $string, FILTER_SANITIZE_NUMBER_INT );
    609     }
     515        $all_invoices = [];
     516        foreach ( $all as $value ) {
     517
     518            if ( in_array( $value['meta_key'], $this->order_attr ) ) {
     519                if ( ! ctype_space( $value['meta_value'] ) and ! empty( $value['meta_value'] ) ) {
     520                    $all_invoices[ $value['order_id'] ][ $value['meta_key'] ] = $value['meta_value'];
     521                }
     522                continue;
     523            }
     524
     525            $all_invoices[ $value['order_id'] ]['modified_date'] = $value['modified_date'];
     526            $all_invoices[ $value['order_id'] ]['post_date']     = $value['post_date'];
     527            $all_invoices[ $value['order_id'] ]['status']        = $value['order_status'];
     528
     529            if ( $value['meta_key'] == '_order_total' ) {
     530                $all_invoices[ $value['order_id'] ]['_order_total'] = $value['meta_value'];
     531                continue;
     532            }
     533
     534            $all_invoices[ $value['order_id'] ]['items'][ $value['item_id'] ][ $value['meta_key'] ] = $value['meta_value'];
     535
     536        }
     537
     538        return apply_filters( "skng_get_all_order_data_filter", $all_invoices );
     539    }
     540
     541    /**
     542     * return persian name of given state key
     543     *
     544     * @param $state
     545     *
     546     * @return string
     547     * @since 1.2.0
     548     */
     549    private function getRegionName( $state ): string {
     550        $state = str_replace("استان", "", $state);
     551        $state = str_replace("شهرستان", "", $state);
     552        $state = str_replace("مقدس", "", $state);
     553        $state = str_replace(",", "", $state);
     554        $state = str_replace(".", "", $state);
     555        $state = str_replace("،", "", $state);
     556
     557        if ( isset( $this->states[ $state ] ) ) {
     558            return trim( $this->states[ $state ], " " );
     559        }
     560
     561        return trim( $state, " " );
     562    }
     563
     564    private function convertToEnNumbers( $string ) {
     565        if ( empty( $string ) ) {
     566            return "";
     567        }
     568        $string  = str_replace( ' ', '', $string );
     569        $persian = [ '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' ];
     570        $english = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
     571        $string  = str_replace( $persian, $english, $string );
     572
     573        return filter_var( $string, FILTER_SANITIZE_NUMBER_INT );
     574    }
    610575
    611576}
  • sokan-integration/trunk/readme.txt

    r2733673 r2735651  
    55Tested up to: 5.9
    66Donate link: http://sokan.tech/
    7 Stable tag: 1.5.1
     7Stable tag: 1.5.2
    88Requires PHP: 7.0
    99License: GPLv2 or later
     
    7979== Changelog ==
    8080
     81= 1.5.2 =
     82* بهبود عملکرد
     83
     84
    8185= 1.5.1 =
    8286* بهبود عملکرد
     
    126130== Upgrade Notice ==
    127131
     132= 1.5.2 =
     133* بهبود عملکرد
     134
    128135= 1.5.1 =
    129136* بهبود عملکرد
Note: See TracChangeset for help on using the changeset viewer.