<?php
require_once('config.php');
require_once "PHPExcel.php";
require_once "PHPExcel/IOFactory.php";

class InvtAuto
{
    protected $error = [];

    public function __construct() {
        $this->time = date("Y-m-d H:i:s");
    }

    /**
     * Note:
     * User: Yao
     * Date: 2021/6/5
     * Time: 14:44
     * @param $file
     * @param $uploadId
     * @return bool|string 成功时返回核放单号失败返回false
     */
    public function dealFile($file, $uploadId) {
        $mainifestProcess = new Service_CargoManifestProcess();
        $mainifestProcess->setDefaultWarehouse('DGST-YZ');
        $mainifestProcess->setCustomerCode('C0426');
        $excelReader = PHPExcel_IOFactory::createReaderForFile($file);
        $excelReader->setReadDataOnly(true);
        $sheet = $excelReader->load($file);
        $orderSheet = $sheet->getSheet(0);
        $carSheet = $sheet->getSheet(1);
        $highestColum = $orderSheet->getHighestRow();
        $orderCodeList = [];
        $giftFlag = false;
        for ($i = 2; $i <= $highestColum; $i++) {
            $valuData = $orderSheet->getCell('A' . $i)->getValue();
            if (is_object($valuData)) {
                $valuData = $valuData->__toString();
            }
            if ($valuData) {
                $valuData = trim($valuData);
                $orderCodeList[] = $valuData;
                $mainifestProcess->checkTransactionNo($valuData);
                if(!$giftFlag) {
                    $orderId = Service_Orders::checkHasGift([
                        'reference_no' => $valuData,
                        'order_status_neq' => 0,
                        'intercept_status' => '0',
                        'gift_flag'=>1,
                    ]);
                    if($orderId){
                        $giftFlag = true;
                    }
                }

            }
        }
        $error = $mainifestProcess->getError();
        if ($error) {
            $this->error = $error;
            return false;
        }
        $carNumber = $carSheet->getCell("A2")->getValue();
        $carWeight = $carSheet->getCell("B2")->getValue();
        $goodsGrossWeight = $carSheet->getCell("C2")->getValue();
        $hasGift = $carSheet->getCell("D2")->getValue();
        $invNo = $carSheet->getCell("E2")->getValue();
        $isPromotion = $carSheet->getCell("F2")->getValue();
        $carData = [
            'car_number' => $carNumber,
            'car_weight' => $carWeight,
            'goods_gross_weight' => $goodsGrossWeight,
            'has_gift' => $hasGift,
            'inv_no' => $invNo,
            'is_promotion'=>$isPromotion,
        ];
        $carErrorInfo = $this->checkCarInfo($carData,$giftFlag);
        if (!empty($carErrorInfo)) {
            $this->error = $carErrorInfo;
            return false;
        }
        $imcode = $mainifestProcess->createFromUpload($orderCodeList);
        if ($imcode == false) {
            $this->error = $mainifestProcess->getError();
            return false;
        }
        $shipBatchCode = Service_CargoManifestProcess::translateToShipBatch($imcode);
        if ($shipBatchCode != true) {
            $this->error[] = '生成出货总单失败' . $shipBatchCode;
            return false;
        }
        echo "载货单生成出货总单成功".$imcode;
        echo PHP_EOL;
        $result = $this->makeInvtManifest($imcode);
        if (!$result) {
            return $result;
        }
        var_dump($result);
        $db = Common_Common::getAdapter();
        //生成核注清单
        try {
            $db->beginTransaction();
            $imCode = $result['code'];
            $invManifestInfo = Service_InvtManifiest::getByField($imCode, 'im_code');
            $invOrderProcess = new Process_InvOrder();
            $invConfig = new Api_Inv_Config();
            $headConfig = $invConfig->getInvHeadConfig(2);//象嵘的信息
            $invOrderProcess->setHeadInfo($headConfig);
            $invOrderProcess->makeInvByIm($invManifestInfo);
            $invCodeList = $invOrderProcess->getInvCode();
            echo "生成核注清单" . implode(',', $invCodeList);
            echo PHP_EOL;
            foreach ($invCodeList as $invCode) {
                Service_InvtManifiestInvt::add([
                    'im_id' => $invManifestInfo['im_id'],
                    'etps_inner_invt_no' => $invCode,
                    'add_time' => date("Y-m-d H:i:s"),
                ]);
                $update = [
                    'upload_file_id' => $uploadId
                ];
                Service_InvtList::update($update, $invCode, 'EtpsInnerInvtNo');
            }
            Service_InvtManifiest::update([
                'im_status' => 1,
                'im_update_time' => date("Y-m-d H:i:s")
            ], $invManifestInfo['im_id']);
            $log = [
                'im_id' => $invManifestInfo['im_id'],
                'operater_id' => -1,
                'add_time' => date("Y-m-d"),
                'content' => "生成核注清单" . implode(',', $invCodeList),
                'status_from' => $invManifestInfo['im_status'],
                'status_to' => 1,
                'ip' => '127.0.0.1',
            ];
            Service_InvtManifestLog::add($log);
            $db->commit();
        } catch (Exception $e) {
            $db->rollBack();
            $this->error[] = $e->getMessage();
            return false;
        }
        foreach ($invCodeList as $invCode) {
            try {
                $db->beginTransaction();
                $invInfo = Service_InvtList::getByField($invCode, 'EtpsInnerInvtNo');
                $invProcess = new Process_Inv();
                $invProcess->setSendZb();//直接申报
                $res = $invProcess->confirm($invInfo);
                if($res){
                    echo "发送综保核注清单：".$invCode.'成功';
                    echo PHP_EOL;
                }else{
                    echo "发送综保核注清单：".$invCode.'失败';
                    echo PHP_EOL;
                }
                $db->commit();
            } catch (Exception $e) {
                $db->rollBack();
                $this->error[] = '核注清单' . $invCode . '确认失败:' . $e->getMessage();
                return false;
            }
        }
        $sbCode = $this->makeDelivery($invCodeList, $carData, $uploadId,$invManifestInfo['im_id']);
        if ($sbCode == false) {
            return false;
        }
        return $sbCode;
    }

    /**
     * Note:生成汇总单
     * User: Yao
     * Date: 2021/6/5
     * Time: 16:52
     * @param $imcode
     * @return bool
     */
    protected function makeInvtManifest($imcode) {
        $db = Common_Common::getAdapter();
        $db->beginTransaction();
        try {
            $invConfig = new Api_Inv_Config();
            $headConfig = $invConfig->getInvHeadConfig(2);//象嵘的信息
            $invOrder = new Process_InvOrder();
            $cargoManifestInfo = Service_CargoManifest::getByField($imcode, 'cm_code');
            $invOrder->setHeadInfo($headConfig);
            $result = $invOrder->createMainifestBySbcode([$cargoManifestInfo['sb_code']]);
            if ($result['state'] != 1) {
                $this->error[] = '创建汇单信息失败';
                return false;
            }
            echo "创建汇单成功:" . $result['code'];
            echo PHP_EOL;
            $db->commit();
            return $result;
        } catch (Exception $e) {
            echo $e;
            $this->error[] = '创建汇单信息失败:' . $e->getMessage();
            $db->rollBack();
            return false;
        }
    }

    /**
     * Note:生成核放单
     * User: Yao
     * Date: 2021/6/3
     * Time: 18:10
     * @param $invCodeList
     */
    public function makeDelivery($invCodeList, $carInfo, $uploadId,$imId) {
        $db = Common_Common::getAdapter();
        try {
            $db->beginTransaction();
            $companyInfo = Process_InvtSb::getCompanyInfo();
            $headInfo = [
                'idb_type' => 1,
                'passportTypecd' => '3',
                'rltTbTypecd' => 1,
                'ioTypecd' => 'E',
                'masterCuscd' => '5225',
                'areainEtpsno' => $companyInfo['area_code'],
                'areainEtpsNm' => $companyInfo['company_name'],
                'areainEtpsSccd' => $companyInfo['area_credit_code'],
                'vehicleNo' => $carInfo['car_number'],
                'vehicleIcNo' => $carInfo['car_number'],
                'vehicleFrameNo' => 0,
                'vehicleWt' => $carInfo['car_weight'],
                'vehicleFrameWt' => 0.1,
                'containerNo' => '',
                'totalGrossWt' => $carInfo['goods_gross_weight'],
                'totalNetWt' => '',
                'totalWt' =>  $carInfo['goods_gross_weight']+$carInfo['car_weight']+0.1,
                'DclErConc' => '',
                'DclEtpsno' => $companyInfo['area_code'],
                'DclEtpsNm' => $companyInfo['company_name'],
                'DclEtpsSccd' => '',
                'InputCode' => $companyInfo['area_code'],
                'InputName' => $companyInfo['company_name'],
                'InputSccd' => $companyInfo['area_credit_code'],
                'containerType' => '',
                'containerWt' => 0,
                'del_no' => '',
                'rltNo' => '',
                'rmk' => '',
                'upload_file_id' => $uploadId,
            ];
            if ($carInfo['has_gift'] == '是') {
                $headInfo['sb_mode'] = 1;
                $headInfo['del_no'] = $carInfo['inv_no'];
                $headInfo['rmk'] = $carInfo['inv_no'];
            } else {
                $headInfo['sb_mode'] = -1;
            }
            if($carInfo['is_promotion'] == '是'){
                $giftProductList = Service_InvtOrderSb::getGiftProductByCondition([
                    'im_id'=>$imId,
                    'gift_flag'=>1,
                ],['p.hs_goods_name','sum(op.op_quantity) as total_qty'],'op.product_id');
                $chukuRmk=[];
                foreach ($giftProductList as $gproduct){
                    $chukuRmk[]=$gproduct['hs_goods_name'].'*'.$gproduct['total_qty'];
                }
                $headInfo['rmk'] = implode("|",$chukuRmk);
            }
            if (count($invCodeList) > 1) {
                $headInfo['bindTypecd'] = 1;
            } else {
                $headInfo['bindTypecd'] = 2;
            }
            $code = Common_GetNumber::getCode('INVSB', 'DGST', '');
            //var_dump($code);
            $code =$companyInfo['area_code'].date("YmdHis").substr($code,-4);
            /*var_dump($code);
            exit;*/
            $save = [
                'SeqNo'=>'',
                'PassportNo' => '',
                'sb_mode'=>$headInfo['sb_mode'],
                'PassportTypecd'=>$headInfo['passportTypecd'],
                'MasterCuscd' => $headInfo['masterCuscd'],//主管关区代码
                'DclTypecd' => "1",//
                'IoTypecd' => $headInfo['ioTypecd'],//进出标志代码
                'BindTypecd' => $headInfo['bindTypecd'], //关联单证类型代码
                'RltTbTypecd' => $headInfo['rltTbTypecd'],//关联单据类型
                'RltNo' => $headInfo['rltNo'], //关联单证编号
                'AreainOriactNo' => '', //区内账册编号
                'AreainEtpsno'=>$headInfo['areainEtpsno'],//区内企业编码
                'AreainEtpsNm' => $headInfo['areainEtpsNm'], //区内企业编码
                'AreainEtpsSccd' => $headInfo['areainEtpsSccd'], //区内企业社会信用代码
                'VehicleNo' => $headInfo['vehicleNo'], //承运车车牌号
                'VehicleIcNo' => $headInfo['vehicleIcNo'], //IC卡号
                'ContainerNo' => $headInfo['containerNo'], //集装箱号
                'VehicleWt'=>$headInfo['vehicleWt'], //车自重
                'VehicleFrameNo'=>$headInfo['vehicleFrameNo'], //车架号
                'VehicleFrameWt' =>$headInfo['vehicleFrameWt'], //车架重
                'ContainerType'=>$headInfo['containerType'], //集装箱箱型
                'ContainerWt'=>$headInfo['containerWt'], //集装箱重
                'TotalWt'=>$headInfo['totalWt'],//总重量
                'TotalGrossWt'=>$headInfo['totalGrossWt'],//货物总毛重
                'TotalNetWt'=>$headInfo['totalNetWt'],//货物总净重
                'DclErConc'=>$headInfo['DclErConc'],//申请人及联系方式
                'DclTime'=>date("Y-m-d H:i:s",time()),//申报时间
                'DclEtpsno'=>$headInfo['DclEtpsno']?:'',//申报企业编号
                'DclEtpsNm'=>$headInfo['DclEtpsNm'], //申报企业名称
                'DclEtpsSccd'=>$headInfo['DclEtpsSccd'], //申报企业社会信用代码
                'InputCode'=>$headInfo['InputCode'], //录入单位代码
                'InputSccd'=>$headInfo['InputSccd']?:'', //录入单位社会信用代码
                'InputName'=>$headInfo['InputName'], //录入单位名称
                'EtpsPreentNo'=>$code, //企业内部编号
                'Rmk'=>$headInfo['rmk'],
                'del_no'=>$headInfo['del_no']?:'',
                'upload_file_id'=>$headInfo['upload_file_id']?:0,
                'Col1'=>'',
                'Col2'=>'',
                'Col3'=>'',
                'Col4'=>'',
            ];
            $is_id = Service_InvtSb::add($save);
            if (!$is_id) {
                throw  new Exception('保存核放表头信息失败');
            }
            $log = [
                'is_id' => $is_id,
                'is_node' => '添加核放单',
                'ls_text' => "自动程序：上传交接表生成表头",
                'add_time' => date("Y-m-d H:i:s",time()),
                //'status_to' => '1',
            ];
            Service_InvtSbLog::add($log);
            $db->commit();
            echo "生成核放单:".$code.'成功';
            echo PHP_EOL;
            return $code;
        } catch (Exception $e) {
            $this->error[] = $e->getMessage();
            $db->rollBack();
        }
        return false;
    }

    public function checkCarInfo($carData,$giftFlag) {
        $error = [];
        if (empty($carData['car_number'])) {
            $error[] = '车牌号必填';
        }
        if (empty($carData['car_weight'])) {
            $error[] = '车重为空';
        }
        if (empty($carData['goods_gross_weight'])) {
            $error[] = '货物毛重为空';
        }
        if (empty($carData['has_gift'])) {
            $error[] = '请填写是否有赠品信息';
        } else {
            if (!in_array($carData['has_gift'], ['是', '否'])) {
                $error[] = '赠品信息只能填写是否';
            } else {
                if ($carData['has_gift'] == '是') {
                    if(!$giftFlag){
                        $error[]='系统查询无赠品信息';
                    }
                    if (empty($carData['inv_no'])) {
                        $error[] = '有赠品信息，请填写赠品核注清单海关编号';
                    }

                }else{
                    if($giftFlag){
                        $error[]='系统查询到含有赠品订单';
                    }
                }
            }
        }
        if (empty($carData['is_promotion'])) {
            $error[] = '请填写是否大促';
        } else {
            if (!in_array($carData['is_promotion'], ['是', '否'])) {
                $error[] = '是否大促只能填写是或者否';
            }else{
                if($carData['is_promotion'] == '是'){
                    if (empty($carData['inv_no'])) {
                        // $error[] = '大促模式，请填写赠品核注清单海关编号';
                    }
                }
            }
        }
        if(!empty($carData['inv_no'])){
            // $endHead = Service_InvtEntHead::getByField($carData['inv_no'],'pre_ent_no');
            // if(empty($endHead)){
            //     $error[] = '核注清单海关编号信息不存在';
            // }
        }
        return $error;
    }

    /**
     * Note:发送核放单
     * User: Yao
     * Date: 2021/6/4
     * Time: 18:28
     */
    public function refillDiliverInfo() {
        $invList = Service_InvtList::getByCondition([
            'upload_file_id_no_empty' => true,
            'zb_status_in' => ['4', '5']
        ]);
        $fileId = [];
        foreach ($invList as $invt) {
            $fileId[] = $invt['upload_file_id'];
        }
        $fileId = array_unique($fileId);
        foreach ($fileId as $fid) {
            $invtSbInfo = Service_InvtSb::getByField($fid, 'upload_file_id');
            $db = Common_Common::getAdapter();
            try {
                $db->beginTransaction();
                if (!empty($invtSbInfo) && $invtSbInfo['is_status'] == -1) {
                    if ($invtSbInfo['TotalNetWt'] == 0) {
                        $totalNetWeight = 0;
                        $fileInvtList = Service_InvtList::getByCondition([
                            'upload_file_id' => $fid
                        ]);
                        if (!empty($fileInvtList)) {
                            foreach ($fileInvtList as $value) {
                                $invtNetWeight = Service_InvtListBody::getByCondition([
                                    'il_id' => $value['il_id']
                                ], 'sum(NetWt) as net_wt');
                                $totalNetWeight += $invtNetWeight[0]['net_wt'];
                                if($value['zb_status']!=4 && $value['zb_status']!=5){
                                    throw new Exception('核注清单不是预核扣或者通过未核扣状态');
                                }
                                if (empty($value['BondInvtNo'])) {
                                    throw new Exception($value['EtpsInnerInvtNo'] . '核注清单海关清单号为空');
                                }
                                $addSbInvt = array(
                                    'is_id' => $invtSbInfo['is_id'],
                                    'EtpsInnerInvtNo' => $invtSbInfo['EtpsPreentNo'],
                                    'RltInvtNo' => $value['BondInvtNo'],
                                    'add_time' => date("Y-m-d H:i:s", time())
                                );
                                if (!Service_InvtSbInvtlist::add($addSbInvt)) {
                                    throw new Exception("核放单和核注清单关联失败");
                                }
                                $log = [
                                    'is_id' => $invtSbInfo['is_id'],
                                    'is_node' => '添加核放单表体',
                                    'ls_text' => $invtSbInfo['EtpsPreentNo'],
                                    'add_time' => date("Y-m-d H:i:s", time()),
                                    //'status_to' => '1',
                                ];
                                Service_InvtSbLog::add($log);
                            }
                        }
                        if ($totalNetWeight) {
                            $updateInvtSb = [
                                'TotalNetWt' => $totalNetWeight
                            ];
                            $invtSbInfo['TotalNetWt'] = $totalNetWeight;
                            Service_InvtSb::update($updateInvtSb, $invtSbInfo['is_id']);
                            $log = [
                                'is_id' => $invtSbInfo['is_id'],
                                'is_node' => '更新核放单净重',
                                'ls_text' => '',
                                'add_time' => date("Y-m-d H:i:s", time()),
                                //'status_to' => '1',
                            ];
                            Service_InvtSbLog::add($log);
                        }
                    }
                }
                $db->commit();
            }catch (Exception $e){
                $dingding = new Api_Dd_Robbot();
                $dingding->sendMessageText($e->__toString());
                $db->rollBack();
                echo $e;
            }
        }
    }
    public function sendDelivery(){
        $sbDriverList = Service_InvtSb::getByCondition([
            'is_status'=>-1,
            'upload_file_id_no_empty'=>true
        ]);
        foreach ($sbDriverList as $sb){
            if ($sb['TotalNetWt']!=0) {
                $sbProcess = new Process_InvtSb();
                $result = $sbProcess->send($sb, 1);//直接申报
                $dingding = new Api_Dd_Robbot();
                $weixing = new Api_Dd_WxRobbot();
                if($result['state'] == 1) {
                    echo '核放单' . $sb['EtpsPreentNo'] . '发送成功';
                    $updateInvtSb = [
                        'is_status' => 1
                    ];
                    Service_InvtSb::update($updateInvtSb, $sb['is_id']);
                    echo PHP_EOL;
                    $dingding->sendMessageText('核放单' . $sb['EtpsPreentNo'] . '发送成功');
                    $weixing->sendMessageText('核放单' . $sb['EtpsPreentNo'] . '发送成功');
                } else {
                    '核放单' . $sb['EtpsPreentNo'] . '发送综保失败';
                    echo PHP_EOL;
                    $dingding->sendMessageText('核放单' . $sb['EtpsPreentNo'] . '发送综保失败');
                    $weixing->sendMessageText('核放单' . $sb['EtpsPreentNo'] . '发送综保失败');
                }
            }
        }

    }

    public function exe() {
        $flag = APPLICATION_PATH . '/../data/log/' . basename(__FILE__, '.php') . '.lock';
        if (@file_exists($flag)) {
            echo "Another process is running\r\n";
            echo "{$flag}\r\n";
            //exit();
        }
        $handler = fopen($flag, 'wb');
        $uploadList = Service_HandOverFile::getByCondition([
            //'deal_state' => '-1',
            'hof_id' => '43',
        ]);

        //var_dump($uploadList);
        //exit;
        $dingding = new Api_Dd_Robbot();
        $weixing = new Api_Dd_WxRobbot();
        //先处理上传的文件，文件处理完等核注清单回执，回执成功，发送核放单
       /* foreach ($uploadList as $upload) {
            $this->error = [];
            $res = $this->dealFile($upload['file_path'], $upload['hof_id']);
            if (!empty($this->error)) {
                $dingding->sendMessageText(implode(',',$this->error));
                $weixing->sendMessageText(implode(',',$this->error));
                $update = [
                    'deal_state' => 2,
                    'result_message' => implode(',', $this->error),
                    'deal_time' => date("Y-m-d H:i:s"),
                ];
                Service_HandOverFile::update($update, $upload['hof_id']);
            } else {
                $dingding->sendMessageText($upload['client_file_name'].'处理成功，核放单号：'.$res);
                $weixing->sendMessageText($upload['client_file_name'].'处理成功，核放单号：'.$res);
                $update = [
                    'deal_state' => 1,
                    'result_message' => '处理成功',
                    'deal_time' => date("Y-m-d H:i:s"),
                ];
                Service_HandOverFile::update($update, $upload['hof_id']);
            }
        }
        $this->refillDiliverInfo();//补充核放单净重和关联核注清单号
        $this->sendDelivery();//发送核放单*/
        $notNotifyFile = Service_HandOverFile::getByCondition([
            /*'notify_status'=>'0',
            'deal_state'=>1,*/
            'hof_id' => '43',
        ]);
        // var_dump($notNotifyFile);
        foreach ($notNotifyFile as $file){
            $invtSb = Service_InvtSb::getByField($file['hof_id'],'upload_file_id');
            if(!empty($invtSb)){
                //if($invtSb['is_status'] ==2){
                    $sbInvtList = Service_InvtSbInvtlist::getByCondition([
                        'is_id'=>$invtSb['is_id']
                    ]);
                    $totalOrder = 0;
                    foreach ($sbInvtList as $invt){
                        $invt = Service_InvtList::getByField($invt['RltInvtNo'],'BondInvtNo');
                        $invtSbcount = Service_InvtOrderSb::getByCondition(['EtpsInnerInvtNo'=>$invt['EtpsInnerInvtNo']],'count(*)');
                        $totalOrder+=$invtSbcount;
                    }
                    $content ="# 车牌:".$invtSb['VehicleNo'].'核放单已经审核通过'.date("Y-m-d H:i:s",time()).PHP_EOL;
                    $content .="*  核注清单号:".$invtSb['PassportNo'].PHP_EOL;
                    $content .="*  车牌：".$invtSb['VehicleNo'].PHP_EOL;
                    $content .="*  订单总数：".$totalOrder.PHP_EOL;
                    $content .="*  总重量：".$invtSb['TotalWt'].PHP_EOL;
                    $content .="*  货物毛重：".$invtSb['TotalGrossWt'].PHP_EOL;
                    $dingding->sendMessageMarkdown($invtSb['VehicleNo'].'已经审核通过',$content);
                    $weixing->sendMessageText($content);
                    //Service_HandOverFile::update(['notify_status'=>1],$file['hof_id']);
                //}
            }
        }
        fclose($handler);
        echo '[', date('Y-m-d H:i:s'), '] Start', "\r\n";
        echo "处理完成\r\n";
        echo '[', date('Y-m-d H:i:s'), '] End', "\r\n";
        @unlink($flag);
    }

}

$invtAuto = new InvtAuto();
$invtAuto->exe();