<?php
/**
 * Class Process_Inv
 * User: Yao
 * Date: 2021/5/6
 * Note:核注清单
 */

use App\models\Logistic\Api\SendXml\Inv;

class Process_Inv
{
    protected $headInfo;
    protected $bodyInfo;
    protected $bodyAfterFunction = [];
    protected $sendZb = 0;//是否直接申报综保系统0:暂存，1直接申报

    protected $formType; //业务类型

    public function setSendZb()
    {
        $this->sendZb = 1;
    }

    public function setFormType($formType){
        $this->formType = $formType;
    }

    /**
     * Note:验证表头信息
     * User: Yao
     * Date: 2020/8/6
     * Time: 17:54
     * @param $headInfo
     * @return array
     */
    public function validateHeadInfo($headInfo)
    {
        $error = [];
        if (empty($headInfo['dcl_typecd'])) {
            $error[] = '申报类型为空';
        } else {
            if (!in_array($headInfo['dcl_typecd'], array_keys(Service_InvtList::getdclTypecdStatus()))) {
                $error[] = '申报类型错误';
            }
        }
        if (empty($headInfo['DclPlcCuscd']) && $headInfo['DclPlcCuscd'] == '') {
            $error[] = '申报地海关为空';
        }

        if (empty($headInfo['bwl_type']) && $headInfo['bwl_type'] !== '0') {
            $error[] = '底账类型为空';
        } else {
            if (!in_array($headInfo['bwl_type'], array_keys(Service_InvtList::getbwlType()))) {
                $error[] = '底账类型错误';
            }
        }
        if (empty($headInfo['bwl_no'])) {
            $error[] = '底账海关编号为空';
        }
        if (empty($headInfo['invt_type']) && $headInfo['invt_type'] !== '0') {
            $error[] = '清单类型为空';
        } else {
            if (!in_array($headInfo['invt_type'], array_keys(Service_InvtList::getInvtType()))) {
                $error[] = '清单类型错误';
            }
        }
        if (empty($headInfo['bizop_etps_no'])) {
            $error[] = '经营企业信用代码为空';
        }
        if (empty($headInfo['supv_modecd'])) {
            $error[] = '监管方式为空';
        } else {
            if (!in_array($headInfo['supv_modecd'], array_keys(Service_InvtList::getsupvModecd()))) {
                $error[] = '监管方式为空错误';
            }
        }
        if (empty($headInfo['trsp_modecd'])) {
            $error[] = '运输方式为空';
        } else {
            if (!in_array($headInfo['trsp_modecd'], array_keys(Service_InvtList::getTrspMethod()))) {
                $error[] = '运输方式错误';
            }
        }
        if (empty($headInfo['dclcus_flag'])) {
            $error[] = '报关标记为空';
        } else {
            if (!in_array($headInfo['dclcus_flag'], array_keys(Service_InvtList::getDclusFlag()))) {
                $error[] = '报关标记错误';
            }
        }
        if (empty($headInfo['mtpck_endprd_markcd'])) {
            $error[] = '料件成品标记为空';
        } else {
            if (!in_array($headInfo['mtpck_endprd_markcd'], array_keys(Service_InvtList::getMtpckEndprdMarkd()))) {
                $error[] = '料件成品标错误';
            }
        }
        if (empty($headInfo['impexp_markcd'])) {
            $error[] = '进出口标记为空';
        } else {
            if (!in_array($headInfo['impexp_markcd'], array_keys(Service_InvtList::getImepexpMarkcdStatus()))) {
                $error[] = '进出口标记错误';
            }
        }
        if (empty($headInfo['impexp_portcd'])) {
            $error[] = '进出境关别为空';
        } else {
            if (!in_array($headInfo['impexp_portcd'], array_keys(Service_InvtList::getImexpPortcd()))) {
                $error[] = '进出境关别错误';
            }
        }
        if (empty($headInfo['stship_trsarv_natcd'])) {
            $error[] = '起运/运抵国为空';
        } else {
            $countryInfo = Service_Country::getByField($headInfo['stship_trsarv_natcd'], 'trade_country');
            if (empty($countryInfo)) {
                $error[] = '起运/运抵国错误';
            }
        }
        if (empty($headInfo['gen_dec_flag'])) {
            $error[] = '是否生成报关单为空';
        }
        if (!empty($headInfo['dec_type'])) {
            $declType = Service_InvtList::getDecType();
            if (!isset($declType[$headInfo['dec_type']])) {
                $error[] = '报关单类型错误';
            }
        }
        if (empty($headInfo['rcvgd_etps_no'])) {
            $error[] = '收发货企业信息为空';
        }
        return $error;
    }

    /**
     * Note:验证入区的申报数据
     * User: Yao
     * Date: 2020/8/10
     * Time: 17:52
     * @param $bodyInfo
     * @param $warehosueAccount 仓库账册号
     */
    public function validateInBodyInfo(&$bodyInfo, $warehosueAccount)
    {
        $error = [];
        $warnError = [];
        foreach ($bodyInfo as $key => $body) {
            $lineError = [];
            $linWarnError = [];
            if (empty($body['dcl_qty'])) {
                $lineError[] = '申报数量为空';
            } else {
                if (!preg_match('/^[1-9]\d*$/', $body['dcl_qty'])) {
                    $lineError[] = '申报数量必须为正整数';
                }
            }
            if (empty($body['gdecd'])) {
                $lineError[] = '海关编码为空';
            }
            if (empty($body['gds_nm'])) {
                $lineError[] = '海关品名为空';
            }
            if (empty($body['dcl_unitcd'])) {
                $lineError[] = '申报单位为空';
            } else {
                if (!preg_match("/^\d+$/", $body['dcl_unitcd'])) {
                    $lineError[] = '申报单位为数字类型';
                }
            }
            if (empty($body['lawf_unitcd'])) {
                $lineError[] = '法一单位为空';
            } else {
                if (!preg_match("/^\d+$/", $body['lawf_unitcd'])) {
                    $lineError[] = '申报单位为数字类型';
                }
            }
            if (empty($body['natcd'])) {
                $lineError[] = '原产国为空';
            } else {
                if (!preg_match("/^\d+$/", $body['natcd'])) {
                    $lineError[] = '原产国必须为数字类型';
                }
            }
            if (empty($body['gds_mtno'])) {
                $lineError[] = '商品料号为空';
            } else {
                if($body['product_type'] != 2) {
                    $productInfo = Service_Product::getByField($body['gds_mtno'], 'goods_id', ['product_id', 'hs_code']);
                    if (empty($productInfo)) {
                        $lineError[] = $body['gds_mtno'] . '对应的商品信息不存在';
                    } else {
                        if (!empty($productInfo['hs_code'])) {
                            if ($body['gdecd'] != $productInfo['hs_code']) {
                                $lineError[] = '料号' . $body['gds_mtno'] . '录入的海关编码和商品海关编码不一致';
                            }
                            $hsUom = Service_HsUom::getByField($productInfo['hs_code'], 'hs_code');
                            if (!empty($body['second_legal_unit']) && $body['second_legal_unit'] > 0 && empty($hsUom['pu_code_second'])) {
                                $lineError[] = '料号' . $body['gds_mtno'] . '没有法二数量，不能上传';
                            }
                        } else {
                            $lineError[] = '料号' . $body['gds_mtno'] . '没有备案海关编码信息';
                        }
                    }
                    $bodyInfo[$key]['product_id'] = $productInfo['product_id'];
                    $billBook = Service_BillBook::getByCondition([
                        'warehous_account_no' => $warehosueAccount,
                        'goods_code' => $body['gds_mtno'],
                        'state' => '0'
                    ]);
                    if (!empty($billBook)) {
                        if (empty($body['putrec_seqno'])) {
                            $lineError[] = $body['gds_mtno'] . '料号已经存在账册备案号' . $billBook[0]['recorde_no'] . '请确认是否要入到新的备案序号';
                        } else {
                            $same = false;
                            foreach ($billBook as $recode) {
                                if ($body['putrec_seqno'] == $recode['recorde_no']) {
                                    $same = true;
                                }
                            }
                            if (!$same) {
                                $linWarnError[] = $body['putrec_seqno'] . '料号已存在账册信息，入区备案号必须与已有的一致';
                            }
                        }
                    }
                }
                //一日游的不检查了
                $arroneDay = array(
                    'IN1D',
                    'EN1D'
                );
                if(!in_array($this->formType,$arroneDay)){
                    //不检测了
                    /*$checkInvt = Service_InvtList::getLeftJoinByCondition([
                        'GdsMtno' => $body['gds_mtno'],
                        'PutrecNo' => $warehosueAccount,
                        'status_in' => ['1', '2'],
                        'putrec_seqno_empty' => true,
                    ], 'count(*)');
                    if ($checkInvt) {
                        $lineError[] = '商品料号【' . $body['gds_mtno'] . '】有新备案序号未完成核注清单号' . $checkInvt[0]['EtpsInnerInvtNo'];
                    }*/
                }
            }
            if (!empty($body['putrec_seqno'])) {
                $billBook = Service_BillBook::getByCondition([
                    'warehous_account_no' => $warehosueAccount,
                    'recorde_no' => $body['putrec_seqno']
                ]);
                if (!preg_match("/^\d+$/", $body['putrec_seqno'])) {
                    $lineError[] = '备案序号必须是数字，不能有空格';
                }
                if (empty($billBook)) {


                } else {
                    $billBook = $billBook[0];
                    if ($billBook['hs_code'] != $body['gdecd']) {
                        $lineError[] = '账册海关编码不一致';
                    }
                    if ($billBook['product_title'] != $body['gds_nm']) {
                        $lineError[] = '账册海关品名不一致';
                    }
                    if ($billBook['decalare_unit'] != $body['dcl_unitcd']) {
                        $lineError[] = '账册申报单位不一致';
                    }
                    if ($billBook['legal_unit'] != $body['lawf_unitcd']) {
                        $lineError[] = '账册法一单位不一致';
                    }
                    if ($billBook['second_legal_unit'] != $body['secd_lawf_unitcd']) {
                        $lineError[] = '账册法二单位不一致';
                    }
                    if ($billBook['country_code'] != $body['natcd']) {
                        $lineError[] = '账册原产国不一致';
                    }
                }
            }
            if (!empty($lineError)) {
                $error[] = "序号【" . $body['gds_seqno'] . '】错误：' . implode(',', $lineError);
            }
            if (!empty($linWarnError)) {
                $warnError[] = "序号【" . $body['gds_seqno'] . '】错误：' . implode(',', $linWarnError);
            }

        }
        return [
            'error' => $error,
            'warn_error' => $warnError,
        ];
    }

    /**
     * Note:验证转出表体信息
     * User: Yao
     * Date: 2020/8/6
     * Time: 17:55
     * @param $bodyInfo
     * @param $warehosueAccount 账册号代码
     * @param $checkCanUserQuantiy 是否验证可用库存
     */
    public function validateOutBodyInfo(&$bodyInfo, $warehosueAccount, $checkCanUserQuantiy = true)
    {
        $error = [];
        foreach ($bodyInfo as $key => $body) {
            $lineError = [];
            if (empty($body['putrec_seqno'])) {
                $lineError[] = "账册项号为空";
            }
            if (empty($body['dcl_qty'])) {
                $lineError[] = '申报数量为空';
            } else {
                if (!preg_match('/^[1-9]\d*$/', $body['dcl_qty'])) {
                    $lineError[] = '申报数量必须为正整数';
                }
            }
            if (empty($lineError) && $body['product_type']!=2) {
                $productInfo = Service_Product::getByField($body['gds_mtno'], 'goods_id', 'product_id');
                if (empty($productInfo)) {
                    $lineError[] = $body['gds_mtno'] . '对应的商品信息不存在';
                }
                $bodyInfo[$key]['product_id'] = $productInfo['product_id'];
                $billBook = Service_BillBook::getByCondition([
                    'warehous_account_no' => $warehosueAccount,
                    'recorde_no' => $body['putrec_seqno']
                ]);
                if (!empty($billBook)) {
                    if ($checkCanUserQuantiy) {
                        if ($billBook[0]['can_use_quantity'] < $body['dcl_qty']) {
                            $lineError[] = "转出数量不够" . $billBook[0]['can_use_quantity'];
                        }
                    }
                }
            }
            if (!empty($lineError)) {
                $error[] = "序号【" . $body['gds_seqno'] . '】错误：' . implode(',', $lineError);
            }
        }
        return $error;
    }

    /**
     * Note:添加核注清单数据
     * User: Yao
     * Date: 2020/8/8
     * Time: 11:06
     * @param $headInfo
     * @param $bodyInfo
     * @return string 企业内部订单号
     * @throws Exception
     */
    public function doSave($headInfo, $bodyInfo)
    {
        $code = Common_GetNumber::getCode('INV', 'DGST', '');
        $code = $headInfo['rcvgd_etps_no'] . date("YmdHis") . '2' . substr($code, -3);
        //申报单位和关联报关单申报单位社会信用代码填上数据
        $dcl_etps_sccd = $headInfo['dcl_etps_sccd'];
        if($headInfo['dcl_etpsno']!=''){
            $decEnt = Service_EntInfo::getByField($headInfo['dcl_etpsno'],'ent_customs_code');
            $dcl_etps_sccd = $decEnt['ent_code_scc'];
        }
        $corr_entry_dcl_etps_sccd = $headInfo['corr_entry_dcl_etps_sccd'];
        if($headInfo['corr_entry_dcl_etps_no']!=''){
            $corrEnt = Service_EntInfo::getByField($headInfo['corr_entry_dcl_etps_no'],'ent_customs_code');
            $corr_entry_dcl_etps_sccd = $corrEnt['ent_code_scc'];
        }


        $save = [
            'PutrecNo' => $headInfo['bwl_no'],
            'DclTypecd' => $headInfo['dcl_typecd'],
            'BizopEtpsno' => $headInfo['bizop_etps_no'],//经营企业编号
            'BizopEtpsNm' => $headInfo['bizop_etps_nm'],//经营企业名称
            'BizopEtpsSccd' => $headInfo['bizop_etps_sccd'],//经营企业社会信用代码
            'EtpsInnerInvtNo' => $code,
            'DclEtpsSccd'=>$dcl_etps_sccd,//申报企业社会信用代码
            'SupvModecd' => $headInfo['supv_modecd'],//监管方式代码
            'TrspModecd' => $headInfo['trsp_modecd'],
            'DclcusFlag' => $headInfo['dclcus_flag'],
            'StshipTrsarvNatcd' => $headInfo['stship_trsarv_natcd'],//起运抵运国
            'MtpckEndprdMarkcd' => $headInfo['mtpck_endprd_markcd'],
            'ImpexpMarkcd' => $headInfo['impexp_markcd'],
            'ImpexpPortcd' => $headInfo['impexp_portcd'],
            'DclPlcCuscd' => $headInfo['DclPlcCuscd'], //申报地海关丢失
            'GenDecFlag' => $headInfo['gen_dec_flag'],
            'bwl_type' => $headInfo['bwl_type'],
            'InvtType' => $headInfo['invt_type'],
            'DclEtpsno' => $headInfo['dcl_etpsno'] ?: '',
            'DclEtpsNm' => $headInfo['dcl_etps_nm'] ?: '',
            'InputCode' => $headInfo['input_code'] ?: '',
            'InputCreditCode' => $headInfo['input_credit_code'] ?: '',
            'InputName' => $headInfo['input_name'] ?: '',
            'bwl_no' => $headInfo['bwl_no'],
            'add_time' => date("Y-m-d H:i:s"),
            'Rmk' => $headInfo['remark'],
            'EntryNo' => $headInfo['entry_no'] ? trim($headInfo['entry_no']) : "",
            'RcvgdEtpsno' => $headInfo['rcvgd_etps_no'],//固定 企业海关代码 收发货企业信息
            'RvsngdEtpsSccd' => $headInfo['rvsngd_etps_sccd'],//固定企业信用代码
            'RcvgdEtpsNm' => $headInfo['rcvgd_etps_nm'],//企业中文名称
            'RltInvtNo' => $headInfo['rlt_invt_no']??'',//关联清单编号
            'RltPutrecNo' => $headInfo['rlt_putrec_no']??'',//关联账册备案编号
            'RltEntryNo' => $headInfo['rlt_entry_no'] ?: '',//关联报关单编号
            'DclcusTypecd' => $headInfo['dclcus_typecd'] ?: '',//报关类型
            'DecType' => $headInfo['dec_type'] ?: '',//报关单类型
            'RltEntryBizopEtpsSccd'=>$headInfo['rlt_entry_bizop_etps_sccd']?:'',//关联报关单境内收发货人社会信用代码',
            'RltEntryBizopEtpsno'=>$headInfo['rlt_entry_bizop_etps_no']?:'',// 关联报关单境内收发货人编号',
            'RltEntryBizopEtpsNm'=>$headInfo['rlt_entry_bizop_etps_nm']?:'',//'关联报关单境内收发货人名称',
            'RltEntryRvsngdEtpsSccd'=>$headInfo['rlt_entry_rcvgd_etps_sccd']?:'',//'关联报关单收发货单位社会统一信用代码',
            'RltEntryRcvgdEtpsno' =>$headInfo['rlt_entry_rcvgd_etpsno']?:'',//关联报关单海关收发货单位编码',
            'RltEntryRcvgdEtpsNm' =>$headInfo['rlt_entry_rcvgd_etps_nm']?:'' ,//关联报关单收发货单位名称',
            'RltEntryDclEtpsSccd'  =>$headInfo['rlt_entry_dcl_etps_sccd']?:'',//关联报关单申报单位社会统一信用代码',
            'RltEntryDclEtpsno' =>$headInfo['rlt_entry_dcl_etpsno']?:'',//'关联报关单海关申报单位编码',
            'RltEntryDclEtpsNm' =>$headInfo['rlt_entry_dcl_etps_nm']?:'',
            'CorrEntryDclEtpsNo' => $headInfo['corr_entry_dcl_etps_no'] ?: '',//对应报关单申报单位代码
            'CorrEntryDclEtpsNm' => $headInfo['corr_entry_dcl_etps_nm'] ?: '',//对应报关单申报单位名称
            'CorrEntryDclEtpsSccd' => $corr_entry_dcl_etps_sccd,//$headInfo['corr_entry_dcl_etps_sccd'] ?: '',//对应报关单申报单位社会统一信用代码
        ];
        $invId = Service_InvtList::add($save);
        if (!$invId) {
            throw  new Exception('保存信息失败');
        }
        $save['il_id'] = $invId;
        if (empty($bodyInfo)) {
            throw new Exception("核注清单表体内容为空");
        }
        foreach ($bodyInfo as $key => $value) {
            $saveBody = [
                'il_id' => $invId,
                // 'SeqNo'=>$value['seq_no'],
                'GdsSeqno' => $value['gds_seqno'],
                'PutrecSeqno' => $value['putrec_seqno'],
                'GdsMtno' => $value['gds_mtno'],
                'Gdecd' => $value['gdecd'],
                'GdsNm' => $value['gds_nm'],
                'GdsSpcfModelDesc' => $value['gds_spcf_model_desc'],
                'DclUnitcd' => $value['dcl_unitcd'],
                'LawfUnitcd' => $value['lawf_unitcd'],
                'SecdLawfUnitcd' => $value['secd_lawf_unitcd'],
                'Natcd' => $value['natcd'],
                'DclUprcAmt' => $value['dcl_uprc_amt'],
                'DclTotalAmt' => $value['dcl_total_amt'],
                'UsdStatTotalAmt' => empty($value['usd_stat_total_amt']) ? 0 : $value['usd_stat_total_amt'],
                'DclCurrcd' => $value['dcl_currcd'],
                'LawfQty' => $value['lawf_qty'],
                'SecdLawfQty' => $value['secd_lawf_qty'],
                'WtSfVal' => empty($value['wt_sf_val']) ? 0 : $value['wt_sf_val'],
                'FstSfVal' => empty($value['fst_sf_val']) ? 0 : $value['fst_sf_val'],
                'SecdSfVal' => empty($value['secd_sf_val']) ? 0 : $value['secd_sf_val'],
                'DclQty' => $value['dcl_qty'],
                'GrossWt' => empty($value['gross_wt']) ? 0 : $value['gross_wt'],
                'NetWt' => empty($value['net_wt']) ? 0 : $value['net_wt'],
                'UseCd' => $value['use_cd'],
                'LvyrlfModecd' => $value['lvyrlf_modecd'],
                'UcnsVerno' => $value['ucns_verno'],
                'EntryGdsSeqno' => $value['entry_gds_seqno'],
                'ClyMarkcd'=> !empty($value['cly_markcd']) ? $value['cly_markcd'] : '0',//isset($value['cly_markcd']) ? $value['cly_markcd'] :'0',
                'ApplyTbSeqno' => empty($value['apply_tb_seqno']) ? '' : $value['apply_tb_seqno'],
                'DestinationNatcd' => $value['destination_natcd'],
                'ModfMarkcd' => 3,
                'Rmk' => $value['rmk'],
                'product_id' => $value['product_id'] ?: '',
            ];
            $ilb_id = $saveBody['ilb_id'] = Service_InvtListBody::add($saveBody);
            if (!$ilb_id) {
                throw  new Exception('核注清单表体插入失败');
            }
            $this->bodyAfter($saveBody, $save, $value);
        }
        $log = [
            'il_id' => $invId,
            'note' => '添加',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => '0',
            'status_to' => '1',
        ];
        Service_InvtListLog::add($log);
        return $code;
    }

    /**
     * Note:表体添加后逻辑
     * User: Yao
     * Date: 2021/1/11
     * Time: 9:29
     * @param $afterFunction
     */
    protected function bodyAfter(...$argument)
    {
        foreach ($this->bodyAfterFunction as $function) {
            if ($function instanceof Closure) {
                $function(...$argument);
            } elseif (is_callable($function)) {
                call_user_func_array($function, $argument);
            }
        }
    }

    public function addBodyAfter($function)
    {
        $this->bodyAfterFunction[] = $function;
    }

    /**
     * Note:编辑订单信息
     * User: Yao
     * Date: 2020/8/12
     * Time: 18:08
     * @param $headInfo
     * @param $bodyInfo
     */
    public function doEdit($headInfo, $bodyInfo)
    {
        $invList = Service_InvtList::getByField($headInfo['il_id']);
        $save = [
            'DclTypecd' => $headInfo['dcl_typecd'],
            'BizopEtpsno' => $headInfo['bizop_etps_no'],//经营企业编号
            'BizopEtpsNm' => $headInfo['bizop_etps_nm'],//经营企业名称
            'BizopEtpsSccd' => $headInfo['bizop_etps_sccd'],//经营企业社会信用代码
            // 'DclEtpsSccd'=>$headInfo['dcl_etps_sccd'],//申报企业社会信用代码
            'SupvModecd' => $headInfo['supv_modecd'],//监管方式代码
            'TrspModecd' => $headInfo['trsp_modecd'],
            'DclcusFlag' => $headInfo['dclcus_flag'],
            'StshipTrsarvNatcd' => $headInfo['stship_trsarv_natcd'],//起运抵运国
            'MtpckEndprdMarkcd' => $headInfo['mtpck_endprd_markcd'],
            'ImpexpMarkcd' => $headInfo['impexp_markcd'],
            'ImpexpPortcd' => $headInfo['impexp_portcd'],
            'DclPlcCuscd' => $headInfo['DclPlcCuscd'], //申报地海关丢失
            'GenDecFlag' => $headInfo['gen_dec_flag'],
            'bwl_type' => $headInfo['bwl_type'],
            'InvtType' => $headInfo['invt_type'],
            'bwl_no' => $headInfo['bwl_no'],
            'EntryNo' => $headInfo['entry_no'] ? trim($headInfo['entry_no']) : "",
            'Rmk' => $headInfo['remark'],
            'RcvgdEtpsno' => $headInfo['rcvgd_etps_no'],//固定 企业海关代码 收发货企业信息
            'RvsngdEtpsSccd' => $headInfo['rvsngd_etps_sccd'],//固定企业信用代码
            'RcvgdEtpsNm' => $headInfo['rcvgd_etps_nm'],//企业中文名称
            'RltInvtNo' => $headInfo['rlt_invt_no'],//关联清单编号
            'RltPutrecNo' => $headInfo['rlt_putrec_no'],//关联账册备案编号
            'RltEntryNo' => $headInfo['rlt_entry_no'] ?: '',//关联报关单编号
            'DecType' => $headInfo['dec_type'] ?: '',//报关单类型
            'DclcusTypecd' => $headInfo['dclcus_typecd'] ?: '',//报关类型
            'CorrEntryDclEtpsNo' => $headInfo['corr_entry_dcl_etps_no'] ?: '',//对应报关单申报单位代码
            'CorrEntryDclEtpsNm' => $headInfo['corr_entry_dcl_etps_nm'] ?: '',//对应报关单申报单位名称
            'CorrEntryDclEtpsSccd' => $headInfo['corr_entry_dcl_etps_sccd'] ?: '',//对应报关单申报单位社会统一信用代码
        ];
        $headDiffer = array_diff_uassoc($save, $invList, function ($a, $b) {
            return $a == $b ? 0 : '1';
        });
        $editInfo = [];
        if (!empty($headDiffer)) {
            $editInfo['header'] = $headDiffer;
        }
        Service_InvtList::update($save, $invList['il_id']);
        $invBodyList = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        $bodyList = [];
        foreach ($invBodyList as $body) {
            $bodyList[$body['GdsSeqno']] = $body;
        }
        foreach ($bodyInfo as $key => $value) {
            $invBodyInfo = $bodyList[$value['gds_seqno']] ? $bodyList[$value['gds_seqno']] : [];
            $saveBody = [
                'GdsSeqno' => $value['gds_seqno'],
                'PutrecSeqno' => $value['putrec_seqno'],
                'GdsMtno' => $value['gds_mtno'],
                'Gdecd' => $value['gdecd'],
                'GdsNm' => $value['gds_nm'],
                'GdsSpcfModelDesc' => $value['gds_spcf_model_desc'],
                'DclUnitcd' => $value['dcl_unitcd'],
                'LawfUnitcd' => $value['lawf_unitcd'],
                'SecdLawfUnitcd' => $value['secd_lawf_unitcd'],
                'Natcd' => $value['natcd'],
                'DclUprcAmt' => $value['dcl_uprc_amt'],
                'DclTotalAmt' => $value['dcl_total_amt'],
                'UsdStatTotalAmt' => empty($value['usd_stat_total_amt']) ? 0 : $value['usd_stat_total_amt'],
                'DclCurrcd' => $value['dcl_currcd'],
                'LawfQty' => $value['lawf_qty'],
                'SecdLawfQty' => $value['secd_lawf_qty'],
                'WtSfVal' => empty($value['wt_sf_val']) ? 0 : $value['wt_sf_val'],
                'FstSfVal' => empty($value['fst_sf_val']) ? 0 : $value['fst_sf_val'],
                'SecdSfVal' => empty($value['secd_sf_val']) ? 0 : $value['secd_sf_val'],
                'DclQty' => $value['dcl_qty'],
                'GrossWt' => $value['gross_wt'],
                'NetWt' => $value['net_wt'],
                'UseCd' => empty($value['use_cd']) ? 0 : $value['use_cd'],
                'LvyrlfModecd' => $value['lvyrlf_modecd'],
                'UcnsVerno' => $value['ucns_verno'],
                'EntryGdsSeqno' => $value['entry_gds_seqno'],
                // 'ClyMarkcd'=>$value['cly_markcd'],
                'ApplyTbSeqno' => empty($value['apply_tb_seqno']) ? '' : $value['apply_tb_seqno'],
                'DestinationNatcd' => $value['destination_natcd'],
                'ModfMarkcd' => 3,
                'Rmk' => $value['rmk'],
                'product_id' => $value['product_id'] ?: '',
            ];
            if ($invBodyInfo) {
                $bodyDiffer = array_diff_uassoc($saveBody, $invBodyInfo, function ($a, $b) {
                    return $a == $b ? 0 : '1';
                });
                unset($bodyList[$value['gds_seqno']]);
                if ($bodyDiffer) {
                    foreach ($bodyDiffer as $key => $value) {
                        $bodyDiffer[$key . '_prev'] = $invBodyInfo[$key];
                    }
                    Service_InvtListBody::update($saveBody, $invBodyInfo['ilb_id']);
                }
            } else {
                $saveBody['il_id'] = $headInfo['il_id'];
                Service_InvtListBody::add($saveBody);
                $bodyDiffer = $saveBody;
            }
            if ($bodyDiffer) {
                $editInfo['body'][] = $bodyDiffer;
            }
        }
        if (!empty($bodyList)) {
            foreach ($bodyList as $list) {
                Service_InvtListBody::delete($list['ilb_id']);
            }
            $editInfo['delete'] = $bodyList;
        }
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '编辑',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invList['status'],
            'status_to' => $invList['status'],
            'edite_info' => json_encode($editInfo),
            'operater' => Service_User::getUserId()
        ];
        Service_InvtListLog::add($log);
        return $invList['EtpsInnerInvtNo'];
    }

    /**
     * Note:反填核注清单账册号
     * User: Yao
     * Date: 2020/9/2
     * Time: 16:23
     * @param $headInfo
     * @param $bodyInfo
     * @return mixed
     */
    public function reFillRecodeNo($headInfo, $bodyInfo)
    {
        $invList = Service_InvtList::getByField($headInfo['il_id']);
        $save = [
            'DclTypecd' => $headInfo['dcl_typecd'],
            'BizopEtpsno' => $headInfo['bizop_etps_no'],//经营企业编号
            'BizopEtpsNm' => $headInfo['bizop_etps_nm'],//经营企业名称
            'BizopEtpsSccd' => $headInfo['bizop_etps_sccd'],//经营企业社会信用代码
            // 'DclEtpsSccd'=>$headInfo['dcl_etps_sccd'],//申报企业社会信用代码
            'SupvModecd' => $headInfo['supv_modecd'],//监管方式代码
            'TrspModecd' => $headInfo['trsp_modecd'],
            'DclcusFlag' => $headInfo['dclcus_flag'],
            'StshipTrsarvNatcd' => $headInfo['stship_trsarv_natcd'],//起运抵运国
            'MtpckEndprdMarkcd' => $headInfo['mtpck_endprd_markcd'],
            'ImpexpMarkcd' => $headInfo['impexp_markcd'],
            'ImpexpPortcd' => $headInfo['impexp_portcd'],
            'GenDecFlag' => $headInfo['gen_dec_flag'],
            'bwl_type' => $headInfo['bwl_type'],
            'InvtType' => $headInfo['invt_type'],
            'bwl_no' => $headInfo['bwl_no'],
            'Rmk' => $headInfo['remark'],
            'RcvgdEtpsno' => $headInfo['rcvgd_etps_no'],//固定 企业海关代码 收发货企业信息
            'RvsngdEtpsSccd' => $headInfo['rvsngd_etps_sccd'],//固定企业信用代码
            'RcvgdEtpsNm' => $headInfo['rcvgd_etps_nm'],//企业中文名称
            'RltInvtNo' => $headInfo['rlt_invt_no'],//关联清单编号
            'RltPutrecNo' => $headInfo['rlt_putrec_no'],//关联账册备案编号
            'RltEntryNo' => $headInfo['rlt_entry_no'] ?: '',//关联报关单编号
            'BondInvtNo' => $headInfo['bound_invt_no'] ?: '',
            'DecType' => $headInfo['dec_type'] ?: '',//报关单类型
            'DclcusTypecd' => $headInfo['dclcus_typecd'] ?: '',//报关类型
            'CorrEntryDclEtpsNo' => $headInfo['corr_entry_dcl_etps_no'] ?: '',//对应报关单申报单位代码
            'CorrEntryDclEtpsNm' => $headInfo['corr_entry_dcl_etps_nm'] ?: '',//对应报关单申报单位名称
            'CorrEntryDclEtpsSccd' => $headInfo['corr_entry_dcl_etps_sccd'] ?: '',//对应报关单申报单位社会统一信用代码
        ];
        $headColumn = [
            'BondInvtNo' => '清单编号',
            'SeqNo' => '清单预录入统一编号',
            'PutrecNo' => '备案编号',
            'EtpsInnerInvtNo' => '企业内部清单编号',
            'BizopEtpsSccd' => '经营企业社会信用代码',
            'BizopEtpsno' => '经营企业编号',
            'BizopEtpsNm' => '经营企业名称',
            'RcvgdEtpsno' => '收货企业编号',
            'RvsngdEtpsSccd' => '收发货企业社会信用代码',
            'RcvgdEtpsNm' => '收货企业名称',
            'DclEtpsSccd' => '申报企业社会信用代码',
            'DclEtpsno' => '申报企业编号',
            'DclEtpsNm' => '申报企业名称',
            'InvtDclTime' => '清单申报时间',
            'EntryDclTime' => '报关单申报日期',
            'EntryNo' => '对应报关单编号',
            'RltInvtNo' => '关联清单编号',
            'RltPutrecNo' => '关联备案编号',
            'RltEntryNo' => '关联报关单编号',
            'RltEntryBizopEtpsSccd' => '关联报关单境内收发货人社会信用代码',
            'RltEntryBizopEtpsno' => '关联报关单境内收发货人编号',
            'RltEntryBizopEtpsNm' => '关联报关单境内收发货人名称',
            'RltEntryRvsngdEtpsSccd' => '关联报关单收发货单位社会统一信用代码',
            'RltEntryRcvgdEtpsno' => '关联报关单海关收发货单位编码',
            'RltEntryRcvgdEtpsNm' => '关联报关单收发货单位名称',
            'RltEntryDclEtpsSccd' => '关联报关单申报单位社会统一信用代码',
            'RltEntryDclEtpsno' => '关联报关单海关申报单位编码',
            'RltEntryDclEtpsNm' => '关联报关单申报单位名称',
            'ImpexpPortcd' => '进出境关别',
            'DclPlcCuscd' => '申报地关区代码',
            'ImpexpMarkcd' => '进出口标记代码',
            'MtpckEndprdMarkcd' => '料件成品标记代码',
            'SupvModecd' => '监管方式代码',
            'TrspModecd' => '运输方式代码',
            'DclcusFlag' => '是否报关标志',
            'DclcusTypecd' => '报关类型代码',
            'VrfdedMarkcd' => '核扣标记代码',
            'InvtIochkptStucd' => '清单进出卡口状态代码',
            'PrevdTime' => '预核扣时间',
            'FormalVrfdedTime' => '正式核扣时间',
            'ApplyNo' => '申请表编号',
            'ListType' => '流转类型',
            'InputCode' => '录入企业编号',
            'InputCreditCode' => '录入企业社会信用代码',
            'InputName' => '录入单位名称',
            'IcCardNo' => '申报人IC卡号',
            'InputTime' => '录入日期',
            'ListStat' => '清单状态',
            'CorrEntryDclEtpsSccd' => '对应报关单申报单位社会统一信用代码',
            'CorrEntryDclEtpsNo' => '对应报关单申报单位代码',
            'CorrEntryDclEtpsNm' => '对应报关单申报单位名称',
            'DecType' => '报关单类型',
            'StshipTrsarvNatcd' => '起运/运抵国(地区）',
            'InvtType' => '清单类型',
            'EntryStucd' => '报关状态',
            'PassportUsedTypeCd' => '核放单生成标志代码',
            'Rmk' => '备注',
            'DclTypecd' => '申报类型',
            'NeedEntryModified' => '报关单同步修改标志',
            'LevyBlAmt' => '计征金额',
            'ChgTmsCnt' => '变更次数',
        ];
        $headDiffer = array_diff_uassoc($save, $invList, function ($a, $b) {
            return $a == $b ? 0 : '1';
        });
        $editInfo = [];
        $contEdit = [];
        if (!empty($headDiffer)) {
            foreach ($headDiffer as $col => $value) {
                $contEdit[] = $headColumn[$col];
            }
            throw new Exception(implode(',', $contEdit) . '内容不可修改');
        }
        $invBodyList = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        $bodyList = [];
        foreach ($invBodyList as $body) {
            $bodyList[$body['GdsSeqno']] = $body;
        }
        if (count($bodyInfo) != count($invBodyList)) {
            throw new Exception('表体信息不能增加或则减少');
        }

        foreach ($bodyInfo as $key => $value) {
            $invBodyInfo = $bodyList[$value['gds_seqno']] ? $bodyList[$value['gds_seqno']] : [];
            $saveBody = [
                'PutrecSeqno' => $value['putrec_seqno'],
            ];
            if ($invBodyInfo) {
                $bodyDiffer = array_diff_uassoc($saveBody, $invBodyInfo, function ($a, $b) {
                    return $a == $b ? 0 : '1';
                });
                if ($bodyDiffer) {
                    if ($invBodyInfo['PutrecSeqno']) {
                        throw new Exception('序号:' . $value['gds_seqno'] . '已存在备案号，不能更改');
                    }
                    foreach ($bodyDiffer as $key => $value) {
                        $bodyDiffer[$key . '_prev'] = $invBodyInfo[$key];
                    }
                    Service_InvtListBody::update($saveBody, $invBodyInfo['ilb_id']);
                }
                $editInfo['body'][] = $bodyDiffer;
            } else {
                throw new Exception('程序错误');
            }
        }
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '反填备案序号',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invList['status'],
            'status_to' => $invList['status'],
            'edite_info' => json_encode($editInfo),
            'operater' => Service_User::getUserId()
        ];
        Service_InvtListLog::add($log);
        return $invList['EtpsInnerInvtNo'];
    }

    /**
     * Note:核注清单确认
     * User: Yao
     * Date: 2020/8/8
     * Time: 10:16
     * @param $invList
     * @throws Exception
     */
    public function confirm($invList)
    {
        $invListBody = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        if (empty($invListBody)) {
            throw new Exception('核注清单内容为空');
        }
        $invlist = Service_InvtList::getForLock($invList['il_id']);
        if ($invList['status'] != 1 && $invList['status'] != 3) {
            throw new Exception('核注清单状态不正确，无法确认');
        }
        $billStock = new Process_BillBook();
        try {
            if ($invList['ImpexpMarkcd'] == "E") {
                //出口
                if ($invList['InvtType'] == '8') {//BBC订单核注确认
                    /*$updateCount = Service_InvtOrderSb::updateByCondition([
                        'ios_status'=>1
                    ],[
                        'EtpsInnerInvtNo'=>$invList['EtpsInnerInvtNo'],
                        'ios_status_neq'=>4
                    ]);
                    if(!$updateCount){
                        throw new Exception('订单申报状态修改失败');
                    }*/
                    throw new Exception("保税电商模式暂时不可用");
                } else {
                    $bgHeadInfo = Service_BgPriEntryDataDetailBodyHead::getByField($invList['EtpsInnerInvtNo'],'inv_no');
                    $invtManifestInvt = Service_InvtManifiestInvt::getByField($invList['EtpsInnerInvtNo'], 'etps_inner_invt_no');
                    $lockQuantityCondition = true;
                    if ($invtManifestInvt) {
                        // $invtManifest = Service_InvtManifiest::getByField($invtManifestInvt['im_id']);
                        // if($invtManifest['im_type'] ==2){
                        //     $lockQuantityCondition =false;
                        // }
                    }
                    //一日游的不操作库存
                    if($bgHeadInfo && ($bgHeadInfo['pt_code'] == 'IN1D'||$bgHeadInfo['pt_code'] == 'EN1D'||$bgHeadInfo['pt_code'] == 'EN1D-J')){
                        $lockQuantityCondition = false;
                    }
                    if ($lockQuantityCondition) {
                        foreach ($invListBody as $body) {
                            $billStock->setReferenceNo($invList['EtpsInnerInvtNo'])
                                ->setNote('核注清单确认')
                                ->setBillBookFromNo($body['PutrecSeqno'], $invlist['PutrecNo'])
                                ->lockQuantity($body['DclQty']);
                        }
                    }
                }
                Service_InvtList::update([
                    'status' => 2,
                ], $invList['il_id']);
                $log = [
                    'il_id' => $invList['il_id'],
                    'note' => '确认',
                    'add_time' => date("Y-m-d H:i:s"),
                    'status_from' => '1',
                    'status_to' => '2',
                    'operater' => Service_User::getUserId()
                ];
                Service_InvtListLog::add($log);
                $sendRes = $this->sendXml($invlist, $invListBody);
                if ($sendRes['state'] != 1) {
                    throw new Exception($sendRes['message']);
                }
            } elseif ($invList['ImpexpMarkcd'] == "I") {
                // foreach ($invListBody as $body) {
                //    if(empty($body['PutrecSeqno'])){
                //        throw new Exception('备案序号不完整');
                //    }
                // }
                $sendRes = $this->sendXml($invlist, $invListBody);
                if ($sendRes['state'] != 1) {
                    throw new Exception($sendRes['message']);
                }
                Service_InvtList::update([
                    'status' => 2,
                ], $invList['il_id']);
                $log = [
                    'il_id' => $invList['il_id'],
                    'note' => '确认',
                    'add_time' => date("Y-m-d H:i:s"),
                    'status_from' => '1',
                    'status_to' => '2',
                    'operater' => Service_User::getUserId()
                ];
                Service_InvtListLog::add($log);
            } else {
                throw new Exception('数据不正确');
            }
            return true;
        } catch (Exception $e) {
            Service_InvtList::update([
                'status' => 3,
            ], $invList['il_id']);
            $log = [
                'il_id' => $invList['il_id'],
                'note' => '确认失败' . $e->getMessage(),
                'add_time' => date("Y-m-d H:i:s"),
                'status_from' => $invlist['status'],
                'status_to' => '3',
                'operater' => Service_User::getUserId()
            ];
            Service_InvtListLog::add($log);
            return $e->getMessage();
        }
    }

    public function complete($invList)
    {
        $invListBody = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        if (empty($invListBody)) {
            throw new Exception('核注清单内容为空');
        }
        $invlist = Service_InvtList::getForLock($invList['il_id']);
        if ($invList['status'] != 2) {
            throw new Exception('核注清单不是确认状态，无法完成');
        }
        $billStock = new Process_BillBook();
        if ($invlist['ImpexpMarkcd'] == 'E' && $invList['InvtType'] == '8') {
            $invOrderSb = Service_InvtOrderSb::getByCondition([
                'EtpsInnerInvtNo' => $invList['EtpsInnerInvtNo'],
                'osb_type' => 1,
                'ios_status_neq' => 4
            ]);
            foreach ($invOrderSb as $invOrder) {
                Service_OrderExtra::update([
                    'destroy_status' => 1,
                    'update_time' => date("Y-m-d H:i:s"),
                ], $invOrder['order_code'], 'order_code');
                Service_InvtOrderSb::update([
                    'ios_status' => 5,
                ], $invOrder['ios_id']);
                $orderInfo = Service_Orders::getByField($invOrder['order_code'], 'order_code');
                if (in_array($orderInfo['order_declare_mode'], Common_DeclareModel::getdecalareNoInventory())) {
                    Service_Orders::update([
                        'order_status' => 12,
                        'update_time' => date("Y-m-d H:i:s")
                    ], $orderInfo['order_id']);
                    Service_OrderLog::log($orderInfo['order_id'], $orderInfo['order_code'], $orderInfo['order_status'], 12, 0, '订单出区核注');
                }
                $zsClearance = Service_ZsClearanceHead::getByField($invOrder['order_code'], 'order_code');
                if (empty($zsClearance)) {
                    throw  new Exception('订单' . $invOrder['order_code'] . '没有申报记录信息');
                }
                $zsClearanceBody = Service_ZsClearanceBody::getByCondition([
                    'zch_id' => $zsClearance['zch_id']
                ]);
                foreach ($zsClearanceBody as $zb) {
                    $billStock->setReferenceNo($invOrder['order_code'])
                        ->setNote('核注清单完成')
                        ->setBillBookFromNo($zb['item_record_no'], $invlist['PutrecNo'])
                        ->bbcDestory($zb['qty']);
                }
            }
        } else {
            $bgHeadInfo = Service_BgPriEntryDataDetailBodyHead::getByField($invList['EtpsInnerInvtNo'],'inv_no');
            //一日游的不操作库存
            if($bgHeadInfo && ($bgHeadInfo['pt_code'] == 'IN1D'||$bgHeadInfo['pt_code'] == 'EN1D'||$bgHeadInfo['pt_code'] == 'EN1D-J')){
                $this->addProductRecode($invListBody,$invlist);
            }else{
                $this->billDeal($invListBody,$invlist,$billStock);
            }

        }
        Service_InvtList::update([
            'status' => 4,
        ], $invList['il_id']);
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '完成',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invlist['status'],
            'status_to' => '4',
            'operater' => Service_User::getUserId()
        ];
        Service_InvtListLog::add($log);
        return true;
    }

    /**
     * @date 2022/7/18
     * @todo 账册库存入账或者核扣
     * @auther 46935
     * @param $invListBody
     * @param $invlist
     * @throws Exception
     */
    private function billDeal($invListBody,$invlist,$billStock){
        foreach ($invListBody as $body) {
            if ($invlist['ImpexpMarkcd'] == 'E') {
                //出口核注的，转账册需要把核注状态改为已核注
                // $invOrderSb = Service_InvtOrderSb::getByCondition([
                //     'EtpsInnerInvtNo'=>$invList['EtpsInnerInvtNo'],
                //     'osb_type'=>3,
                //     'ios_status_neq'=>4
                // ]);
                // if(!empty($invOrderSb)){
                //     foreach ($invOrderSb as $invOrder){
                //         Service_OrderExtra::update([
                //             'destroy_status'=>1,
                //             'update_time'=>date("Y-m-d H:i:s"),
                //         ],$invOrder['order_code'],'order_code');
                //     }
                // }
                $billStock->setReferenceNo($invlist['EtpsInnerInvtNo'])
                    ->setNote('核注清单完成')
                    ->setBillBookFromNo($body['PutrecSeqno'], $invlist['PutrecNo'])
                    ->destory($body['DclQty']);
            } elseif ($invlist['ImpexpMarkcd'] == 'E' && $invlist['InvtType'] == '8') {//核注清单，bbc申报
                // $billStock->setReferenceNo($invList['EtpsInnerInvtNo'])
                //     ->setNote('核注清单BBC完成')
                //     ->setBillBookFromNo($body['PutrecSeqno'])
                //     ->bbcDestory($body['DclQty']);
            } elseif ($invlist['ImpexpMarkcd'] == 'I') {
                if (empty($body['PutrecSeqno'])) {
                    throw new Exception('备案序号不完整');
                }
                $invOrderSb = Service_InvtOrderSb::getByCondition([
                    'EtpsInnerInvtNo' => $invlist['EtpsInnerInvtNo'],
                    'osb_type' => 5,
                    'ios_status_neq' => 4
                ]);
                if (!empty($invOrderSb)) {
                    foreach ($invOrderSb as $order) {
                        Service_ReceivingReturnOrder::update([
                            'invt_status' => 1,
                        ], $order['order_code'], 'order_code');
                    }
                }
                $this->inBill($body, $invlist);
            }
        }
    }

    /**
     * @date 2022/7/18
     * @todo 一日游商品记录海关返回账册号
     * @auther 46935
     * @param $invListBody
     * @param $invlist
     * @throws Exception
     */
    protected function addProductRecode($invListBody,$invlist){
        $tradeName = "";
        $tradeCode = "";
        //查找预录入数据的生产销售企业信息
        if($invlist['bpedbh_id']>0){
            $bpedbHead = Service_BgPriEntryDataDetailBodyHead::getByField($invlist['bpedbh_id'],'bpedbh_id');
            $tradeName = $bpedbHead['owner_name'];
            $tradeCode = $bpedbHead['owner_code'];
        }

        foreach ($invListBody as $body) {
           if ($invlist['ImpexpMarkcd'] == 'I') {
                if (empty($body['PutrecSeqno'])) {
                    throw new Exception('备案序号不完整');
                }
                $this->addBgProduct($body, $tradeName,$tradeCode);
            }
        }
    }
    protected function addBgProduct($body,$tradeName,$tradeCode){
        $bgProductAdd =[
            'customer_name'=>$tradeName,
            'trade_co'=>$tradeCode,
            'gmodel'=>$body['GdsSpcfModelDesc'],
            'gname'=>$body['GdsNm'],
            'hs_code'=>$body['Gdecd'],
            'origin_country'=>$body['Natcd'],
            'goods_id'=>$body['GdsMtno'],
            'gunit'=>$body['DclUnitcd'],
            'first_unit'=>$body['LawfUnitcd'],
            'second_unit'=>$body['SecdLawfUnitcd'],
            'contr_item'=>$body['PutrecSeqno'],
            'add_time'=>date("Y-m-d H:i:s",time())
        ];
        if(empty($bgProductAdd['contr_item'])){
            throw new Exception('备案序号为空');
        }
        $check = Service_BgProduct::getByCondition([
            'trade_co'=>$tradeCode,
            'goods_id'=>$bgProductAdd['goods_id'],
            'contr_item'=>$bgProductAdd['contr_item']
        ]);
        if(!$check){
            $productId = Service_BgProduct::add($bgProductAdd);
            return $productId;
        }
        return 0;

    }

    /**
     * Note:清单取消
     * User: Yao
     * Date: 2020/8/10
     * Time: 11:56
     * @param $invList
     * @return bool
     * @throws Exception
     */
    public function concel($invList)
    {
        $invListBody = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        if (empty($invListBody)) {
            throw new Exception('核注清单内容为空');
        }
        $invlist = Service_InvtList::getForLock($invList['il_id']);
        if ($invList['status'] != 2) {
            throw new Exception('核注清单不是确认状态，无法取消');
        }
        $invtManifestInvt = Service_InvtManifiestInvt::getByField($invlist['EtpsInnerInvtNo'], 'etps_inner_invt_no');
        if (!empty($invtManifestInvt)) {
            $invtOrderSb = Service_InvtOrderSb::getByCondition([
                'im_id' => $invtManifestInvt['im_id'],
            ]);
            foreach ($invtOrderSb as $orderSb) {
                Service_InvtOrderSb::update([
                    'ios_status' => '4'
                ], $orderSb['ios_id']);
            }
        }
        $billStock = new Process_BillBook();
        foreach ($invListBody as $body) {
            if ($invlist['ImpexpMarkcd'] == 'E') {
                if ($invList['InvtType'] == '8') {
                    Service_InvtOrderSb::updateByCondition([
                        'ios_status' => 4
                    ], [
                        'EtpsInnerInvtNo' => $invList['EtpsInnerInvtNo'],
                        'ios_status_neq' => 4
                    ]);
                } else {
                    //一日游都没有冻结库存把一日游的情况取消
                    $bgHeadInfo = Service_BgPriEntryDataDetailBodyHead::getByField($invList['EtpsInnerInvtNo'],'inv_no');
                    $invtManifestInvt = Service_InvtManifiestInvt::getByField($invList['EtpsInnerInvtNo'], 'etps_inner_invt_no');
                    $unlockQuantity = true;
                    if($bgHeadInfo && ($bgHeadInfo['pt_code'] == 'IN1D'||$bgHeadInfo['pt_code'] == 'EN1D'||$bgHeadInfo['pt_code'] == 'EN1D-J')){
                        $unlockQuantity = false;
                    }
                    if($unlockQuantity){
                        $billStock->setReferenceNo($invList['EtpsInnerInvtNo'])
                            ->setNote('核注清单取消')
                            ->setBillBookFromNo($body['PutrecSeqno'], $invlist['PutrecNo'])
                            ->unlockQuantity($body['DclQty']);
                    }
                }
            }
        }
        Service_InvtList::update([
            'status' => 0,
        ], $invList['il_id']);
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '取消',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invlist['status'],
            'status_to' => '0',
            'operater' => Service_User::getUserId(),
        ];
        Service_InvtListLog::add($log);
        return true;
    }
    /**
     * @todo 核注单删除（草稿状态下删除核注单，取消状态和预录入数据的取消）
     */
    public function delete($invList){
        $invListBody = Service_InvtListBody::getByCondition([
            'il_id' => $invList['il_id']
        ]);
        if (empty($invListBody)) {
            throw new Exception('核注清单内容为空');
        }
        $invlist = Service_InvtList::getForLock($invList['il_id']);
        if ($invList['status'] != 1) {
            throw new Exception('核注清单不是草稿状态，无法删除');
        }
        $invtManifestInvt = Service_InvtManifiestInvt::getByField($invlist['EtpsInnerInvtNo'], 'etps_inner_invt_no');
        if (!empty($invtManifestInvt)) {
            $invtOrderSb = Service_InvtOrderSb::getByCondition([
                'im_id' => $invtManifestInvt['im_id'],
            ]);
            foreach ($invtOrderSb as $orderSb) {
                Service_InvtOrderSb::update([
                    'ios_status' => '4'
                ], $orderSb['ios_id']);
            }
        }

        if($invlist['bpedbh_id']>0){
            $bgedh = Service_BgPriEntryDataDetailBodyHead::getByField($invlist['bpedbh_id'],'bpedbh_id');
            //更新信息
            if(!empty($bgedh)){
                if($bgedh['inv_no']==$invlist['EtpsInnerInvtNo']){
                    $preDataHeadUpdate = array(
                        'hz_status'=>'-1',
                        'inv_no'=>''
                    );
                    Service_BgPriEntryDataDetailBodyHead::update($preDataHeadUpdate,$bgedh['bpedbh_id'],'bpedbh_id');
                    //添加日志
                    $detailLog = array(
                        'bped_id'=>$bgedh['bped_id'],
                        'bpedbh_id'=>$bgedh['bpedbh_id'],
                        'change_status'=>'bg_status',
                        'status_from'=>$bgedh['bg_status'],
                        'status_to'=>'-1',
                        'ip'=>Common_Common::getIP(),
                        'content'=>"核注单草稿到删除,更新预录入数据状态",
                    );
                    Service_BgPriEntryDataDetailLog::add($detailLog);
                }
            }
        }

        Service_InvtList::update([
            'status' => 0,
        ], $invList['il_id']);
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '取消',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invlist['status'],
            'status_to' => '0',
            'operater' => Service_User::getUserId(),
        ];
        Service_InvtListLog::add($log);
        return true;
    }
    /**
     * Note:入底账，海关账册
     * User: Yao
     * Date: 2020/8/13
     * Time: 10:56
     * @param $bodyInfo
     * @param $invList
     */
    protected function inBill($bodyInfo, $invList)
    {
        $user = new Zend_Session_Namespace('userAuthorization');
        $billBook = Service_BillBook::getByCondition([
            'recorde_no' => $bodyInfo['PutrecSeqno'],
            'warehous_account_no' => $invList['bwl_no'],
        ]);
        if (empty($billBook)) {
            $billBookAdd = [
                'warehous_account_no' => $invList['bwl_no'],
                'recorde_no' => $bodyInfo['PutrecSeqno'],
                'product_title' => $bodyInfo['GdsNm'],
                'goods_code' => $bodyInfo['GdsMtno'],
                'hs_code' => $bodyInfo['Gdecd'],
                'specification' => $bodyInfo['GdsSpcfModelDesc'],
                'country_code' => $bodyInfo['Natcd'],
                'decalare_unit' => $bodyInfo['DclUnitcd'],
                'legal_unit' => $bodyInfo['LawfUnitcd'],
                'second_legal_unit' => $bodyInfo['SecdLawfUnitcd'],
                'decalar_price' => $bodyInfo['DclUprcAmt'],
                'decalar_currency' => $bodyInfo['DclCurrcd'],
                'total_dollar_price' => $bodyInfo['UsdStatTotalAmt'],
                'in_quantity' => $bodyInfo['DclQty'],
                'in_legal_quantity' => $bodyInfo['LawfQty'],
                'in_seconde_legal_quantity' => $bodyInfo['SecdLawfQty'],
                'real_increa_quantity' => $bodyInfo['DclQty'],
                'real_reduce_quantity' => 0,
                'pre_increa_quantity' => $bodyInfo['DclQty'],
                'bill_serial' => $bodyInfo['GdsSeqno'],
                'stock_quantity' => $bodyInfo['DclQty'],
                'ie_port' => 'I',
                'bill_time' => date("Y-m-d H:i:s"),
                'total_price' => $bodyInfo['DclTotalAmt'],
                'add_time' => date("Y-m-d H:i:s"),
                'can_use_quantity' => $bodyInfo['DclQty'],
            ];
            $id = Service_BillBook::add($billBookAdd);
            $ip = Common_Common::getRealIp();
            if (empty($ip)) {
                $ip = '127.0.0.1';
            }
            $log = array(
                'sys_add_time' => date("Y-m-d H:i:s"),
                'operator_ip' => $ip,
                'operator_id' => $user->userId == '' ? '0' : $user->userId,
                'goods_id' => $billBookAdd['goods_code'],
                'bill_book_id' => $id,
                'json_row' => json_encode($billBookAdd)
            );
            Service_BillBookLog::add($log);
            $productInfo = Service_Product::getByField($bodyInfo['GdsMtno'], 'goods_id');
            $biilProuduct = array(
                'product_sku' => $productInfo['product_sku'],
                'product_id' => $productInfo['product_id'],
                'customer_code' => $productInfo['customer_code'],
                'add_time' => date("Y-m-d H:i:s"),
                'bill_book_id' => $id,
            );
            Service_BillBookProduct::add($biilProuduct);
            Service_BillStockLog::add([
                'warehous_account_no' => $invList['bwl_no'],
                'recode_no' => $bodyInfo['PutrecSeqno'],
                'incre_quantity' => $bodyInfo['DclQty'],
                'reference_no' => $invList['EtpsInnerInvtNo'],
                'add_time' => date("Y-m-d H:i:s"),
                'note' => '添加新账册,核增库存',
            ]);
        } else {
            $billStock = new Process_BillBook();
            $billStock->setBillBookFromId($billBook[0]['id']);
            $billStock->setReferenceNo($invList['EtpsInnerInvtNo'])->setNote('核注清入区完成')->increQuanity($bodyInfo['DclQty']);
        }

    }

    public function sendXml($invtList, $invListBody)
    {
        // return [
        //     'state'=>'1',
        //     'message'=>'发送综保系统成功'
        // ];
        $return = array(
            'state'=>'1',
            'message'=>'发送消息成功'
        );
        try{
            $xml = new Api_Inv_Xml();
            $invHead = new Api_Inv_InvtHeadType();
            $invHead->setFromArray($invtList);
            $xml->setInvtHeadType($invHead);
            $xml->setEtpsInnerInvtNo($invtList['EtpsInnerInvtNo']);
            foreach ($invListBody as $body) {
                $invtListType = new Api_Inv_InvtListType();
                $invtListType->setFromArray($body);
                $xml->addInvtListType($invtListType);
            }
            $invSbOrder = Service_InvtOrderSb::getByCondition([
                'EtpsInnerInvtNo' => $invtList['EtpsInnerInvtNo'],
                'ios_status_neq' => 4
            ]);
            if (!empty($invSbOrder)) {
                foreach ($invSbOrder as $invOrder) {
                    $invCbecBillType = new Api_Inv_InvtCbecBillType();
                    $invCbecBillType->setFromArray([
                        'SeqNo' => '',
                        'BondInvtNo' => $invtList['EtpsInnerInvtNo'],
                        'CbecBillNo' => $invOrder['form_id_port'],
                    ]);
                    $xml->addInvtCbecBill($invCbecBillType);
                }
            }
            $xml->setDelcareFlag($this->sendZb);
            //$xmlString = $xml->toXml();
            $xmlString = $xml->toSingleXml();

            //查找预录入数据,若是直接写入核注单的没有这个传送公司数据（若是单个公司使用默认一个若是多个企业使用可以界面做上让选择企业的）
            $bgHead = Service_BgPriEntryDataDetailBodyHead::getByField($invtList['EtpsInnerInvtNo'], 'inv_no');
            $company_code = "ZH-WXT";//为空暂时默认一个公司
            $res = [];
            if (!empty($bgHead)) {
                $bgpreData = Service_BgPriEntryData::getByField($bgHead['bped_id']);
                if (!empty($bgpreData)) {
                    $company_code = $bgpreData['company_code'];
                }
            }
            if($company_code!=''){
                $bgCompany = Service_BgCompany::getByField($company_code, 'company_code');
                if (!empty($bgCompany)) {
                    $resourceRow = json_decode($bgCompany['config_value'], true);
                    if (!empty($resourceRow)) {
                        $res = $resourceRow['inv']['send'];
                    }
                }
            }

            $path = APPLICATION_PATH . '/../data/baoguan/invt/' . date('Ymd') . '/';
            if (!is_dir($path)) {
                mkdir($path, 0777, true);
            }
            $name = "INV101." . time() . "." . $invtList['il_id'] . ".xml";
            $filePath = $path . $name;
            file_put_contents($filePath, $xmlString);
            //压缩成zip
            //$zipFileStream = file_get_contents($filePath,false,null);
            $zipFileName = $path.$name.".zip";
            //file_put_contents($zipFileName,$zipFileStream);
            $zip = new ZipArchive();
            if ($zip->open($zipFileName,\ZipArchive::CREATE) === TRUE)
            {
                $zip->addFile($filePath,basename($filePath));
                $zip->close();
            }else{
                throw new Exception("生成压缩zip的核住失败");
            }
           // unlink($zipFileName);

            $aMessage['fmt_code'] = 'inv';
            $aMessage['fmt_type'] = 'inv';
            $aMessage['refercence_no'] = $invtList['EtpsInnerInvtNo'];
            $aMessage['fml_status'] = 2;
            $aMessage['fml_add_time'] = date('Y-m-d H:i:s');
            $aMessage['company_code'] = $company_code;
            $aMessage['fml_path'] = $zipFileName;
            Service_FtpMessageSendlist::add($aMessage);

            $sendApi = new Inv($res);
            $result = $sendApi->send($zipFileName);
            if(empty($result)||$result!==true){
                throw new Exception("发送到ftp服务器失败");
            }
        }catch (Exception $e){
            $return['state'] = 0;
            $return['message'] = $e->getMessage();
        }
        return $return;
    }

    /**
     * Note:退回草稿
     * User: Yao
     * Date: 2020/11/20
     * Time: 16:14
     */
    public function toDraft($invList)
    {
        if (!($invList['ImpexpMarkcd'] == 'E' && $invList['InvtType'] == '8')) {
            throw new Exception('非BBC保税电商核注清单，无法操作');
        }
        Service_InvtOrderSb::updateByCondition([
            'ios_status' => -1
        ], [
            'EtpsInnerInvtNo' => $invList['EtpsInnerInvtNo'],
            'ios_status_neq' => 4
        ]);
        Service_InvtList::update([
            'status' => 1,
        ], $invList['il_id']);
        $log = [
            'il_id' => $invList['il_id'],
            'note' => '退回草稿',
            'add_time' => date("Y-m-d H:i:s"),
            'status_from' => $invList['status'],
            'status_to' => '1',
            'operater' => Service_User::getUserId(),
        ];
        Service_InvtListLog::add($log);
        return true;

    }
}