<?php
class Service_PutawayProcess
{
    protected $_putawayCode = null;
    protected $_putaway = array();
    protected $_putawayDetail = array();
    protected $_userWarehouseId = 0;
    protected $_userId = 0;
    protected $_errorArr = array();
    protected $_params = array();
    protected $_date = '';

    //状态
    public static function getItemStatus()
    {
        return Common_Status::putawayDetailStatus('auto');
    }

    //上架搜索
    public static function getSearchType()
    {
        return array(
            0 => '质检单号',
           // 1 => '收货单号',
            2 => '上架单号',
            3 => '分箱单号',
        );
    }

    //类型
    public static function getItemType()
    {
        return Common_Type::putawayDetailType('auto');
    }

    public function __construct()
    {
        $this->_date = date('Y-m-d H:i:s');
    }

    /**
     * @desc 数据初始化以及数据验证
     * @param $params
     * @return bool
     */
    private function setDataValid($params)
    {
        $this->_userWarehouseId = Service_User::getUserWarehouseId();
        $this->_userId = Service_User::getUserId();
        $pdIds = array();
        $locationObj = new Service_Location();
        foreach ($params as $key => $val) {
            if (empty($val['lc_code']) || !isset($val['lc_code'])) {
                $this->_errorArr[] = array('errorCode' => '10009', 'errorMsg' => Ec::Lang('notEmptyShelf'));
            } else {
                $locationRow = $locationObj->getByField($val['lc_code'], 'lc_code', array('lc_code', 'lc_status', 'warehouse_id','wa_code'));
                if (empty($locationRow)) {
                    $this->_errorArr[] = array('errorCode' => '10011', 'errorMsg' => Ec::Lang('ShelfNotExist'));
                } elseif ($locationRow['lc_status'] == '0' || $locationRow['warehouse_id'] != $this->_userWarehouseId) {
                    $this->_errorArr[] = array('errorCode' => '10012', 'errorMsg' => Ec::Lang('ShelfNotBeUsed'));
                }else{             
                    $warehouseAreaRow   =   Service_WarehouseArea::getByField($locationRow['wa_code'] , 'wa_code' , array('wa_type'));
                    if(empty($warehouseAreaRow) || $warehouseAreaRow == false){
                        $this->_errorArr[] = array('errorCode' => '10013', 'errorMsg' => Ec::Lang('WarehouseAreaIsNuLL'));
                    }
                    else if($warehouseAreaRow['wa_type'] != 1){
                        $this->_errorArr[] = array('errorCode' => '10014', 'errorMsg' => sprintf(Ec::Lang('WarehouseAreaTypeError') , $val['lc_code']));
                    }
                    $pc_id  =   Service_Product::getByField($val['product_barcode'] , 'product_barcode' , array('pc_id'));
                    if($warehouseAreaRow['pc_id'] != $pc_id['pc_id'] && $warehouseAreaRow['pc_id'] != '0'){
                        //$this->_errorArr[] = array('errorCode' => '10015', 'errorMsg' => sprintf(Ec::Lang('WarehouseAreaPcIdNotEqPorductPcId') , $val['lc_code']));
                    }
                }
            }
            if (!in_array($val['pd_id'], $pdIds)) {
                $pdIds[] = $val['pd_id'];
            }
            $val['lc_code'] = strtoupper($val['lc_code']);
            $this->_params['putawayDetail'][$val['pd_id']] = $val;
        }
        if (!empty($this->_errorArr)) {
            return false;
        }


        $putawayDetailRows = Service_PutawayDetail::getByCondition(array('pd_id_arr' => $pdIds), '*');
        if (empty($putawayDetailRows)) {
            $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' => Ec::Lang('paramsErrormsg'));
            return false;
        }

        foreach ($putawayDetailRows as $key => $val) {
            $this->_putawayDetail[$val['pd_id']] = $val;
        }

        foreach ($this->_params['putawayDetail'] as $key => $val) {
            if (!isset($this->_putawayDetail[$val['pd_id']])) {
                $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' => Ec::Lang('paramsErrormsg'));
                return false;
            }
        }
    }

    /**
     * @desc 更新上架数据状态
     */
    private function updatePutawayDetail()
    {
        $pdObj = new Service_PutawayDetail();
       // print_r($this->_params['putawayDetail']);exit;
        foreach ($this->_params['putawayDetail'] as $key => $val) {
            $pd=$pdObj->getByField($val['pd_id'],'pd_id');
            $pdObj->update(array('pd_status' => 1, 'lc_code' => $val['lc_code'], 'putaway_user_id' => $this->_userId, 'pd_putaway_time' => $this->_date, 'pd_update_time' => $this->_date), $val['pd_id']);
        }
    }

    /**
     * @desc 更新ASN上架数量
     * @item for update 1.QC状态 2.AsnItem 3.box(创建时已完成,查找未完成box可以查找putawayDetail)
     */
    private function updateAsnDetailAndQc()
    {
        $qcArr = array();
        foreach ($this->_putawayDetail as $key => $val) {
            if (isset($this->_params['putawayDetail'][$key])) {
                //统计各QC上架数量
                if (!isset($qcArr[$val['qc_code']])) {
                    $qcArr[$val['qc_code']] = $val['pd_quantity'];
                } else {
                    $qcArr[$val['qc_code']] += $val['pd_quantity'];
                }
            }
        }
        if (empty($qcArr)) {
            $this->_errorArr[] = array('errorCode' => '10013', 'errorMsg' => '上架数据异常');
            return false;
        }
        $qcObj = new Service_QualityControl();
        $rdbObj = new Service_ReceivingDetailBatch();
        $rdObj = new  Service_ReceivingDetail();
        foreach ($qcArr as $qcCode => $quantity) {
            $qcRow = $qcObj->getByField($qcCode, 'qc_code');
            if (empty($qcRow)) {
                $this->_errorArr[] = array('errorCode' => '10013', 'errorMsg' => Ec::Lang('QcNotExist'));
            } else {
                if($qcRow['qc_model']=="1"){
                    Service_SwapOrderDetail::update(array('swod_status'=>5),$qcRow['rd_id'],'swod_id');
                    $qcObj->update(array('qc_status' => 2, 'qc_update_time' => $this->_date), $qcRow['qc_id']);
                    $con = array(
                        'receiving_code'=>$qcRow['receiving_code'],
                        'not_qc_status'=>2,
                    );
                    $existQc = Service_QualityControl::getByCondition($con,'count(*)');
                    if(!$existQc){
                        $updateSwapOrder =array(
                            'swo_status'=>5,
                            'last_update_time'=>date("Y-m-d H:i:s"),
                            'putway_time'=>$this->_date,
                        );
                        Service_SwapOrder::update($updateSwapOrder,$qcRow['receiving_code'],'swo_code');
                        Service_SwapOrderProcess::sendToFenxiao($qcRow['receiving_code']);
                    }
                }else{
                    //分箱上架,多条上架记录,QC是否已上架，没有“上架中”状态，暂时先判断数量，数量相等才“已上架”
                    $qcStatus = $qcRow['qc_quantity_sellable'] == $quantity ? 2 : $qcRow['qc_status'];
                    $qcObj->update(array('qc_status' => $qcStatus, 'qc_update_time' => $this->_date), $qcRow['qc_id']);
                    //存在不良品,上架数量不一定等于收货数量
                    $rdbObj->update(array('rdb_putaway_qty' => $quantity, 'rdb_update_time' => $this->_date), $qcCode, 'qc_code');
                    $rdRow = $rdObj->getByField($qcRow['rd_id'], 'rd_id', array('rd_putaway_qty', 'rd_received_qty'));
                    $rdObj->update(array('rd_putaway_qty' => $quantity + $rdRow['rd_putaway_qty'], 'rd_update_time' => $this->_date), $qcRow['rd_id'], 'rd_id');
                }
            }
            if(isset($qcRow['qc_model'])&&$qcRow['qc_model']!="1"){
                $condition = array(
                    'receiving_code'=>$qcRow['receiving_code'],
                    'unshelf_status'=>'1'
                );
                $total = Service_QualityControl::getByCondition($condition,"count(*)");
                if(!$total){
                    Service_Receiving::update(array('receiving_status' => 7, 'receiving_update_time' =>date("Y-m-d H:i:s")), $qcRow['receiving_code'],"receiving_code");
                    $updateRa = array(
                        'shelf_time'=>date("Y-m-d H:i:s"),
                        'complete_received_time'=>date("Y-m-d H:i:s"),
                    );
                    Service_ReceivingAttribute::update($updateRa,$qcRow['receiving_code'],"receiving_code");
                }
            }
        }
    }

    /**
     * @desc 添加货架批次库存
     */
    private function inventoryBatch()
    {
        $inventoryBatchObj = new  Service_InventoryBatch();
        $receivingObj = new Service_Receiving();
        $batchLogObj = new Service_InventoryBatchLog();
        $receiving = array();
        foreach ($this->_putawayDetail as $key => $val) {
            if (isset($this->_params['putawayDetail'][$key])) {
                $fromProductId = 0;
                $qcRow = Service_QualityControl::getByField($val['qc_code'],"qc_code","*");
                if($qcRow['qc_model']=="1"){
                    if(!isset($receiving[$val['receiving_code']])){
                        $receiving[$val['receiving_code']] = Service_SwapOrder::getByField($val['receiving_code'], 'swo_code');
                    }
                    $detail = Service_SwapOrderDetail::getByField( $qcRow['rd_id'] );
                    $product = Service_Product::getByCondition( array( 'product_sku' => $detail['from_sku'], 'customer_code' => $detail['from_customer_code'] ) );
                    $fromProductId = $product[0]['product_id'];
                }else{
                    if (!isset($receiving[$val['receiving_code']])) {
                        $receiving[$val['receiving_code']] = $receivingObj->getByField($val['receiving_code'], 'receiving_code');
                    }
                }
				$productInfo	= Service_Product::getByField($val['product_id'], 'product_id');
                $row = array(
                    'lc_code' => $this->_params['putawayDetail'][$key]['lc_code'],
                    'product_id' => $val['product_id'],
                    'product_barcode' => $val['product_barcode'],
                    'reference_no' => $val['qc_code'],
					'customer_code'=>$productInfo['customer_code'],
                    'box_code' => $val['box_code'],
                    'application_code' => 'Putaway',
                    'warehouse_id' => $val['warehouse_id'],
                    'receiving_code' => $val['receiving_code'],
                    'receiving_id' =>isset($receiving[$val['receiving_code']]['receiving_id'])?$receiving[$val['receiving_code']]['receiving_id']:$receiving[$val['receiving_code']]['swo_id'],
                    'supplier_id' => isset($receiving[$val['receiving_code']]['supplier_id'])?$receiving[$val['receiving_code']]['supplier_id']:0,
                    'lot_number' => 1,
                    'ib_status' => 1,
                    'ib_quantity' => $val['pd_quantity'],
                    'ib_fifo_time' => $this->_date,
                    'ib_add_time' => $this->_date,
                    'from_product_id'=> $fromProductId,
                    'hs_serial_no'=>$qcRow['hs_serial_no'],
                );
                $ibId = $inventoryBatchObj->add($row);
                $log = array(
                    'lc_code' => $this->_params['putawayDetail'][$key]['lc_code'],
                    'product_id' => $val['product_id'],
                    'product_barcode' => $val['product_barcode'],
                    'reference_no' => $val['qc_code'],
                    'box_code' => $val['box_code'],
                    'application_code' => 'Putaway',
                    'warehouse_id' => $val['warehouse_id'],
                    'receiving_code' => $val['receiving_code'],
                    'supplier_id' => isset($receiving[$val['receiving_code']]['supplier_id'])?$receiving[$val['receiving_code']]['supplier_id']:0,
                    'ib_id' => $ibId,
                    'ibl_quantity_before' => 0,
                    'ibl_quantity_after' => $val['pd_quantity'],
                    'user_id' => $this->_userId,
                    'ibl_ip' => Common_Common::getIP(),
                    'ibl_add_time' => $this->_date,
                );
                if($qcRow['qc_model']=="1"){
                    $ibsList = Service_InventoryBatchSerial::getByCondition(array('product_id' => $val['product_id'],'swo_code'=>$val['receiving_code']),"*");
                    if(!empty($ibsList)){
                        foreach($ibsList as $ibs){
                            Service_InventoryBatchSerial::update(array('ib_id'=>$ibId,'ibs_status'=>1),$ibs['ibs_id'],"ibs_id");
                        }
                    }
                }
                $batchLogObj->add($log);
            }
        }
    }

    /**
     * @desc 更新产品库存
     * @throws Exception
     */
    private function updateInventory()
    {
        $inventoryObj = new Service_ProductInventoryProcess();
        foreach ($this->_putawayDetail as $key => $val) {
            if (isset($this->_params['putawayDetail'][$key])) {
                $row = array(
                    'product_id' => $val['product_id'],
                    'quantity' => $val['pd_quantity'],
                    'customQty' => 0, //用于其它
                    'operationType' => 3,
                    'unsellable' => 0,
                    'warehouse_id' => $val['warehouse_id'],
                    'reference_code' => $val['qc_code'], //操作单号
                    'application_code' => 'Putaway', //操作类型
                    'note' => '确认上架',
                );
                $qcRow = Service_QualityControl::getByField($val['qc_code'],'qc_code',"*");
                if($qcRow['qc_model']=="1"){
                    $swd = Service_SwapOrderDetail::getByField($qcRow['rd_id'],"swod_id","*");
                    $fromProduct = Service_Product::getByField($swd['product_id'],"product_id","*");
                    $exSwp = Service_SwapProduct::getByCondition(array('product_id'=>$swd['product_id'],'from_goods_id'=>$fromProduct['goods_id']),"*");
                    if(!empty($exSwp)){
                        $updateSwp = array(
                            'sp_quantity'=>$exSwp[0]['sp_quantity']-$val['pd_quantity'],
                        );
                        Service_SwapProduct::update($updateSwp,$exSwp[0]['sp_id'],"sp_id");
                    }
                }

                $productRow = Service_Product::getByField($val['product_id'],"product_id","*");
                $exSwp = Service_SwapProduct::getByCondition(array('product_id'=>$productRow['product_id'],'from_goods_id'=>$productRow['goods_id']),"*");
                if(!empty($exSwp)){
                    $updateSwp = array(
                        'sp_quantity'=>$exSwp[0]['sp_quantity']+$val['pd_quantity'],
                    );
                    Service_SwapProduct::update($updateSwp,$exSwp[0]['sp_id'],"sp_id");
                }else{
                    $swapProductRow = array(
                        'product_id'=>$productRow['product_id'],
                        'product_sku'=>$productRow['product_sku'],
                        'customer_code'=>$productRow['customer_code'],
                        'product_barcode'=>$productRow['product_barcode'],
                        'from_goods_id'=>$productRow['goods_id'],
                        'sp_quantity'=>$val['pd_quantity'],
                    );
                    Service_SwapProduct::add($swapProductRow);
                }

                $result = $inventoryObj->update($row);
                // print_r($result);
                if (!isset($result['state']) || $result['state'] != '1') {
                    throw new Exception('Inventory Internal error');
                }
            }
        }
    }

    /**
     * @desc 更新产品历史货架
     * @throws Exception
     */
    private function updateProductLocationMap()
    {
        $obj = new Service_ProductLocationMap();
        $result = true;
        $productArr = array();
        foreach ($this->_putawayDetail as $key => $val) {
            if (isset($this->_params['putawayDetail'][$key])) {
                if (!in_array($val['product_id'], $productArr)) {
                    $productArr[] = $val['product_id'];
                } else {
                    continue;
                }
                $condition = array(
                    'product_id' => $val['product_id'],
                    'warehouse_id' => $val['warehouse_id'],
                );
                $rows = $obj->getByCondition($condition);
                if (!empty($rows)) {
                    if ($rows[0]['lc_code'] == $this->_params['putawayDetail'][$key]['lc_code']) {
                        continue;
                    }
                    $result = $obj->update(array('lc_code' => $this->_params['putawayDetail'][$key]['lc_code']), $rows[0]['plm_id'], 'plm_id');
                } else {
                    $condition['lc_code'] = $this->_params['putawayDetail'][$key]['lc_code'];
                    $result = $obj->add($condition);
                }
            }
        }
        if (!$result) {
            throw new Exception('Update Product Location Internal error');
        }
    }

    /**
     * @todo 添加gs库存通知
     */
    private function inventoryNotify(){

        foreach ($this->_putawayDetail as $key => $value) {
            $product = Service_Product::getByField( $value['product_id'], 'product_id' );
            $notify = array(
                'product_id' => $value['product_id'],
                'product_sku' => $product['product_sku'],
                'customer_code' => $value['customer_code'],
                'reason' => '入库上架',
                'quantity' => $value['pd_quantity'],
                'referecne_no' => $value['qc_code'],
                'reftype' => 1,
                'gstype' => 'InboundInventory',

            );
            Service_GsNotifyProcess::addNotify( $notify );
        }
    }

    /**
     * @desc 产品上架 事务处理 主入口
     * @param array $params
     * @return array
     */
    public function submit($params = array())
    {
        $result = array(
            'state' => 0,
            'error' => array(),
            'message' => ''
        );
        $db = Service_QualityControl::getModelInstance()->getAdapter();
        $this->setDataValid($params);
        //print_r($params);exit;
        if (!empty($this->_errorArr)) {
            $result['error'] = $this->_errorArr;
            return $result;
        }
        $db->beginTransaction();
        try {
            $this->updatePutawayDetail();
            $this->updateAsnDetailAndQc();
            $this->inventoryBatch();
            $this->updateInventory();
            $this->updateProductLocationMap();
            $keys = array_keys( $this->_putawayDetail );
            $customerCode = $this->_putawayDetail[ $keys[0] ]['customer_code'];
            //环球的用户才执行
            if( Service_CustomerProcess::$HuanQiu == Service_CustomerProcess::getOwner( $customerCode ) ) {
                $this->inventoryNotify();
            }
            $result = array('state' => 1, 'message' => Ec::Lang('operationSuccess'));
            $db->commit();
            return $result;
        } catch (Exception $e) {
            $db->rollBack();
            $result['error'][] = array(
                'errorCode' => '50000',
                'errorMsg' => $e->getMessage()
            );
            return $result;
        }
    }

  /**
   * 为特殊客户用的上架，用于Service_AsnForCustomer
   * 根据self::submit微作修改
   */
  public function submitForCustomer($params = array()) {
    $this->setDataValid($params);

    if (!empty($this->_errorArr)) {
      throw new Exception(implode('；', $this->_errorArr));
    }

    $this->updatePutawayDetail();
    $this->updateAsnDetailAndQc();
    $this->inventoryBatch();
    $this->updateInventory();
    $this->updateProductLocationMap();
  }
}