<?php
class Service_QualityControlProcess
{
    protected $_QcCode = null;
    protected $_QcOrder = null;
    protected $_asnItem = null;
    protected $_errorArr = array();
    protected $_params = array();
    protected $_userId = 0;
    protected $_warehouseId = 0;
    protected $_date = '';
    protected $_product = null;//单个产品的信息
    protected $_receiving = null;//入库单信息
    protected $_submitFromPDA = false;


    //QC状态
    public static function getStatus()
    {
        return Common_Status::qualityControlStatus('auto');
    }

    public function __construct()
    {
        $this->_date = date('Y-m-d H:i:s');
        $this->setUser();
        $this->setWarehouse();
    }

    /**
     * @desc 表单参数
     * @param array $params
     */
    private function setData($params = array())
    {
        $keys = array(
            'receivedQty' => 0,
            'problemQty' => 0,
            'noLabelQty' => 0,
            'qcId' => 0,
            'userId' => 0,
            'remark' => '',
            'firstReceived' => 1,
            'shelf' => 0,
            'productWeight' => 0,
            'qcQty' => array(),
            'qcNote' => array(),
            'product' => array(),
        	'boxArray' =>array(),
        );
        foreach ($keys as $key => $val) {
            $this->_params[$key] = isset($params[$key]) ? $params[$key] : $val;
        }
        if(isset($params['userId']) && preg_match('/^[1-9]+[0-9]*$/',$params['userId'])){
            $this->_userId = $params['userId'];
        }
        if(isset($params['wareshoueId']) && preg_match('/^[1-9]+[0-9]*$/',$params['wareshoueId'])){
            $this->_warehouseId = $params['wareshoueId'];
        }
        $this->_params['userId'] =  $this->_userId;
        $this->_params['userId'] = $this->_params['userId'] == '0' ? $this->_userId : $this->_params['userId'];
        $this->_params['shelf'] = !empty($this->_params['shelf']) ? strtoupper(trim($this->_params['shelf'])) : '';
        $this->_QcOrder = Service_QualityControl::getByField($this->_params['qcId'], 'qc_id');
    }

    protected function setUser(){
        $this->_userId = Service_User::getUserId();
    }

    protected function setWarehouse(){
        $this->_warehouseId = Service_User::getUserWarehouseId();
    }

    private function valid()
    {
        //当收货数量为0时,应当处理未到货
        if ($this->_params['problemQty'] > $this->_params['receivedQty'] || $this->_params['noLabelQty'] > $this->_params['receivedQty'] || !is_numeric($this->_params['receivedQty']) || $this->_params['receivedQty']<1 ) {
            $this->_errorArr[] = array('errorCode' => '10003', 'errorMsg' => Ec::Lang('quantityError'));
        }
        if (!empty($this->_params['qcQty'])) {
            foreach ($this->_params['qcQty'] as $key => $val) {
                if ($val > 0 && ($this->_params['qcNote'][$key] == '' || !isset($this->_params['qcNote'][$key]))) {
                    $this->_errorArr[] = array('errorCode' => '10004', 'errorMsg' => Ec::Lang('abnormalNote'));
                }
            }
        }
        if (empty($this->_QcOrder)) {
            $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' => Ec::Lang('paramsErrormsg'));
        }
        if ($this->_QcOrder['qc_status'] != '0' && isset($this->_QcOrder['qc_status'])) {
            $this->_errorArr[] = array('errorCode' => '10005', 'errorMsg' => Ec::Lang('errorState'));
        }
        if ($this->_params['firstReceived'] == '0' && empty($this->_params['product'])) {
            $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' => Ec::Lang('paramsErrormsg'));
        }

        if (empty($this->_params['shelf']) && $this->_params['problemQty'] > 0) {
            $this->_errorArr[] = array('errorCode' => '10006', 'errorMsg' => '货架号不能为空.');
        } elseif (!empty($this->_params['shelf']) && $this->_params['problemQty'] > 0) {
            $shelfRow = Service_Location::getByCondition(array('lc_code' => $this->_params['shelf'], 'warehouse_id' => $this->_warehouseId), '*');
            if (empty($shelfRow)) {
                $this->_errorArr[] = array('errorCode' => '10007', 'errorMsg' => '货架号不存在.');
            } else {
                if ($shelfRow[0]['lc_status'] != '1') {
                    $this->_errorArr[] = array('errorCode' => '10008', 'errorMsg' => '货架号不可用.');
                } else {
                    $areaRow = Service_WarehouseArea::getByField($shelfRow[0]['wa_code'], 'wa_code');
                    //不良品区
                    if (isset($areaRow['wa_type']) && $areaRow['wa_type'] != '2') {
                        $this->_errorArr[] = array('errorCode' => '10008', 'errorMsg' => '此货架号不属于不良品区域.');
                    }
                }
            }

        }
        $boxArr = $this->_params['boxArray'];
        $boxCodeArr=array();
    	if(!empty($boxArr)){
    		//校验
            $boxQty=0;
    		foreach($boxArr as $key=>$val){
    			$boxCode=$val['box_code'];
    			if(empty($boxCode)){
    				$this->_errorArr[] = array('errorCode' => '10014', 'errorMsg'=>"分箱".($key+1)."必填");
                    break;
    			}else{
    				/*if(preg_match('/^BOX\d+/i', $val['box_code'])==false){
    					$this->_errorArr[] = array('errorCode' => '10014', 'errorMsg'=>"分箱号:".$val['box_code']."必须以box开头");
    				}*/
                    if(!in_array($val['box_code'],$boxCodeArr)){
                        $boxCodeArr[]=$val['box_code'];
                    }else{
                        $this->_errorArr[] = array('errorCode' => '10014', 'errorMsg'=>"分箱号:".$val['box_code']."存在重复");
                        exit;
                    }
                    /* if(!empty($boxCode)){
                    	$checkbox = Service_PutawayBox::getByField($boxCode,'box_code');
                    	if(!empty($checkbox)){
                    		$this->_errorArr[] = array('errorCode' => '10014', 'errorMsg'=>"分箱号:".$val['box_code']."系统已存在");
                    	}
                    } */
                    if(!is_numeric($val['quantity']) || $val['quantity']<1 || $val['quantity']=='' ){
                        $this->_errorArr[] = array('errorCode' => '10015', 'errorMsg'=>"分箱号:".$val['box_code'].'数量必填');
                        break;
                    }else{
                        $boxQty+=$val['quantity'];
                    }
    			}
            /*if($boxQty<$this->_params['receivedQty']-$this->_params['problemQty']){
               
                $box=Service_Box::getByField($val['box_code'],'box_code');
                if ($box['box_status']!='2') {
                  $product=Service_Product::getByField($this->_QcOrder['product_barcode'],'product_barcode');
                $up=array(
                    'box_status'=>2,
                    'product_barcode'=>$this->_QcOrder['product_barcode'],
                    'product_id'=>$product['product_id'],
                    'receiving_code'=>$this->_QcOrder['receiving_code'],
                    'box_quantity'=>$val['quantity']
                    );
                Service_Box::update($up,$box['box_id']);
                 $this->_errorArr[] = array('errorCode' => '10020', 'errorMsg'=>'分箱产品总数量小于实收总数减不合格总数');
                }
                
                }else if($boxQty>$this->_params['receivedQty']-$this->_params['problemQty']){
                    $this->_errorArr[] = array('errorCode' => '10021', 'errorMsg'=>'分箱产品总数量大于实收总数减不合格总数');
                    break;
                }*/
    	   }

    	}
    }

    private function updateAsnItem()
    {
        $asnItem = Service_ReceivingDetail::getByCondition(array('receiving_code' => $this->_QcOrder['receiving_code']), '*');
        $asnStatus = 6;
        $rdStatus = 1;
        $asnItemStatus = array();
        foreach ($asnItem as $key => $val) {
            $asnItem[$val['rd_id']] = $val;
            $asnItemStatus[$val['rd_id']] = $val['rd_status'];
            if ($val['rd_status'] != '2' && $this->_QcOrder['rd_id'] != $val['rd_id']) {
                $asnStatus = 6;
            }
        }

        if ($this->_params['receivedQty'] + $asnItem[$this->_QcOrder['rd_id']]['rd_received_qty'] >= $asnItem[$this->_QcOrder['rd_id']]['rd_receiving_qty']) {
            $rdStatus = 2;
            $asnItem[$this->_QcOrder['rd_id']]['rd_status'] = 2;
        } else {
            $asnStatus = 6;
        }
        //$asnStatus = $asnStatus == '7' && $rdStatus == '2' ? 7 : 6;

        //update AsnItem
        $updateAsnItem['rd_received_qty'] = $asnItem[$this->_QcOrder['rd_id']]['rd_received_qty'] + $this->_params['receivedQty'];
        $updateAsnItem['rd_update_time'] = $this->_date;
        $updateAsnItem['rd_status'] = $rdStatus;
        Service_ReceivingDetail::update($updateAsnItem, $this->_QcOrder['rd_id']);

        //update ASN
        Service_Receiving::update(array('receiving_status' => $asnStatus, 'receiving_update_time' => $this->_date), $this->_QcOrder['receiving_id']);

        $this->_receiving['receiving_status'] = $asnStatus;

        /*if($asnStatus=="7"){
            $updateRa = array(
                'complete_received_time'=>date("Y-m-d H:i:s"),
            );
            Service_ReceivingAttribute::update($updateRa,$this->_QcOrder['receiving_id'],"receiving_id");
        }*/

        //receiving batch
        $batch = array(
            'receiving_id' => $this->_QcOrder['receiving_id'],
            'qc_code' => $this->_QcOrder['qc_code'],
            'receiving_code' => $this->_QcOrder['receiving_code'],
            'receiving_line_no' => $asnItem[$this->_QcOrder['rd_id']]['receiving_line_no'],
            'product_barcode' => $this->_QcOrder['product_barcode'],
            'product_id' => $this->_QcOrder['product_id'],
            'rdb_weight' => $this->_params['productWeight'],
            'rdb_received_qty' => $this->_params['receivedQty'],
            'labeled' => $this->_params['noLabelQty'] > 0 ? 1 : 0,
            'non_labeled_qty' => $this->_params['noLabelQty'],
            'receiving_user_id' => $this->_QcOrder['receiving_user_id'],
            'rdb_add_time' => $this->_date,
            'rdb_update_time' => $this->_date,
        );
        Service_ReceivingDetailBatch::add($batch);

        $this->_asnItem = $asnItem;
    }

    private function updateQC()
    {
        $qcRow = array(
            'qc_received_quantity' => $this->_params['receivedQty'],
            'qc_status' => 1,
            'lc_code' => $this->_params['shelf'],
            'qc_note' => $this->_params['remark'],
            'qc_operator_id' => $this->_params['userId'],
            'qc_quantity_sellable' => $this->_params['receivedQty'] - $this->_params['problemQty'],
            'qc_quantity_unsellable' => $this->_params['problemQty'],
            'qc_update_time' => $this->_date,
            'qc_finish_time' => $this->_date,
        );
        $result = Service_QualityControl::update($qcRow, $this->_QcOrder['qc_id']);
        if(!$result){
            throw new Exception('更新质检单失败',3000);
        }

        //Qc Result
        if ($this->_QcOrder['qc_type'] == '1' && !empty($this->_params['qcQty'])) {
            $qcResultObj = new Service_QualityControlResult();
            foreach ($this->_params['qcQty'] as $key => $qty) {
                $add = array(
                    'qc_id' => $this->_QcOrder['qc_id'],
                    'qc_code' => $this->_QcOrder['qc_code'],
                    'pqo_id' => $key,
                    'qcr_quantity_pass' => $this->_params['receivedQty'] - $qty,
                    'qcr_quantity_problem' => $qty,
                    'qcr_description' => isset($this->_params['qcNote'][$key]) ? $this->_params['qcNote'][$key] : '',
                    'qcr_add_time' => $this->_date,
                );
                $result = $qcResultObj->add($add);
                if(!$result){
                    throw new Exception('更新质检单失败',3000);
                }
            }
        }
    }

    private function  putaway()
    {

        $putawayRow = Service_Putaway::getByField($this->_QcOrder['receiving_code'], 'receiving_code');

        $boxArr = $this->_params['boxArray'];
        if(!empty($boxArr)){
        	foreach($boxArr as $key=>$val){
        			$putaway = array(
      					'putaway_id' => $putawayRow['putaway_id'],
        				'putaway_code' => $putawayRow['putaway_code'],
        				'qc_code' => $this->_QcOrder['qc_code'],
        				'box_code'=>strtoupper($val['box_code']),
        				'receiving_code' => $putawayRow['receiving_code'],
        				'pd_type' => 2,
        				'product_barcode' => $this->_QcOrder['product_barcode'],
        				'product_id' => $this->_QcOrder['product_id'],
        				'pd_quantity' =>$val['quantity'],
        				'pd_lot_number' => 1,
        				'warehouse_id' => $this->_QcOrder['warehouse_id'],
        				'pd_add_time' => $this->_date,
        			);
                $result = Service_PutawayDetail::add($putaway);
                if(!$result){
                    throw new Exception('生成上架信息失败',3000);
                }
        	}
        }else{
        	//之前的程序 只有一条 如果 有 分箱会插入多条
        	$putaway = array(
        			'putaway_id' => $putawayRow['putaway_id'],
        			'putaway_code' => $putawayRow['putaway_code'],
        			'qc_code' => $this->_QcOrder['qc_code'],
        			'receiving_code' => $putawayRow['receiving_code'],
        			'pd_type' => 1,
        			'product_barcode' => $this->_QcOrder['product_barcode'],
        			'product_id' => $this->_QcOrder['product_id'],
        			'pd_quantity' => $this->_params['receivedQty'] - $this->_params['problemQty'],
        			'pd_lot_number' => 1,
        			'warehouse_id' => $this->_QcOrder['warehouse_id'],
        			'pd_add_time' => $this->_date,
        	);
            $result = Service_PutawayDetail::add($putaway);
            if(!$result){
                throw new Exception('生成上架信息失败',3000);
            }
        }


    }

    private function updateProduct()
    {
        $productRow = Service_Product::getByField($this->_QcOrder['product_id'], 'product_id');
        //不是首次收货，只更新重量
        if ($this->_params['firstReceived'] == '1') {
            //if ($productRow['product_weight'] < $this->_params['productWeight']) {
            $productQcCount = Service_QualityControl::getByCondition(array(
              'product_id' => $this->_QcOrder['product_id'],
              'no_draft' => TRUE, // 统计非草稿状态的所有质检单数量
            ), 'count(*)');

           if (!$productQcCount) {
                Service_Product::update(array('product_weight' => $this->_params['productWeight'], 'product_update_time' => $this->_date), $this->_QcOrder['product_id']);
                $note = ' Weight:' . $productRow['product_weight'] . ' to  ' . $this->_params['productWeight'];
                $log = array(
                    'product_id' => $this->_QcOrder['product_id'],
                    'pl_type' => '0',
                    'user_id' => $this->_userId,
                    'customer_id' => $this->_QcOrder['customer_id'],
                    'pl_note' => $note,
                );
                Service_ProductLog::add($log);
           }
            //}
            return true;
        }
        //检查品类是否存在
        if($this->_params['product']['category']===''){
            throw new Exception('产品目录不能为空');
        }
        //首次收货,确认详细资料
        $row = array(
            //'product_declared_value' => $this->_params['product']['declaredValue'],
            'product_length' => $this->_params['product']['length'],
            'product_width' => $this->_params['product']['width'],
            'product_receive_status' => 1,
            'product_height' => $this->_params['product']['height'],
            'pc_id' => $this->_params['product']['category'],
            'product_weight' => $this->_params['productWeight'],
            'product_update_time' => $this->_date,
        );
        if(isset($this->_params['product']['category'])){
            $row['pce_id'] = $this->_params['product']['category'];
        }
        if ('' != $this->_params['first_product_barcode']) {
            $row['product_barcode'] = $this->_params['first_product_barcode'];
        }
        $result = Service_Product::update($row, $this->_QcOrder['product_id']);
        /*if(!$result){
            throw new Exception('更新产品信息失败',3000);
        }*/
        //$note = 'first goods,declaredValue:' . $productRow['product_declared_value'] . ' to  ' . $this->_params['product']['declaredValue'];
        $note = 'first goods,declaredValue: Weight:' . $productRow['product_weight'] . ' to  ' . $this->_params['productWeight'];
        $note .= ' Width:' . $productRow['product_width'] . ' to  ' . $this->_params['product']['width'];
        $note .= ' Length:' . $productRow['product_length'] . ' to  ' . $this->_params['product']['length'];
        $note .= ' Height:' . $productRow['product_height'] . ' to  ' . $this->_params['product']['height'];

        $log = array(
            'product_id' => $this->_QcOrder['product_id'],
            'pl_type' => '0',
            'user_id' => $this->_userId,
            'customer_id' => $this->_QcOrder['customer_id'],
            'pl_note' => $note,
        );
        Service_ProductLog::add($log);
        $package = Service_ProductPackageMap::getByCondition(array('product_id' => $this->_QcOrder['product_id'], 'warehouse_id' => $this->_QcOrder['warehouse_id']), '*');
        if (!empty($package)) {
            Service_ProductPackageMap::update(array('pp_id' => $this->_params['product']['package'], 'ppm_update_time' => $this->_date), $package[0]['ppm_id']);
        } else {
            $row = array(
                'product_id' => $this->_QcOrder['product_id'],
                'pp_id' => $this->_params['product']['package'],
                'warehouse_id' => $this->_QcOrder['warehouse_id'],
                'ppm_update_time' => $this->_date,
            );
            Service_ProductPackageMap::add($row);
        }
    }

    private function inventory()
    {
        $row = array(
            'product_id' => $this->_QcOrder['product_id'],
            'quantity' => 0,
            'customQty' => 0, //用于其它
            'operationType' => 2,
            'unsellable' => 0,
            'warehouse_id' => $this->_QcOrder['warehouse_id'],
            'reference_code' => $this->_QcOrder['qc_code'], //操作单号
            'application_code' => 'QC', //操作类型
            'note' => '质检入库',
        );
        if($this->_submitFromPDA){
            $row['operationType'] = 8;
        }
        $obj = new Service_ProductInventoryProcess();
        $onWay = ($this->_asnItem[$this->_QcOrder['rd_id']]['rd_received_qty'] + $this->_params['receivedQty']) - $this->_asnItem[$this->_QcOrder['rd_id']]['rd_receiving_qty'];
        if ($onWay > 0) {
            $qty = $this->_asnItem[$this->_QcOrder['rd_id']]['rd_receiving_qty'] - $this->_asnItem[$this->_QcOrder['rd_id']]['rd_received_qty'];
            $row['customQty'] = $qty;
        } else {
            $row['customQty'] = $this->_params['receivedQty'];
        }
        $row['quantity'] = $this->_params['receivedQty'];
        $row['unsellable'] = $this->_params['problemQty'];

        $result = $obj->update($row);
        if (!isset($result['state']) || $result['state'] != '1') {
            // $this->_errorArr[]=array('errorCode'=>'50000','errorMsg'=>'Internal error');
            throw new Exception('Inventory Internal error');
        }
    }
 private function inventory_batch() {
        if($this->_params['problemQty'] <= 0)
            return false;
         $row = array(
            'lc_code' => $this->_params['shelf'],
            'product_id' => $this->_QcOrder['product_id'],
            'receiving_code'   => $this->_QcOrder['receiving_code'],
            'receiving_id'   => $this->_QcOrder['receiving_id'],
            'customer_code'=>  $this->_QcOrder['customer_code'],
            'product_barcode' => $this->_QcOrder['product_barcode'],
            'application_code' => 'Putaway',                     
            'lot_number' => 1,
            'ib_status' => 0,
            'ib_quantity' => 0,
            'warehouse_id' => $this->_warehouseId,
            'ib_fifo_time' => $this->_date,
            'ib_add_time' => $this->_date,
             'ib_quantity'       => $this->_params['problemQty'],
             'hs_serial_no'=> $this->_QcOrder['hs_serial_no'],
        );
       
        $receiving  =   Service_Receiving::getByField($this->_QcOrder['receiving_id'] , 'receiving_id' , array('reference_no','supplier_id'));
        $row['reference_no']    =   $receiving['reference_no'];
        $row['supplier_id']    =   $receiving['supplier_id'];              
        
        $ibId = Service_InventoryBatch::add($row);
        if(!$ibId){
            throw new Exception('添加批次库存失败');
        }
        $log = array(
            'lc_code' => $this->_params['shelf'],
            'product_id' => $this->_QcOrder['product_id'],
            'product_barcode' => $this->_QcOrder['product_barcode'],
            'reference_no' => $receiving['reference_no'],
            'box_code' => '',
            'application_code' => 'Putaway',
            'warehouse_id' =>$this->_warehouseId,
            'receiving_code' =>$this->_QcOrder['receiving_code'],
            'supplier_id' => $receiving['supplier_id'],
            'ib_id' => $ibId,
            'ibl_quantity_before' => 0,
            'ibl_quantity_after' => 0,
            'user_id' => $this->_userId,
            'ibl_ip' => Common_Common::getIP(),
            'ibl_add_time' => $this->_date,
        );
        Service_InventoryBatchLog::add($log);         
         
    }
    /*
     * @质检入口，事务处理
     * @质检完成
     * @return array('state','error','message')
     */
    public function submit($params = array())
    {
        $result = array(
            'state' => 0,
            'error' => array(),
            'message' => ''
        );

        $db = Service_QualityControl::getModelInstance()->getAdapter();
        $this->setData($params);
        $this->valid();
        if (!empty($this->_errorArr)) {
            $result['error'] = $this->_errorArr;
            return $result;
        }
        $db->beginTransaction();
        try {
            $this->updateAsnItem();
            $this->updateProduct();
            $this->updateQC();
            $this->putaway();
            $this->inventory();
			//$this->putawaybox();
            $this->inventory_batch();
            //$db->rollBack();
            $allQc = Service_QualityControl::getByCondition(array('receiving_code'=>$this->_QcOrder['receiving_code']),"*");
            $stag = true;
            foreach($allQc as $key=>$value){
                if($value['qc_status']=="0"){
                    $stag = false;
                }
            }
            if($stag){
                //添加asn日志
                $receivingRow = Service_Receiving::getByField($this->_QcOrder['receiving_id'],"receiving_id","*");
                $ASNLog = array(
                    'receiving_id'=>$this->_QcOrder['receiving_id'],
                    'receiving_code' => $this->_QcOrder['receiving_code'],
                    'user_id'=>$this->_userId,
                    'customer_code' => $receivingRow['customer_code'],
                    'rl_note' => "收货完成",
                    'rl_status_from' => '6',
                    'rl_status_to' => "7",
                    'rl_add_time'=>date("Y-m-d H:i:s"),
                    'rl_ip'=>Common_Common::getIP()
                );
                Service_ReceivingLog::add($ASNLog);
            }
            
            $db->commit();
            $result = array('state' => 1, 'message' => Ec::Lang('operationSuccess'));
            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->setData($params);
    $this->valid(TRUE);

    if (!empty($this->_errorArr)) {
      throw new Exception(print_r($this->_errorArr, TRUE));
    }

    $this->updateAsnItem();
    $this->updateQC();
    $this->putaway();
    $this->updateProduct();
    $this->inventory();

    $allQc = Service_QualityControl::getByCondition(array('receiving_code' => $this->_QcOrder['receiving_code']));
    $stag  = TRUE;

    foreach ($allQc as $key => $value) {
      if (0 === (int) $value['qc_status']) {
        $stag = FALSE;
      }
    }

    $receivingRow = Service_Receiving::getByField($this->_QcOrder['receiving_id'], 'receiving_id');
    $count        = Service_ReceivingTracking::getByCondition(array(
      'receiving_code' => $receivingRow['receiving_code'],
      'description'    => '收货中',
    ),'count(*)');

    if (!$count) {
      $warehouse         = Service_Warehouse::getByField($receivingRow['warehouse_id'], 'warehouse_id');
      $receivingTracking = array(
        'receiving_code'  => $receivingRow['receiving_code'],
        'location'        => $warehouse['warehouse_name'],
        'time'            => $this->_date,
        'tracking_number' => $receivingRow['traf_name'],
        'on_status'       => 2,
        'description'     => '收货中',
        'from_status'     => $receivingRow['receiving_status'],
        'to_status'       => $receivingRow['receiving_status'],
        'warehouse_id'    => $receivingRow['warehouse_id'],
      );
      Service_ReceivingTracking::add($receivingTracking);
    }

    if ($stag) {
      // 添加ASN日志
      $ASNLog = array(
        'receiving_id'   => $this->_QcOrder['receiving_id'],
        'receiving_code' => $this->_QcOrder['receiving_code'],
        'user_id'        => $this->_userId,
        'customer_code'  => $receivingRow['customer_code'],
        'rl_note'        => '收货完成',
        'rl_status_from' => '6',
        'rl_status_to'   => '7',
        'rl_add_time'    => $this->_date,
        'rl_ip'          => Common_Common::getIP()
      );
      Service_ReceivingLog::add($ASNLog);
    }
  }

    /**
     * @产品未到货,事务处理
     * @param array $params
     * @return array
     */
    public function stopQcTransaction($params = array())
    {
        $result = array(
            'state' => 0,
            'error' => array(),
            'message' => ''
        );

        $db = Service_QualityControl::getModelInstance()->getAdapter();
        $this->setData($params);
        if (empty($this->_QcOrder)) {
            $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' => Ec::Lang('paramsErrormsg'));
        }
        if(empty($this->_params['remark'])){
            $this->_errorArr[] = array('errorCode' => '10002', 'errorMsg' =>'请填写备注.');
        }
        if ($this->_QcOrder['qc_status'] != '0' && isset($this->_QcOrder['qc_status'])) {
            $this->_errorArr[] = array('errorCode' => '10005', 'errorMsg' => Ec::Lang('errorState'));
        }
        if (!empty($this->_errorArr)) {
            $result['error'] = $this->_errorArr;
            return $result;
        }
        $db->beginTransaction();
        try {
            $qcRow = array(
                'qc_received_quantity' => 0,
                'qc_status' => 2, //状态 转为 已上架
                'lc_code' => '',
                'qc_note' => $this->_params['remark'],
                'qc_operator_id' => $this->_params['userId'],
                'qc_quantity_sellable' => 0,
                'qc_quantity_unsellable' => 0,
                'qc_update_time' => $this->_date,
                'qc_finish_time' => $this->_date,
            );
            if (!Service_QualityControl::update($qcRow, $this->_QcOrder['qc_id'])) {
                throw new Exception('Update QcOrder Fail.');
            }
            $db->commit();
            $result = array('state' => 1, 'message' => Ec::Lang('operationSuccess'));

        } catch (Exception $e) {
            $db->rollBack();
            $result['error'][] = array(
                'errorCode' => '50000',
                'errorMsg' => $e->getMessage()
            );
        }
        return $result;
    }


    /**
     * @param string $QcCode
     * @return array
     */
    public function getQcOrder($QcCode = '')
    {
        $result = array(
            'state' => 0,
            'data' => array(),
            'message' => ''
        );

        $qcRow = Service_QualityControl::getByField($QcCode, 'qc_code');
        if (empty($qcRow)) {
            $result['message'] = Ec::Lang('notFound');
            return $result;
        }
        $warehouseId = Service_User::getUserWarehouseId();
        $warehouse = Common_DataCache::getWarehouse();
        $status = self::getStatus();
        $qcRow['warehouse_code'] = isset($warehouse[$qcRow['warehouse_id']]) ? $warehouse[$qcRow['warehouse_id']]['warehouse_code'] : '';
        $qcRow['status'] = isset($status[$qcRow['qc_status']]) ? $status[$qcRow['qc_status']] : '';
        $userRow = Service_User::getByField($qcRow['receiving_user_id'], 'user_id', array('user_name', 'user_name_en'));
        $qcRow['receiving_user'] = $userRow['user_name'];
        $qcRow['operator_user'] = '';
        if ($qcRow['qc_operator_id'] != '0') {
            $userRow = Service_User::getByField($qcRow['qc_operator_id'], 'user_id', array('user_name', 'user_name_en'));
            $qcRow['operator_user'] = $userRow['user_name'];
        }

        //qcOption 质检项
        if ($qcRow['qc_type'] == '1') {
            $qcItem = Service_ProductQcOptions::getByItemCondition(array(), '*');
            $productQc = Service_ProductQcMap::getByCondition(array('product_id' => $qcRow['product_id'], 'warehouse_id_arr' => array(0, $warehouseId)), '*');
            foreach ($productQc as $key => $val) {
                $qcRow['qcOption'][$val['pqo_id']] = $val;
                $qcRow['qcOption'][$val['pqo_id']]['qc'] = $qcItem[$val['pqo_id']]['pqo_name'];
            }
        }
        $qcRow['product'] = Service_Product::getByField($qcRow['product_id'], 'product_id', array('product_sku','product_title_en', 'product_title', 'product_receive_status', 'product_weight', 'product_net_weight', 'pc_id'));
        $packageMap = Service_ProductPackageMap::getByCondition(array('product_id' => $qcRow['product_id'], 'warehouse_id' => $qcRow['warehouse_id']), '*');
        $qcRow['product_sku'] = $qcRow['product']['product_sku'];

        $qcRow['product']['package'] = array(
            'pp_id' => '',
            'pp_barcode' => '',
            'pp_name' => '',
        );
        if (!empty($packageMap)) {
            $package = Service_ProductPackage::getByField($packageMap[0]['pp_id'], 'pp_id');
            $qcRow['product']['package'] = array(
                'pp_id' => isset($package['pp_id']) ? $package['pp_id'] : '',
                'pp_barcode' => isset($package['pp_barcode']) ? $package['pp_barcode'] : '',
                'pp_name' => isset($package['pp_id']) ? $package['pp_id'] : '',
            );
        }

        $result['state'] = 1;
        $result['data']['order'] = $qcRow;

        $result['data']['result'] = array();
        if ($qcRow['qc_status'] != '0') {
            $qcOptions = Common_DataCache::getQcOptions();
            $typeArr = Service_TypeCategory::getByCode('QCR_PROBLEM_TYPE');
            $data = Service_QualityControlResult::getByCondition(array('qc_code' => $QcCode), '*');
            foreach ($data as $key => $val) {
                $result['data']['result'][$val['pqo_id']] = $val;
                $result['data']['result'][$val['pqo_id']]['pqo'] = isset($qcOptions[$val['pqo_id']]) ? $qcOptions[$val['pqo_id']] : array();
                $result['data']['result'][$val['pqo_id']]['problem_type'] = isset($typeArr['data']['item'][$val['qcr_problem_type']]) ? $typeArr['data']['item'][$val['qcr_problem_type']] : array();
            }
            //收货批次
            $rdbRow = Service_ReceivingDetailBatch::getByField($QcCode, 'qc_code', array('rdb_weight', 'labeled', 'non_labeled_qty'));
            $result['data']['rdb'] = $rdbRow;
            $lcCode = self::getProductLocation($qcRow['product_id'],$qcRow['warehouse_id']);
            $result['data']['other'] = array(
                'date' => $qcRow['qc_finish_time'],
                'qc_user_id' => $qcRow['qc_operator_id'],
                'lc_code' => $lcCode,
                'user_name' => $qcRow['operator_user'],
            );
        } else {
            //推荐货架:在用、空货架
            $lcCode = self::getProductLocation($qcRow['product_id'],$qcRow['warehouse_id']);
            $userRow = Service_User::getLoginUser();
            $result['data']['other'] = array(
                'date' => date('Y-m-d H:i:s'),
                'qc_user_id' => Service_User::getUserId(),
                'lc_code' => $lcCode,
                'user_name' => isset($userRow['user_name']) ? $userRow['user_name'] : '',
            );
        }
        //增加putaway_box获取
        $boxConditon = array(
        	'qc_code'=>$QcCode,
        	'product_barcode'=>$qcRow['product_barcode']	
        );
        //print_r($boxConditon);exit;
        $box = Service_PutawayBox::getByCondition($boxConditon,'*');
        if(empty($box)){
        	$box = array();
        }
        $result['data']['box'] = $box;
        return $result;
    }

    /**
     * @desc 获取产品历史货架
     * @param int $productId
     * @param int $warehouseId
     */
    public static function getProductLocation($productId = '', $warehouseId = '')
    {
        $lcCode = '';
        if ($productId == '' || $warehouseId == '') {
            return $lcCode;
        }
        $ibRows = Service_InventoryBatch::getByCondition(array('warehouse_id' => $warehouseId, 'product_id' => $productId, 'ib_status' => 1), array('lc_code'), 1, 1);
        if (!empty($ibRows)) { // 有批次库存就随便取一个货架，否则不用推荐货架
            $lcCode = $ibRows[0]['lc_code'];
        }/* else {
            $condition = array(
                'product_id' => $productId,
                'warehouse_id' => $warehouseId,
            );
            $rows = Service_ProductLocationMap::getByCondition($condition);
            $lcCode = isset($rows[0]['lc_code']) ? $rows[0]['lc_code'] : '';
        }*/
        return $lcCode;
    }

    /**
     * @author william-fan
     * @desc 处理分箱数据
     */
    private function putawayBox()
    {
        $boxArr = $this->_params['boxArray'];
        if (!empty($boxArr)) {
            foreach ($boxArr as $key => $val) {
                $putawayBoxRow = array(
                    'qc_code' => $this->_QcOrder['qc_code'],
                    'box_code' => strtoupper($val['box_code']),
                    'product_barcode' => $this->_QcOrder['product_barcode'],
                    'product_id' => $this->_QcOrder['product_id'],
                    'bb_quantity' => $val['quantity'],
                    'bb_status' => '1',//直接完成,避免上架时，又要更新
                    'bb_add_time' => date('Y-m-d H:i:s', time()),
                );
                Service_PutawayBox::add($putawayBoxRow);
            }
        }
    }

    /*pda确认质检单
    * @author Gilbert
    * @date 2015-08-25
    * @param array $params
    * @return array
    */
    public function pdaSubmit($params){
        $return = array('state'=>0,'message'=>'');
        try{
            $this->setUser();
            $this->checkPdaParams($params);
            $this->setOrder($params['qc_code']);
            $this->setProduct($this->_QcOrder['product_id']);
            $this->setReceiving($this->_QcOrder['receiving_code']);
            $this->_submitFromPDA = true;
            $this->_params['firstReceived'] = $this->_product['product_receive_status']==0?0:1;
            $this->_params['first_product_barcode'] = isset($this->_params['barcode'])?$this->_params['barcode']:'';
            //首次收货，设置基础信息
            if($this->_params['firstReceived']==0){
                if($this->_product['product_barcode_type']==1 && empty($this->_params['first_product_barcode'])){
                    throw new Exception('自定义条码的产品首次收货必须填上条码');
                }
                $this->_params['product'] = array(
                    'product_id'=>$this->_product['product_id'],
                    'declaredValue'=>$this->_product['product_declared_value'],
                    'length'=>$this->_params['length'],
                    'width'=>$this->_params['width'],
                    'height'=>$this->_params['height'],
                    'category'=>$this->_params['category'],
                    'package'=>$this->_params['package'],//取入库单的
                );
            }
            if($this->_QcOrder['qc_status']!=0){
                throw new Exception('质检单已质检',2000);
            }
            if($this->_QcOrder['qc_quantity'] != $params['received_number']){
                throw new Exception('预约入库数量与收货数量不相等',2000);
            }
        }catch(Exception $e){
            $return['message'] = $e->getMessage();
            return $return;
        }

        $db = Service_QualityControl::getModelInstance()->getAdapter();
        $db->beginTransaction();
        try {
            //更新QC单相关数量
            $this->updateQC();
            //更新入库单相关数量
            $this->updateAsnItem();
            //更新产品为已收过货
            $this->updateProduct();
            //更新库存表的在途数量和收货数量
            $this->inventory();
            //生成上架单信息,如果QC单去分箱，那么要更新上架单信息
            $this->putaway();
            /*$allQc = Service_QualityControl::getByCondition(array('receiving_code'=>$this->_QcOrder['receiving_code']),"*");
            $finishQc = 0;
            foreach($allQc as $key=>$value){
                if($value['qc_status']>0){
                    $finishQc += 1;
                }
            }*/
            if($this->_receiving['receiving_status']==7){
                //添加asn日志
                $ASNLog = array(
                    'receiving_id'=>$this->_QcOrder['receiving_id'],
                    'receiving_code' => $this->_QcOrder['receiving_code'],
                    'user_id'=>$this->_userId,
                    'customer_code' => $this->_receiving['customer_code'],
                    'rl_note' => "收货完成",
                    'rl_status_from' => '6',
                    'rl_status_to' => "7",
                    'rl_add_time'=>date("Y-m-d H:i:s"),
                    'rl_ip'=>Common_Common::getIP()
                );
                Service_ReceivingLog::add($ASNLog);
            }else{
                /*if($finishQc==1){
                    $warehouse = Service_Warehouse::getByField($this->_receiving['warehouse_id'],'warehouse_id',"*");
                    $receivingTracking = array(
                        'receiving_code'=>$this->_receiving['receiving_code'],
                        'location'=>$warehouse['warehouse_name'],
                        'time'=>date("Y-m-d H:i:s"),
                        'tracking_number'=>$this->_receiving['traf_name'],
                        'on_status'=>'2',
                        'description'=>'收货中',
                        'from_status'=>$this->_receiving['receiving_status'],
                        'to_status'=>$this->_receiving['receiving_status'],
                        'warehouse_id'=>$this->_receiving['warehouse_id'],
                    );
                    Service_ReceivingTracking::add($receivingTracking);
                }*/
            }
            $db->commit();
            $return['state'] = 1;
            $return['message'] = '质检成功';
        }catch (Exception $e){
            $db->rollback();
            $return['message'] = $e->getMessage();
        }

        $this->_submitFromPDA = false;

        return $return;
    }
    protected function trimParams($params){
        foreach($params as $key=>$value){
            $params[$key] = is_scalar($value)?trim($value):$value;
        }
        return $params;
    }
    /*检查pda传来的是数据
     * @author Gilbert
     * @date 20158-08-26
     * @param array $params pda出来的数据
     * @return void
     */
    protected function checkPdaParams($params){
        $params = $this->trimParams($params);
        if(!is_array($params) || empty($params)){
            throw new Exception('质检数据不正确',2000);
        }
        if(!isset($params['qc_code']) || empty($params['qc_code'])){
            throw new Exception('缺少入库单',2000);
        }
        if(!isset($params['received_number']) || !preg_match('/^[1-9]+[0-9]*$/',trim($params['received_number']))){
            throw new Exception('收货数量必须是大于0的整数',2000);
        }
        if(isset($params['defective_number']) && $params['defective_number']){
            if(preg_match('/^[1-9]+[0-9]*$/',trim($params['defective_number']))){
                if($params['defective_number'] > $params['received_number']){
                    throw new Exception('不良品数量大于收货数量',2000);
                }
            }else{
                throw new Exception('不良品数量必须是大于0的整数',2000);
            }
        }else{
            $params['defective_number'] = 0;
        }
        if(isset($params['barcode'])){
            $params['barcode'] = trim($params['barcode']);
            if(!$this->checkBarcode($params['barcode'])){
                throw new Exception('条码格式不正确,条码只能由数字和中横线"-"组成，且长度不超过18个字符',2000);
            }
        }
        if(isset($params['product_weight'])){
            $params['product_weight'] = trim($params['product_weight']);
            if(!preg_match("/^[1-9]\d*(.\d+)*$|^0.\d*[1-9]+\d*$/", $params['product_weight'])){
                throw new Exception('产品重量必须是大于0的数字',2000);
            }
        }
        if(isset($params['length'])){
            $params['length'] = trim($params['length']);
            if(!is_numeric($params['length'])){
                throw new Exception('产品长必须是数字',2000);
            }
        }
        if(isset($params['width'])){
            $params['width'] = trim($params['width']);
            if(!is_numeric($params['width'])){
                throw new Exception('产品宽必须是数字',2000);
            }
        }
        if(isset($params['height'])){
            $params['height'] = trim($params['height']);
            if(!is_numeric($params['height'])){
                throw new Exception('产品高必须是数字',2000);
            }
        }
        if(isset($params['category']) && $params['category']!==''){
            $category = Service_ProductCategory::getByCondition(array('pc_id'=>$params['category']));
            if(!$category){
                throw new Exception('产品目录不存在');
            }
        }
        $this->setPdaParams($params);
    }
    /*设置pda传来的数据
     * @author Gilbert
     * @date 2015-08-26
     * @param array $params pda传来的数据
     */
    protected function setPdaParams($params){
        $this->setData();
        $this->_params['receivedQty'] = $params['received_number'];
        $this->_params['problemQty'] = $params['defective_number'];
        $this->_params['category'] = isset($params['category'])?$params['category']:0;
        $this->_params['package'] = isset($params['package'])?$params['package']:0;
        $this->_params['barcode'] = isset($params['barcode'])?$params['barcode']:'';
        $this->_params['productWeight'] = isset($params['product_weight'])?$params['product_weight']:0;
        $this->_params['length'] = isset($params['length'])?$params['length']:0;
        $this->_params['width'] = isset($params['width'])?$params['width']:0;
        $this->_params['height'] = isset($params['height'])?$params['height']:0;
    }
    /*初始化质检单
     * @author Gilbert
     * @date 2015-08-26
     * @param string $code 质检单号
     * @return void
     */
    protected function setOrder($code){
        if(!$code){
            throw new Exception('缺少质检单',2000);
        }
        $order = Service_QualityControl::getByField($code,'qc_code');
        if($order instanceof Zend_Db_Table_Row){
            $order = $order->toArray();
        }
        if(!$order){
            throw new Exception('质检单不存在',2000);
        }
        $this->_QcOrder = $order;
    }
    /*初始化入库单
     * @author Gilbert
     * @date 2015-08-26
     * @param string $code 入库单号
     * @return void
     */
    protected function setReceiving($code){
        if(!$code){
            throw new Exception('缺少入库单',2000);
        }
        $order = Service_Receiving::getByField($code,'receiving_code');
        if($order instanceof Zend_Db_Table_Row){
            $order = $order->toArray();
        }
        if(!$order){
            throw new Exception('质检单对应的入库单不存在',2000);
        }
        $this->_receiving = $order;
    }
    /*设置产品信息
     * @author Gilbert
     * @date 2015-08-26
     * @return void
     */
    protected function setProduct($productId){
        if(!$productId){
            throw new Exception('产品ID为空',2000);
        }
        $product = Service_Product::getByField($productId,'product_id');
        if($product instanceof Zend_Db_Table_Row){
            $product = $product->toArray();
        }
        if(!$product){
            throw new Exception('质检单对应的产品不存在',2000);
        }
        $this->_product = $product;
    }
    /* @desc 获取待分箱的数量
     *
     *
     */
    public function getQtyPendedToDivide($code){
        $return = array('passed_qty'=>0,'defective_qty'=>0);
        if(!$code){
            return $return;
        }
        $qcRow = Service_QualityControl::getByField($code,'qc_code');
        if($qcRow instanceof Zend_Db_Table_Row){
            $qcRow = $qcRow->toArray();
        }
        if(!$qcRow){
            return $return;
        }
        if($qcRow['qc_status']!=1){
            return $return;
        }
        $detail = Service_PutawayDetail::getByCondition(array('qc_code'=>$code));
        if($detail){
            if(count($detail)==1 && empty($detail[0]['box_code'])){
                $return['passed_qty'] = $qcRow['qc_quantity_sellable'];
                $return['defective_qty'] = $qcRow['qc_quantity_unsellable'];
            }else{//说明已经分箱了
                $passedQty = 0;
                $defectiveQty = 0;
                foreach($detail as $value){
                    if($value['pd_product_type']==1){
                        $passedQty += $value['pd_quantity'];
                    }else if($value['pd_product_type']==2){
                        $defectiveQty += $value['pd_quantity'];
                    }
                }
                $return['passed_qty'] = $qcRow['qc_quantity_sellable']-$passedQty;
                $return['defective_qty'] = $qcRow['qc_quantity_unsellable']-$defectiveQty;
            }
        }
        return $return;
    }
}