<?php

namespace App\models\Logistic\Pri;

use Pheanstalk\Exception;
use \Service_Receiving;
use \Service_ReceivingDetail;
use \Service_Product;
use \Service_BgPriEntryData;
use \Service_BgPriEntryDataDetail;
use \Common_GetNumbers;
use \Service_BgPriEntryDataDetailBodyHead;
use \Service_BgPriEntryDataDetailBodyDetail;
use \Service_BgPriEntryDataDetailLog;
use \Service_HsUom;
use \Service_HsUomMap;
use \Service_BillBook;
use \Service_BillBookProduct;
use \Service_BgCompany;
use \Process_CisBaoguanDanUpload;

class PriPreData extends PriEnter
{
    protected $baoguanFile = [];
    protected $xlsPaser;
    protected $tmpReceivingInfo;

    public function __construct()
    {
        $this->xlsPaser = new Process_CisBaoguanDanUpload();
    }


    public function addReceivingCode($receivingCode)
    {
        $receivingInfo = Service_Receiving::getByField($receivingCode, 'receiving_code');
        $file = $receivingInfo['baoguan_file'];
        if (pathinfo($file, PATHINFO_EXTENSION) != 'xls' && pathinfo($file, PATHINFO_EXTENSION) != 'xlsx') {
            throw new Exception('文件必须是Excel格式文件');
        }
        if (!file_exists($file)) {
            throw new Exception('文件不存在');
        }
        $this->baoguanFile[$receivingCode] = $file;
        $this->tmpReceivingInfo[$receivingCode] = $receivingInfo;
    }

    public function setReceivingInfo()
    {
        foreach ($this->baoguanFile as $key => $file) {
            $data = $this->paserFile($file);
            $headInfo = $data['head'];
            $this->receivingInfo[$key] = array_merge($headInfo,[
                'pack_no' => $headInfo['pack_no'],
                'receiving_code' => $key,
                'roughweight' => $headInfo['gross_wt'],
            ]);
            $this->receivingInfo[$key]['detail'] = [];
            foreach ($data['body'] as $body) {
                $productInfo = Service_ReceivingDetail::getJoinProductByCondition([
                    'receiving_code'=>$key,
                    'goods_id' => $body['goods_id']
                ]);
                if (empty($productInfo)) {
                    throw new Exception($body['goods_id'] . '料号对应商品信息不存在');
                }
                $productInfo = $productInfo[0];
                $newBody = [
                    'product_id' => $productInfo['product_id'],
                    'rd_receiving_qty' => $body['gqty'],
                    'receiving_qty' => $body['gqty'],
                ];
                $newBody = array_merge($body, $newBody);
                $this->receivingInfo[$key]['detail'][] = $newBody;
            }

        }
    }

    public function getReceivingInfo($receivingCode)
    {
        $receivingInfo = Service_Receiving::getByField($receivingCode, 'receiving_code');
        $receivingInfo['detail'] = $this->receivingInfo[$receivingCode]['detail'];
        return $receivingInfo;
    }


    protected function receivingSplit()
    {
        $receivingList = $this->receivingInfo;
        $cfnumber = 1;
        foreach ($receivingList as $receiving) {
            $detail = $receiving['detail'];
            $chunk = array_chunk($detail, $this->splitNumber);
            $index = 1;
            $zdnum = count($chunk);
            foreach ($chunk as $chunkDetail) {
                $netWeight = 0;
                $grossWeightProduct = 0;
                $packNumber = 0;
                if($zdnum ==1){
                    $netWeight = $receiving['net_wt'];
                }else {
                    foreach ($chunkDetail as $rd) {
                        $netWeight += $rd['rd_receiving_qty'] * $this->getProductWeight($rd['product_id']);
                        $grossWeightProduct += $rd['rd_receiving_qty'] * $this->getProductGrossWeight($rd['product_id']);
                        $packNumber += $rd['receiving_qty'];
                    }
                }

                $this->priEnterDataDetailBodyDetail[] = $chunkDetail; //表体不对按固定项目拆分表体要存相应的拆分表体
                //总重量
                //$gap = $receiving['receiving_code']['roughweight'] -  $this->weightArr[$receiving['receiving_code']]['totalproductgrossweight'];
                $grossWeight = $receiving['roughweight'];
                $grossWeight = sprintf('%.4f', $grossWeight);
                //var_dump($receiving);

                if ($receiving['pack_no'] < count($chunk)) {
                    $this->error[] = "入库单件数" . $receiving['pack_no'] . "小于报关拆分数:{$zdnum},无法拆分";
                }


                if ($index == 1) {
                    //$pack_number
                    $pack_number = $receiving['pack_no'] - floor($receiving['pack_no'] / $zdnum) * ($zdnum - 1);
                } else {
                    $pack_number = floor($receiving['pack_no'] / $zdnum);
                }

                $this->priEnterHead[] = [
                    'bpd_ref_no' => $receiving['receiving_code'] . '-' . $index,
                    'bpdd_pack_number' => $pack_number,
                    'net_weight' => $netWeight,
                    'gross_weight' => $grossWeight,
                    'num' => $this->cfnumber,
                    'pack_no' => $pack_number,
                    'traf_mode'=>$receiving['traf_mode'],
                    'voyage_no'=>$receiving['voyage_no'],
                    'bill_no'=>$receiving['bill_no'],
                    'wrap_type'=>$receiving['wrap_type'],
                    'trade_co'=>$receiving['trade_co'],
                    'trade_name'=>$receiving['trade_name'],
                    'owner_code'=>$receiving['owner_code'],
                    'owner_name'=>$receiving['owner_name'],
                    'trade_mode'=>$receiving['trade_mode'],
                    'trans_mode'=>$receiving['trans_mode'],
                    'trade_country'=>$receiving['trade_country'],
                    'trade_area_code'=>$receiving['trade_area_code'],
                    'destination_port'=>$receiving['destination_port'],
                    'turn_no'=>$receiving['turn_no'],
                    'duty_mode'=>$receiving['duty_mode'],
                    'enty_port_code'=>$receiving['enty_port_code'],
                    'overseas_consignor_ename'=>$receiving['overseas_consignor_ename'],
                ];
                $index++;
                $cfnumber++;
            }
        }
        return $this;
    }

    private function paserFile($file)
    {
        $this->xlsPaser->setFilePath($file);
        return [
            'head' => $this->xlsPaser->getBaseInfo(),
            'body' => $this->xlsPaser->getBodyInfo()
        ];
    }

    public function setDefaultArr()
    {
        $defaultArr = array(
            'declare_port' => '5349',
            'enty_port_code' => '470001',
            'traf_mode' => '4',
            //'duty_mode'=>'3'
        );
        $formType = \Service_FormType::getByField($this->params['pt_code'], 'form_type');
        if ($formType['default_value'] != '') {
            $rowdefault = json_decode($formType['default_value'], true);

            if (!empty($rowdefault)) {
                $defaultArr = array_merge($defaultArr, $rowdefault);
            }
        }
        $this->defaultArr = $defaultArr;
    }

    public function makePriEnter()
    {
        $this->setReceivingInfo();
        $this->validate();
        $this->receivingSplitPre();
        $this->receivingSplitPreNumber();
        $this->receivingSplit();
        $this->setDefaultArr(); //设置一些没有的默认参数
        //生成
        $this->addPriEntryData();
    }

    protected function addPriEntryData()
    {
        $add = [
            'ref_no' => $this->params['ref_no'],
            'declare_port' => $this->defaultArr['declare_port'],
            'ie_port' => $this->params['ie_port'],
            'pre_status' => '-1',
            'pt_code' => $this->params['pt_code'],
            'ie_flag' => $this->params['ie_flag'],
            'pack_number' => '',
            'net_weight' => '',
            'gross_weight' => '',
            'add_time' => date("Y-m-d H:i:s"),
            'company_code' => $this->companyCode
        ];
        $allPackNumber = 0;
        $allNetWeight = 0;
        $allGrossWeight = 0;
        foreach ($this->priEnterHead as $detail) {
            $allPackNumber += $detail['bpdd_pack_number'];
            $allNetWeight += $detail['net_weight'];
            $allGrossWeight += $detail['gross_weight'];
        }
        $add['net_weight'] = $allNetWeight;
        $add['gross_weight'] = $allGrossWeight;
        $add['pack_number'] = $allPackNumber;
        $priEntryDataId = Service_BgPriEntryData::add($add);

        $num = count($this->priEnterHead); //计算拼数
//        var_dump($this->priEnterDataDetailBodyDetail);
//        die();
        foreach ($this->priEnterHead as $k => $detail) {
            $wrap_type = '';
            $trade_mode = ''; //监管方式
            $trans_mode = ''; //成交方式
            $trade_area_code = '';//贸易国
            if ($detail['bpd_ref_no'] != '') {
                $bpdNumber = $detail['bpd_ref_no'];
                $recCode = explode("-", $detail['bpd_ref_no']);
                $receving_code = $recCode[0];
                if (!empty($receving_code)) {
                    $receiving = $this->receivingInfo[$receving_code];
                    if (!empty($receiving)) {
                        $wrap_type = $receiving['wrap_type'];
                        $trade_mode = $receiving['trade_mode'];
                        $trans_mode = $receiving['trans_mode'];
                        if ($this->defaultArr['trade_mode']) {
                            $trade_mode = $this->defaultArr['trade_mode'];
                        }
                        $trade_area_code = $receiving['trade_area_code'];
                        $destination_port = $receiving['trade_country'];
                    }
                }
            } else {
                $bpdNumber = Common_GetNumbers::getCode('bg_date_detail_body_head', '', $this->params['pt_code'], false);
            }
            if (empty($trade_area_code)) {
                if (isset($this->defaultArr['trade_area_code'])) {
                    $trade_area_code = $this->defaultArr['trade_area_code'];
                }
            }
            if (empty($trade_area_code)) {
                $trade_area_code = "";
            }
            if (empty($destination_port)) {
                $destination_port = "";
            }


            $head = [
                'bped_id' => $priEntryDataId,
                'bpd_ref_no' => $detail['bpd_ref_no'],
                'pt_code' => $this->params['pt_code'],
                'ie_flag' => $this->params['ie_flag'],
                'declare_port' => $this->defaultArr['declare_port'],
                'ie_port' => $this->params['ie_port'],
                'enty_port_code' =>$detail['enty_port_code'],
                'ems_no' => $this->companyInfo['bwl_no'],
                'ems_cop_no' => '',
                'cop_gb_code' => '',
                'platenumber' => $this->params['platenumber'],
                'traf_name' => '',
                'traf_mode' => $detail['traf_mode'],
                'voyage_no' => $detail['voyage_no'],
                'bill_no' =>$detail['bill_no'],
                'wrap_type' => $detail['wrap_type'],
                'net_wt' => $detail['net_weight'],
                'gross_wt' => $detail['gross_weight'],
                'pack_no' => $detail['pack_no'],
                'duty_mode' => $detail['duty_mode'],
                'trade_co' => $this->companyInfo['trade_co'],
                'trade_name' => $this->companyInfo['trade_name'],
                'agent_code' => $this->companyInfo['declare_customs_code'],
                'agent_name' => $this->companyInfo['declare_company_name'],
                'owner_code' => $detail['owner_code'], //暂时和境内收发货人一致
                'owner_name' => $detail['owner_name'],//
                'trade_mode' => $trade_mode,
                'trans_mode' => $trans_mode,
                'trade_country' => isset($detail['trade_country']) ?$detail['trade_country'] : '',//运抵国
                'trade_area_code' => $detail['trade_area_code'],//贸易国
                'destination_port' => $detail['destination_port'],//指运港
                'num' => $num, //拼数
                'overseas_consignor_ename'=>$detail['overseas_consignor_ename'],//境外发货人名称（外文
                'rlt_entry_rvsngd_etps_sccd' => '',//关联报关单生产销售单位',
                'rlt_entry_rcvgd_etpsno' => $detail['owner_code'],//关联报关单海关收发货单位编码',
                'rlt_entry_rcvgd_etps_nm' => $detail['owner_name'],// 关联报关单收发货单位名称',
                'rlt_entry_bizop_etps_sccd' => '',//'关联报关单经营企业社会信用代码',
                'rlt_entry_bizop_etpsno' => $detail['trade_co'],//收发货人,
                'rlt_entry_bizop_etps_nm' => $detail['trade_name'],//收发货人,
                'turn_no'=>$detail['turn_no'],
                'add_time' => date("Y-m-d H:i:s"),
            ];
            $headId = Service_BgPriEntryDataDetailBodyHead::add($head);
            $log = [
                'bped_id' => $priEntryDataId,
                'bpedbh_id' => $headId,
                'content' => '生成预录入数据',
                'add_time' => date("Y-m-d H:i:s"),
            ];
            Service_BgPriEntryDataDetailLog::add($log);

            $bodyDetail = $this->priEnterDataDetailBodyDetail[$k];
            $gNo = 1;
            foreach ($bodyDetail as $detailBodyDetail) {
                $productInfo = $this->getProductInfo($detailBodyDetail['product_id']);
                $contr_item = $this->billNO($productInfo['product_id'], $this->companyInfo['bwl_no']);
                if ($contr_item != '') {
                    //账册有取账册
                    $books = Service_BillBook::getByCondition(['warehous_account_no' => $this->companyInfo['bwl_no'], 'recorde_no' => $contr_item], "*", 1, 1);
                    $book = $books[0];
                    $gname = $book['product_title'];
                    $code_ts = $book['hs_code'];
                    $gmodel = $book['specification'];
                    $trade_curr = $book['decalar_currency'];

                } else {
                    //账册无取备案
                    $gname = $detailBodyDetail['gname'];
                    $code_ts = $detailBodyDetail['code_ts'];
                    $gmodel = $detailBodyDetail['gmodel'];
                    $trade_curr = $detailBodyDetail['trade_curr'];

                }
                $humQuantityLaw = $detailBodyDetail['first_qty'];
                $humQuantitySecond = $detailBodyDetail['second_qty'];
                $puCode = $detailBodyDetail['gunit'];
                $firstUnit = $detailBodyDetail['first_unit'];
                $secondUnit = $detailBodyDetail['second_unit'];
                $addBodyDetail = [
                    'bpedbh_id' => $headId,
                    'product_id' => $productInfo['product_id'],
                    'goods_id' => $detailBodyDetail['goods_id'],
                    'g_no' => $gNo,
                    'class_mark' => '',
                    'code_ts' => $code_ts,//
                    'contr_item' => $contr_item,//备案序号,
                    'decl_price' => $detailBodyDetail['decl_price'],
                    'duty_mode' => $detailBodyDetail['duty_mode'],
                    'factor' => '',
                    'gmodel' => $gmodel,
                    'gname' => $gname,
                    'origin_country' => $detailBodyDetail['origin_country'],//$productInfo[''],原产国为空
                    'trade_curr' => $trade_curr,
                    'decl_total' => $productInfo['product_declared_value'] * $detailBodyDetail['rd_receiving_qty'],
                    'gqty' => $detailBodyDetail['rd_receiving_qty'],
                    'first_qty' => $humQuantityLaw,
                    'second_qty' => $humQuantitySecond,
                    'gunit' => $puCode,
                    'first_unit' => $firstUnit,
                    'second_unit' => $secondUnit,
                    'destination_country' => $detailBodyDetail['destination_country'], //最终目的国没有
                    'add_time' => date("Y-m-d H:i:s"),
                ];
                Service_BgPriEntryDataDetailBodyDetail::add($addBodyDetail);
                $gNo++;
            }

        }

    }

    /**
     * @date 2022/7/3
     * @param $productId
     * @param $warehouseCount
     * @return mixed|string
     * @todo 获取账册号
     * @auther 46935
     */
    protected function billNO($productId, $warehouseCount)
    {
        $billBook = Service_BillBookProduct::getByCondition(array(
            'product_id' => $productId,
        ));
        if (!empty($billBook)) {
            $bilId = array();
            foreach ($billBook as $bill) {
                $bilId[] = $bill['bill_book_id'];
            }
            $bilId = array_unique($bilId);
            $billBook = Service_BillBook::getByCondition([
                'id_array' => $bilId,
                'warehous_account_no' => $warehouseCount,
                'state' => '0', //只取正常状态的库存
            ], '*', '1', '1', array('stock_quantity asc '));
            if (!empty($billBook)) {
                return $billBook[0]['recorde_no'];
            }
        }
        return '';
    }

    /*
     * @todo 事先计算合并入库单里面的商品表体，提前计算总毛净重
     */
    protected function receivingSplitPre()
    {
        //$totalweight =
        foreach ($this->receivingInfo as $k => $receiving) {
            $detail = $receiving['detail'];
            $detailMerge = [];//入库单商品可能有重复的 合并重复项目
            $totalproductgrossweight = $totalproductnetweight = 0;

            foreach ($detail as $kd => $vd) {
                if (!$vd['goods_id']) {
                    throw new Exception('商品料号不存在');
                }
                $totalproductgrossweight += $vd['rd_receiving_qty'] * $this->getProductGrossWeight($vd['product_id']);
                $totalproductnetweight += $vd['rd_receiving_qty'] * $this->getProductWeight($vd['product_id']);

                $detailMerge[] = $vd;
                $weightArr = array(
                    'totalproductgrossweight' => $totalproductgrossweight,
                    'totalproductnetweight' => $totalproductnetweight,
                );
            }
            $this->receivingInfo[$k]['detail'] = array_values($detailMerge);
            $this->weightArr[$receiving['receiving_code']] = $weightArr;
            //print_r($this->weightArr);
        }
    }
}
