<?php
class Common_UploadData
{

    public static function readUploadFile($fileName, $filePath)
    {
        $pathinfo = pathinfo($fileName);
        $fileData = array();

        if (isset($pathinfo["extension"]) && $pathinfo["extension"] == "xls") {
            $fileData = Common_Upload::readEXCEL($filePath);
        }
        $result = array();
        if ($fileData) {
            foreach ($fileData[0] as $key => $value) {
                if (isset($columnMap[$value])) {
                    $fileData[0][$key] = $columnMap[$value];
                }
            }
            foreach ($fileData as $key => $value) {
                if ($key == 0) {
                    continue;
                }
                foreach ($value as $vKey => $vValue) {
                    if ($fileData[0][$vKey] == "") continue;
                    /*     $vValue = htmlspecialchars($vValue);
                     $vValue = str_replace(chr(10), "<br>", $vValue);
                       $vValue = str_replace(chr(32), "&nbsp;", $vValue);*/
                    $result[$key][$fileData[0][$vKey]] = $vValue;
                }
            }
        }
        return $result;
    }

    public static function orderKey()
    {
        $orderKeys = array(
            'TrackingNumber' => '',
            'ReferenceNo' => '',
            'Shipping Method' => '',
            'Country' => '',
            'First Name' => '',
            'Last Name' => '',
            'WarehouseCode' => '',
            'Address1' => '',
            'Address2' => '',
            'City' => '',
            'State/Provice' => '',
            'Postalcode' => '',
            'Email' => '',
            'Company' => '',
            'PhoneNo' => '',
        );
        return $orderKeys;
    }

    /**
     * @批量导入订单入口
     * @param $fileName
     * @param $filePath
     * @param string $customerCode
     * @return array
     */
    public static function uploadOrders($fileName, $filePath, $customerCode = 'EC001')
    {
        $result = array('state' => 0, 'errorMsg' => array(), 'message' => '');
        $fileData = self::readUploadFile($fileName, $filePath);
        if (!isset($fileData[1]) || !is_array($fileData[1])) {
            $result['errorMsg'] = array('上传失败，无法解析文件内容;');
            return $result;
        }
        $orderData = $orderArr = $smArr = $warehouseArr = $productQtyArr = $errorArr = array();
        $orderKeys = self::orderKey();
        foreach ($fileData as $key => $val) {
            if (count($val) < 10) {
                $errorArr[] = '第 ' . $key . ' 行,' . '数据异常.';
                continue;
            }
            //清除空值
            $filerArr = array_filter($val);
            //  $orderData[$key] = $filerArr;
            foreach ($orderKeys as $ok => $ov) {
                $orderData[$key][$ok] = isset($filerArr[$ok]) ? $filerArr[$ok] : '';
            }

            if (!empty($val['ReferenceNo'])) {
                if (!in_array($val['ReferenceNo'], $orderArr)) {
                    $orderArr[] = $val['ReferenceNo'];
                } else {
                    $errorArr[] = '第 ' . $key . ' 行,' . '参考号：' . $val['ReferenceNo'] . ' 不允许重复.';
                    continue;
                }
                //验证数据
                $orderRow = Service_Orders::getByCondition(array('reference_no' => $val['ReferenceNo'], 'customer_code' => $customerCode), '*');
                if (!empty($orderRow)) {
                    $errorArr[] = '第 ' . $key . ' 行,' . '参考号：' . $val['ReferenceNo'] . ' 已存在.';
                    continue;
                }
            }

            //国家
            $countryCode = substr($val['Country'], 0, 2);
            $countryRow = Service_Country::getByField($countryCode, 'country_code');
            if (empty($countryRow)) {
                $errorArr[] = '第 ' . $key . ' 行,' . 'Country：' . $val['Country'] . ' 不存在.';
                continue;
            }
            $orderData[$key]['country_id'] = $countryRow['country_id'];

            //运输方式
            if (!isset($smArr[$val['Shipping Method']])) {
                $smRow = Service_ShippingMethod::getByField($val['Shipping Method'], 'sm_code');
                if (empty($smRow)) {
                    $errorArr[] = '第 ' . $key . ' 行,' . 'Shipping Method：' . $val['Shipping Method'] . ' 不存在.';
                    continue;
                }
                $smArr[$val['Shipping Method']] = $smRow['sm_name_cn'];
            }

            //判断创建
            if (!isset($warehouseArr[$val['WarehouseCode']])) {
                $wRow = Service_Warehouse::getByField($val['WarehouseCode'], 'warehouse_code');
                if (empty($wRow)) {
                    $errorArr[] = '第 ' . $key . ' 行,' . 'WarehouseCode：' . $val['WarehouseCode'] . ' 不存在.';
                    continue;
                }
                $warehouseArr[$val['WarehouseCode']] = $wRow['warehouse_id'];
            }
            $orderData[$key]['warehouse_id'] = $warehouseArr[$val['WarehouseCode']];

            //判断有几个产品
            $keys = array_pop(array_keys($filerArr));
            $keyArr = explode('#', $keys);
            if (!preg_match("/qty/i", $keys) || !isset($keyArr[1]) || !is_numeric($keyArr[1])) {
                $errorArr[] = '第 ' . $key . ' 行,' . '产品数量异常.';
                continue;
            }

            //客户
            $customerRow = Service_Customer::getByField($customerCode, 'customer_code');
            if (empty($customerRow)) {
                $errorArr[] = 'customerCode:' . $customerCode . ' 不存在.';
                continue;
            }
            $orderData[$key]['customer_id'] = $customerRow['customer_id'];
            //内件数
            $orderData[$key]['parcel_quantity'] = $keyArr[1];

            $orderData[$key]['order_pick_type'] = $keyArr[1] != '1' || $val['Qty #1'] != '1' ? 1 : 0;
            $orderData[$key]['order_pick_type'] = isset($val['SKU #2']) ? 2 : $orderData[$key]['order_pick_type'];

            for ($i = 1; $i <= $keyArr[1]; $i++) {
                $sku = isset($val['SKU #' . $i]) ? $val['SKU #' . $i] : '';
                $qty = isset($val['Qty #' . $i]) ? $val['Qty #' . $i] : 0;
                if (empty($sku) || $qty == '0' || !is_numeric($qty) || $qty < 1) {
                    $errorArr[] = '第 ' . $key . ' 行,' . ' SKU 或 Qty 异常.SKU:' . $sku . ' Qty:' . $qty;
                    continue;
                }
                $productRows = Service_Product::getByCondition(array('product_sku' => $sku, 'customer_code'), '*');
                if (empty($productRows)) {
                    $errorArr[] = '第 ' . $key . ' 行,' . ' SKU:' . $sku . ' 不存在.';
                    continue;
                }
                //统计各产品数量
                if (!isset($productQtyArr[$sku])) {
                    $productQtyArr[$sku] = array(
                        'product_id' => $productRows[0]['product_id'],
                        'product_sku' => $sku,
                        'qty' => $qty,
                        'warehouse_id' => $orderData[$key]['warehouse_id']
                    );
                } else {
                    $productQtyArr[$sku]['qty'] += $qty;
                }

                $orderData[$key]['order_product'][] = array(
                    'product_sku' => $sku,
                    'op_quantity' => $qty,
                    'product_id' => $productRows[0]['product_id'],
                    'product_barcode' => $productRows[0]['product_barcode'],
                    'op_category' => $productRows[0]['pc_id'],
                );
            }

        }

        //  print_r($orderData);
        //print_r($productQtyArr);
        if (!empty($errorArr)) {
            $result['errorMsg'] = $errorArr;
            return $result;
        }

/*        //验证库存
        $piObj = new Service_ProductInventory();
        foreach ($productQtyArr as $k => $v) {
            $productInventoryRows = $piObj->getByCondition(array('warehouse_id' => $v['warehouse_id'], 'product_id' => $v['product_id']), '*');
            if (empty($productInventoryRows) || !isset($productInventoryRows[0]['pi_sellable']) || $productInventoryRows[0]['pi_sellable'] < $v['qty']) {
                $errorArr[] = 'SKU：' . $v['product_sku'] . ' 库存不足,' . '可用库存数量：' . (isset($productInventoryRows[0]['pi_sellable']) ? $productInventoryRows[0]['pi_sellable'] : 0) . '  全部订单所需库存数量：' . $v['qty'];
            }
        }
        if (!empty($errorArr)) {
            $result['errorMsg'] = $errorArr;
            return $result;
        }*/
        //导入订单数据
        $result = self::addOrders($orderData, $customerCode);
        return $result;
    }

    /**
     * @创建订单
     * @param array $ordersArr
     * @param string $customerCode
     * @return array
     * @throws Exception
     */
    private static function addOrders($ordersArr = array(), $customerCode = 'EC001')
    {
        $result = array(
            'state' => 0,
            'errorMsg' => array(),
            'message' => ''
        );
        $db = Service_Orders::getModelInstance()->getAdapter();
        try {
            $db->beginTransaction();
            $orderObj = new Service_Orders();
            $orderProductObj = new Service_OrderProduct();
            $addressObj = new Service_OrderAddressBook();
            $date = date('Y-m-d H:i:s');
            $piObj = new Service_ProductInventoryProcess();
            $soId = 0;
            $soCode = '';
            $orderStatus=4;
            $parcelQuantity=0;
            foreach ($ordersArr as $key => $orderArr) {;
                $orderStatus=4;
                $parcelQuantity=0;
                $orderCode = Common_GetNumbers::getCode('order', 'SO', 'TT');
                foreach ($orderArr['order_product'] as $k => $product) {
                    //库存
                    $row = array(
                        'product_id' => $product['product_id'],
                        'quantity' => $product['op_quantity'],
                        'warehouse_id' => $orderArr['warehouse_id'],
                    );
                    $parcelQuantity+=$product['op_quantity'];
                    $piRows=Service_ProductInventory::getByCondition($row);
                    if (empty($piRows) || !isset($piRows[0]['pi_sellable']) || $piRows[0]['pi_sellable'] < $product['op_quantity']) {
                        $orderStatus=3;
                    }
                }
                $order = array(
                    'order_code' => $orderCode,
                    'customer_id' => $orderArr['customer_id'],
                    'customer_code' => $customerCode,
                    'parcel_quantity' =>$parcelQuantity,
                    'warehouse_id' => $orderArr['warehouse_id'],
                    'sm_code' => $orderArr['Shipping Method'],
                    'order_status' => $orderStatus,
                    'reference_no' => $orderArr['ReferenceNo'],
                    'order_pick_type' => $orderArr['order_pick_type'],
                    'add_time' => $date,
                );
                if (!$orderId = $orderObj->add($order)) {
                    throw new Exception('第 ' . $key . ' 行,创建订单失败.');
                }

                $orderAddress = array(
                    'order_id' => $orderId,
                    'order_code' => $orderCode,
                    'oab_firstname' => $orderArr['First Name'],
                    'oab_lastname' => $orderArr['Last Name'],
                    'oab_company' => $orderArr['Company'],
                    'oab_country_id' => $orderArr['country_id'],
                    'oab_postcode' => $orderArr['Postalcode'],
                    'oab_state' => $orderArr['State/Provice'],
                    'oab_city' => $orderArr['City'],
                    'oab_street_address1' => $orderArr['Address1'],
                    'oab_street_address2' => $orderArr['Address2'],
                    'oab_email' => $orderArr['Email'],
                    'oab_phone' => $orderArr['PhoneNo'],
                );
                if (!$addressObj->add($orderAddress)) {
                    throw new Exception('第 ' . $key . ' 行,创建订单地址失败.');
                }

                //shipOrder
                if (isset($orderArr['TrackingNumber']) && $orderArr['TrackingNumber'] != '') {
                    $soCode = Common_GetNumbers::getCode('shiporder', $customerCode, 'SP');
                    $orderRow = array(
                        'so_code' => $soCode,
                        'order_id' => $orderId,
                        'order_code' => $orderCode,
                        'warehouse_id' => $orderArr['warehouse_id'],
                        'sm_code' => $orderArr['Shipping Method'],
                        'pp_barcode' => '',
                        'tracking_number' => $orderArr['TrackingNumber'],
                        'so_add_time' => $date,
                    );
                    if (!$soId = Service_ShipOrder::add($orderRow)) {
                        throw new Exception('添加物流信息失败.');
                    }
                }

                foreach ($orderArr['order_product'] as $k => $product) {
                    if($orderStatus=='4'){
                        //库存
                        $row = array(
                            'product_id' => $product['product_id'],
                            'quantity' => $product['op_quantity'],
                            'operationType' => 5,
                            'warehouse_id' => $orderArr['warehouse_id'],
                            'reference_code' => $orderCode, //操作单号
                            'application_code' => 'submitOrder', //操作类型
                            'note' => ''
                        );
                        $piReturn = $piObj->update($row);
                        if (!isset($piReturn['state']) || $piReturn['state'] != '1') {
                            throw new Exception('SKU:' . $product['product_sku'] . ',可用库存不足.');
                        }
                    }

                    unset($product['product_sku']);
                    $product['order_id'] = $orderId;
                    $product['order_code'] = $orderCode;
                    $product['op_add_time'] = $date;
                    if (!$opId = $orderProductObj->add($product)) {
                        throw new Exception('第 ' . $key . ' 行,创建订单产品:' . $product['product_barcode'] . '失败.');
                    }

                    //shipOrder
                    if ($soId != '' && $soId != '0') {
                        $detailRow = array(
                            'so_id' => $soId,
                            'so_code' => $soCode,
                            'order_id' => $orderId,
                            'order_code' => $orderCode,
                            'op_id' => $opId,
                            'sod_quantity' => $product['op_quantity'],
                            /*                        'op_description' => $val['product_title_en'],
                                                    'cn_description' => $val['product_title'],
                                                    'op_title' => $val['product_title'],
                                                    'hs_code' => isset($val['hs_code']) ? $val['hs_code'] : '',
                                                    'op_unit_price' => $val['product_sales_value'],
                                                    'op_subtotal' => round($val['op_quantity'] * $val['product_sales_value'], 4),
                                                    'op_origin' => '',
                                                    'op_declared_value' => $val['product_declared_value'],*/
                        );
                        if (!Service_ShipOrderDetail::add($detailRow)) {
                            throw new Exception ('添加物流详细失败. ' . $opId);
                        }
                    }
                }

            }
            $db->commit();
            $result['state'] = 1;
            $result['message'] = '成功导入订单数量：' . count($ordersArr);
            return $result;
        } catch (Exception $e) {
            $db->rollBack();
            $result['errorMsg'] = $e->getMessage();
            return $result;
        }
    }

    /**
     * @desc 导入ASN数据
     * @param $fileName
     * @param $filePath
     * @param string $customerCode
     */
    public static function uploadAsn($fileName, $filePath, $asnRow = array())
    {
        $result = array('state' => 0, 'errorMsg' => array(), 'message' => '');
        $fileData = self::readUploadFile($fileName, $filePath);
        if (!isset($fileData[1]) || !is_array($fileData[1])) {
            $result['errorMsg'] = array('上传失败，无法解析文件内容;');
            return $result;
        }

        $customerCode = isset($asnRow['customer_code']) ? $asnRow['customer_code'] : '';
        $warehouseId = isset($asnRow['warehouse_id']) ? $asnRow['warehouse_id'] : '';
        if (empty($customerCode)) {
            $result['errorMsg'] = array('customerCode 不能为空.');
            return $result;
        }

        if (empty($warehouseId)) {
            $result['errorMsg'] = array('warehouseCode 不能为空.');
            return $result;
        }

        $customerRow = Service_Customer::getByField($customerCode, 'customer_code');
        if (empty($customerRow)) {
            $result['errorMsg'] = array('customerCode:' . $customerCode . ' 不存在.');
            return $result;
        }

        $asnRow['customer_id'] = $customerRow['customer_id'];

        $productArr = $skuArr = array();
        foreach ($fileData as $key => $val) {
            if (count($val) != '2' || $val['SKU'] == '' || $val['Qty'] == '') {
                $errorArr[] = '第 ' . $key . ' 行,' . '数据异常.';
                continue;
            }

            if (!in_array($val['SKU'], $skuArr)) {
                $skuArr[] = $val['SKU'];
            } else {
                $errorArr[] = 'SKU:' . $val['SKU'] . ' 不允许重复.';
                continue;
            }

            if (!is_numeric($val['Qty']) || $val['Qty'] < 1) {
                $errorArr[] = '第 ' . $key . ' 行,' . 'SKU:' . $val['SKU'] . ',数量异常.';
                continue;
            }

            $productRows = Service_Product::getByCondition(array('product_sku' => $val['SKU'], 'customer_code' => $customerCode), array('product_id', 'product_barcode', 'product_is_qc'));
            if (empty($productRows)) {
                $errorArr[] = '第 ' . $key . ' 行,' . 'SKU:' . $val['SKU'] . ' 不存在.';
                continue;
            }
            $productArr[$key] = array(
                'product_sku' => $val['SKU'],
                'product_id' => $productRows[0]['product_id'],
                'product_barcode' => $productRows[0]['product_barcode'],
                'rd_receiving_qty' => $val['Qty'],
                'is_qc' => $productRows[0]['product_is_qc'],
            );

        }

        if (!empty($errorArr)) {
            $result['errorMsg'] = $errorArr;
            return $result;
        }

        return self::addAsn($asnRow, $productArr);
    }

    /**
     * @desc 创建ASN
     * @param array $ordersArr
     * @param string $customerCode
     */
    private static function addAsn($asnArr = array(), $productArr = array())
    {
        $result = array(
            'state' => 0,
            'errorMsg' => array(),
            'message' => ''
        );
        $db = Service_Orders::getModelInstance()->getAdapter();
        $piObj = new Service_ProductInventoryProcess();
        try {
            $db->beginTransaction();
            $code = Common_GetNumbers::getCode('ASN', $asnArr['warehouse_id'], 'R');
            $date = date('Y-m-d H:i:s');
            $asnRow = array(
                'receiving_code' => $code,
                'reference_no' => $asnArr['reference_no'],
                'warehouse_id' => $asnArr['warehouse_id'],
                'customer_id' => $asnArr['customer_id'],
                'customer_code' => $asnArr['customer_code'],
                'receiving_description' => $asnArr['receiving_description'],
                'receiving_status' => '5',
                'receiving_add_time' => $date
            );
            if (!$rId = Service_Receiving::add($asnRow)) {
                throw new Exception('创建ASN失败.');
            }
            $rdObj = new Service_ReceivingDetail();
            foreach ($productArr as $key => $item) {
                $sku = $item['product_sku'];
                unset($item['product_sku']);
                $item['receiving_id'] = $rId;
                $item['receiving_code'] = $code;
                $item['rd_add_time'] = $date;
                if (!$rdObj->add($item)) {
                    throw new Exception('创建ASN Item失败,SKU:' . $sku);
                }
                //库存
                $row = array(
                    'product_id' => $item['product_id'],
                    'quantity' => $item['rd_receiving_qty'],
                    'operationType' => 1,
                    'warehouse_id' => $asnRow['warehouse_id'],
                    'reference_code' => $code, //操作单号
                    'application_code' => 'ASN', //操作类型
                    'note' => ''
                );
                $piReturn = $piObj->update($row);
                if (!isset($piReturn['state']) || $piReturn['state'] != '1') {
                    throw new Exception('SKU:' . $sku . ',操作库存失败.');
                }
            }
            $db->commit();
            $result['state'] = 1;
            $result['message'] = '导入成功,AsnCode:' . $code . '  SKU种类：' . count($productArr);
        } catch (Exception $e) {
            $db->rollBack();
            $result['errorMsg'] = $e->getMessage();
        }
        return $result;
    }


}