<?php
/**
 * 整进整出
 */
class Service_OrderInOut {
	const TYPE_ASN = 0; // 验证类型：创建ASN时验证
	const TYPE_SHIPMENT = 1; // 验证类型：加挂时验证
	
	/**
	 * 获取缓存目录
	 *
	 * @return string    返回缓存存放的目录
	 */
	public static function getCacheDir() {
		return APPLICATION_PATH . '/../data/cache/';
	}
	/**
	 * 判断是否存在缓存文件
	 *
	 * @param string $cache    缓存文件名
	 * @return boolean
	 */
	public static function isCache($cache) {
		$cache = trim($cache);
		// 合法缓存文件名为md5('XXX') . '.php'
		if (32 !== strpos($cache, '.php')) {
			return FALSE;
		}
		return is_file(self::getCacheDir() . $cache);
	}
	/**
	 * 删除缓存文件
	 *
	 * @param string $cache    文件名
	 * @return boolean
	 */
	public static function removeCache($cache) {
		$cache = trim($cache);
		if (!self::isCache($cache)) {
			return FALSE;
		}
		return unlink(self::getCacheDir() . $cache);
	}
	/**
	 * 获取只能用于整进整出的运输方式
	 *
	 * @return array
	 */
	public static function getShippingMethod() {
		return array(
		//'SELF-HKDHL', // 临时测试使用
		'DHL-DL', 'SELF-HF-DGM', 'SELF-HF-PNLP', 'SELF-HF-EUB', 'SELF-HF-ASENDIA', 'SELF-HF-DDP', 'JD-SPSR', 'JD-YANWEN', 'JD-EQUICK', 'SELF-PNLG', 'JD-EQUICK-EE', 'JD-EQUICK-NL', 'JD-EQUICK-GB', 'EQUICK027-20', 'EQUICK027-120', 'EQUICK02-01', 'SELF-CNDHL', 'SELF-XM-HKSF', 'SELF-XM-YW', 'SELF-XM-FDX', 'SELF-XM-DHL eCommerce', 'JD-CKY', 'SELF-XM-THHK','BF-SELF-HK','HQYP-SELF','JD-UPS');
	}
	/**
	 * 把Excel文件临时缓存为PHP数组，以便后续使用
	 *
	 * @param string  $file             上传订单数据的EXCEL文件
	 * @param integer $type             验证类型
	 * @param string  $shipBatchCode    出区总单号，加挂验证时必填
	 *
	 * @return array    array(
	 *                    'status'  => 'integer|0：失败；1：成功',
	 *                    'message' => 'string|失败：错误信息；成功：缓存文件名'
	 *                  )
	 */
	public static function buildCache($file, $type = self::TYPE_ASN, $shipBatchCode = '', $dir = '') {
		$response = array('status' => 0, 'message' => '');
		$data = array('valid' => TRUE, // 整体数据的有效性
		'weight' => 0, // 总重量
		'car' => array(), // 车牌，一批数据只能有一个车牌号
		'bag' => array(), // 包袋号，同个包袋号的订单必须属于同一种运输方式
		'dross' => 0, // 不符合条件的订单数量
		'shipBatch' => array(), // 出货总单信息，仅加挂时
		);
		if (!is_file($file)) { // 判断文件是否存在
			$response['message'] = '文件【' . $file . '】不存在';
			return $response;
		}
		$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // 文件扩展名
		if (!in_array($ext, array('xls', 'xlsx'), TRUE)) { // 允许的文件类型
			$response['message'] = '文件类型【' . $ext . '】错误，仅支持xls或xlsx类型文件';
			return $response;
		}
		if (self::TYPE_SHIPMENT === $type && '' === trim($shipBatchCode)) {
			$response['message'] = '出货总单号不能为空';
			return $response;
		} elseif (self::TYPE_SHIPMENT === $type) {
			$shipBatch = Service_ShipBatch::getByField($shipBatchCode, 'sb_code');
			if (empty($shipBatch)) {
				$response['message'] = '不存在出货总单【' . $shipBatchCode . '】';
				return $response;
			} elseif (0 !== (int)$shipBatch['sb_status']) {
				$response['message'] = '出货总单【' . $shipBatchCode . '】不是草稿状态';
				return $response;
			}
			$data['shipBatch'] = $shipBatch;
		}
                //获取平台，用于后面环球平台的判断
                $platformShipBatch = self::getPlatformOfShipBatch( $shipBatchCode );
		require_once APPLICATION_PATH . '/../libs/PHPExcel.php';
		require_once APPLICATION_PATH . '/../libs/PHPExcel/IOFactory.php';
		set_time_limit(0); // 不限制执行时间
		ini_set('memory_limit', '2048M'); // 2G内存限制
		$loaderObj = PHPExcel_IOFactory::load($file); // 加载Excel文件
		if (!$loaderObj) {
			$response['message'] = '文件解析失败，请确保所上传的文件类型为xls或xlsx';
			return $response;
		}
		$sheetObj = $loaderObj->getSheet(0); // 获取第一个工作表
		$maxCols = PHPExcel_Cell::columnIndexFromString($sheetObj->getHighestColumn()); // 最大列数
		$maxRows = $sheetObj->getHighestRow(); // 最大行数
		$cacheDir = self::getCacheDir();
		$otn = array(); // 缓存运单号，查验是否有重复的
		$orderCodeArr = array();
                $platformOrder = array();
		for ($i = 2;$i <= $maxRows;++$i) { // 排除表头，从第2行开始读取
			$data['upload'][$i - 2] = array('valid' => FALSE, // 数据有效性
			'order' => array(), // 订单信息
			'customer' => '', // 客户代码
			'message' => '未经过验证', // 验证结果
			);
			for ($j = 0;$j < $maxCols;++$j) { // 读取各个单元格的内容
				$data['upload'][$i - 2][self::getMapIndex($j) ] = trim($sheetObj->getCell(PHPExcel_Cell::stringFromColumnIndex($j) . $i)->getValue());
			}
			$carNumber = $data['upload'][$i - 2]['car_number'];
			$bagNumber = $data['upload'][$i - 2]['bag_number'];
			$trackingNumber = $data['upload'][$i - 2]['tracking_number'];
			$weight = $data['upload'][$i - 2]['weight'];
			$orderCode = $data['upload'][$i - 2]['order_code'];
			$length = $data['upload'][$i - 2]['length'];
			$width = $data['upload'][$i - 2]['width'];
			$height = $data['upload'][$i - 2]['height'];
			$so_fee_weight = $data['upload'][$i - 2]['so_fee_weight'];
			$message = array();
			$firstStep = TRUE; // 第1步验证
			if ('' === $carNumber) {
				$message[] = '车牌号不能为空';
				$firstStep = FALSE;
			} else {
				$data['car'][] = $carNumber;
				$data['car'] = array_unique($data['car']);
			}
			/*if($orderCode==""){
			       $message[] = '订单号不能为空';
			       $firstStep = FALSE;
			   }*/
			if ('' === $bagNumber) {
				$message[] = '包袋号不能为空';
				$firstStep = FALSE;
			} else {
				$outboundBag = Service_OutboundBag::getFields($bagNumber, 'ob_no');
				$ShipBatchattr = Service_ShipBatchAttribute::getByField($shipBatchCode, 'sb_code');
				//判断是整进整出的导入还是加挂的导入
				if (!empty($dir)) {
					if ('E2F' == $ShipBatchattr['form_type']) {
						if ($outboundBag['sm_code'] !== 'ZCCQ') {
							$message[] = '出区暂存只能加挂运输代码为ZCCQ的袋子';
							$firstStep = FALSE;
						} else {
							$shipbatch = Service_ShipBatchDetail::getByCondition(array('sb_code' => $shipBatchCode), '*');
							$batchdetail = Service_OutboundBagDetail::getByCondition(array('ob_no' => $bagNumber), "*");
							if (!empty($shipbatch)) {
								$aoutboundBag = Service_OutboundBagDetail::getByField($shipbatch[0]['ob_no'], 'ob_no');
								$customer = Service_Orders::getByField($aoutboundBag['order_code'], 'order_code');
								if (!empty($batchdetail)) {
									$order = array();
									//判断已经加挂的袋子和要加挂的袋子是否是同一个客户的
									foreach ($batchdetail as $key => $value) {
										$order[$key] = Service_Orders::getByField($value['order_code'], 'order_code');
										if ($order[$key]['customer_code'] !== $customer['customer_code']) {
											exit(Zend_Json::encode(array('state' => 0, 'message' => '袋子下的订单与已经加挂的袋子下的订单不是同一客户的')));
										}
									}
								}
							} else {
								//第一次加挂袋子
								if (!empty($batchdetail)) {
									$order = array();
									foreach ($batchdetail as $key => $value) {
										$order[$key] = Service_Orders::getByField($value['order_code'], 'order_code');
										if (count($order) > 1) {
											if ($order[$key - 1]['customer_code'] !== $order[$key]['customer_code']) {
												exit(Zend_Json::encode(array('state' => 0, 'message' => '袋子下的订单不是同一客户的')));
											}
										}
									}
								}
							}
						}
					}
				}
				if (!empty($outboundBag)) { // 存在包袋需要判断
					if (0 !== (int)$outboundBag['ob_status']) { // 判断包袋状态
						$message[] = '包袋【' . $bagNumber . '】不是草稿状态';
						$firstStep = FALSE;
					} else { // 判断包袋是否为空袋
						$outboundBagDetail = Service_OutboundBagDetail::getByCondition(array('ob_no' => $bagNumber));
						if (!empty($outboundBagDetail) && count($outboundBagDetail) > 0) {
							$message[] = '包袋【' . $bagNumber . '】不是空袋';
							$firstStep = FALSE;
						}
					}
				}
			}
			if ('' === $trackingNumber) {
				$message[] = '运单号不能为空';
				$firstStep = FALSE;
			}
			if ($length != "" && !preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $length)) {
				$message[] = '长只能为数字';
				$firstStep = FALSE;
			}
			if ($width != "" && !preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $width)) {
				$message[] = '宽只能为数字';
				$firstStep = FALSE;
			}
			if ($height != "" && !preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $height)) {
				$message[] = '高只能为数字';
				$firstStep = FALSE;
			}
			if ($so_fee_weight != "" && !preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $so_fee_weight)) {
				$message[] = '计费重只能为数字';
				$firstStep = FALSE;
			}
			if ('' === $weight) {
				$message[] = '重量不能为空';
				$firstStep = FALSE;
			} elseif (!preg_match('/^[0-9]+(?:\.[0-9]+)?$/', $weight)) {
				$message[] = '重量只能为数字';
				$firstStep = FASLE;
			} elseif (floatval($weight) < 0.0000001) { // 重量必须大于0，这里的0.0000001只是精度限制
				$message[] = '重量必须大于0';
				$firstStep = FALSE;
			} else { // 统计总重量
				$weight = floatval(number_format($weight, 4));
				$data['upload'][$i - 2]['weight'] = $weight;
				$data['weight']+= $weight;
			}
			if ('' !== $trackingNumber && isset($otn[$trackingNumber]) && $orderCodeArr[$otn[$trackingNumber]] != $orderCode) { // 验证运单号
				$message[] = '与【序号' . $otn[$trackingNumber] . '】的运单号重复';
				$firstStep = FALSE;
			} elseif ('' !== $trackingNumber) { // 记录运单号
				$otn[$trackingNumber] = $i - 1;
				$orderCodeArr[$otn[$trackingNumber]] = $orderCode;
			}
			if (count($data['car']) > 1) { // 只能是同车牌号的批量数据
				$message[] = '同批数据车牌号必须相同';
				$firstStep = FALSE;
			}
			if (!$firstStep) { // 第1步验证不通过，继续下一轮循环
				$data['upload'][$i - 2]['message'] = join($message, '；');
				++$data['dross']; // 验证不通过的记录数+1
				continue;
			}
			$order = Service_Orders::getByCondition(array('order_status_neq' => 0, // 排除已删除状态的订单
			'ref_tracking_number' => $trackingNumber, // 运单号
			));
			if (empty($order)) {
				$data['upload'][$i - 2]['message'] = '找不到与运单号【' . $trackingNumber . '】相匹配的订单数据';
				++$data['dross']; // 验证不通过的记录数+1
				continue;
			} elseif (count($order) > 1) {
				$data['upload'][$i - 2]['message'] = '存在多个订单对应同一个运单号【' . $trackingNumber . '】';
				++$data['dross']; // 验证不通过的记录数+1
				continue;
			}
			$order = $order[0];
			$secondStep = TRUE; // 第2步验证
			//$smCode                    = strtoupper(trim($order['sm_code']));
			$smCode = trim($order['sm_code']);
			$data['bag'][$bagNumber][] = $smCode;
			$data['bag'][$bagNumber] = array_unique($data['bag'][$bagNumber]);
			$data['upload'][$i - 2]['order_code'] = $order['order_code'];
			$customerData = Service_Customer::getByField($order['customer_code'], 'customer_code', array('is_frozen', 'frozen_reason'));
			if ($customerData['is_frozen']) {
				$message[] = '订单号[' . $order['order_code'] . ']客户[' . $order['order_code'] . ']已冻结，冻结原因：' . $customerData['frozen_reason'];
				$secondStep = FALSE;
			}
			if ((int)Service_User::getUserWarehouseId() !== (int)$order['warehouse_id']) { // 订单所属仓库与当前用户登录仓库不匹配
				$message[] = '订单不属于当前仓库';
				$secondStep = FALSE;
			}
			if (count($data['bag'][$bagNumber]) > 1) { // 包袋号存在多种运输方式
				$message[] = '包袋【' . $bagNumber . '】存在多种运输方式';
				$secondStep = FALSE;
			}
			if (!in_array($smCode, self::getShippingMethod(), TRUE)) { // 订单不是特定运输方式
				$message[] = '订单运输方式【' . $smCode . '】不是特定运输方式，不能用于整进整出';
				$secondStep = FALSE;
			}
			if (1 !== (int)$order['order_mode_type']) { // 订单不是集货模式
				$message[] = '订单不是集货模式';
				$secondStep = FALSE;
			}
			switch ($type) {
				case self::TYPE_ASN: // 创建ASN单时验证
					if (2 !== (int)$order['order_status']) { // 订单不是确认状态
						$message[] = '订单不是确认状态' . $type;
						$secondStep = FALSE;
					}
				break;
				case self::TYPE_SHIPMENT: // 加挂出货时验证
					if (4 !== (int)$order['order_status']) { // 订单不是确认状态
						$message[] = '订单[' . $order['order_code'] . ']不是已提交状态';
						$secondStep = FALSE;
					}
					// 订单车牌号与出货总单车牌号不一致
					if ($carNumber !== trim($shipBatch['sb_truck_no'])) {
						$message[] = '与出货总单车牌【' . trim($shipBatch['sb_truck_no']) . '】不一致';
						$secondStep = FALSE;
					}
					$asnOrderDetail = Service_ReceivingOrderDetail::getByField($order['order_code'], 'order_code');
					if (empty($asnOrderDetail)) {
						$message[] = '订单还没有创建ASN';
						$secondStep = FALSE;
					} else {
						$asnInfo = Service_Receiving::getByField((int)$asnOrderDetail['receiving_id'], 'receiving_id');
						if (empty($asnInfo)) {
							$message[] = '订单还没有创建ASN';
							$secondStep = FALSE;
						} elseif (1 !== (int)$asnInfo['receive_model_type']) {
							$message[] = 'ASN单不是集货模式';
							$secondStep = FALSE;
						} elseif (!in_array((int)$asnInfo['receiving_status'], array(5, 6), TRUE)) {
							$message[] = 'ASN单不是在途或收货中状态';
							$secondStep = FALSE;
						}
						$data['upload'][$i - 2]['asn_code'] = isset($asnInfo['receiving_code']) ? $asnInfo['receiving_code'] : '';
					}
				break;
			}
			if (!$secondStep) { // 第2部验证不通过，继续下一轮循环
				$data['upload'][$i - 2]['message'] = join($message, '；');
				++$data['dross']; // 验证不通过的记录数+1
				continue;
			}
                        $platformOrder[$order['platform']][] = $order['order_code'];
			// 到这里，说明已通过验证
			$data['upload'][$i - 2]['valid'] = TRUE; // 订单通过验证
			$data['upload'][$i - 2]['order'] = $order; // 订单信息
			$data['upload'][$i - 2]['customer'] = $order['customer_code']; // 客户代码
			$data['upload'][$i - 2]['message'] = '验证通过';
		}
		if ($data['dross'] > 0) { // 存在验证不通过的记录，整批验证不通过
			$data['valid'] = FALSE;
		}
                //环球平台的订单不能与其他平台的订单混装
                if( count( $platformOrder ) >= 2 && isset( $platformOrder[2] ) ) {
                    $data['valid'] = FALSE;
                    $response['platformError'] = '环球平台的订单不能与其他平台的订单混装,';
                    $otherPlatformCnt = ( isset( $platformOrder[0] ) ? count( $platformOrder[0] ) : 0  ) + ( isset( $platformOrder[1] ) ? count( $platformOrder[1] ) : 0 );
                    $huanQiuPlatformCnt = isset( $platformOrder[2] ) ? count( $platformOrder[2] ) : 0;
                    if( $otherPlatformCnt <= $huanQiuPlatformCnt ) {
                        $otherPlatform = array_merge( ( isset( $platformOrder[0] ) ? $platformOrder[0] : array() ), ( isset( $platformOrder[1] ) ? $platformOrder[1] : array() )  );
                        $response['platformError'] .= '以下是其他平台的订单：'.implode( ',', $otherPlatform );
                    } else {
                        $response['platformError'] .= '以下是环球平台的订单：'.implode( ',', $platformOrder[2] );
                    }
                } else if( isset( $platformOrder[2] ) && !empty( $platformShipBatch ) && !in_array( 2, $platformShipBatch ) ) {
                    $data['valid'] = FALSE;
                    $response['platformError'] .= '出区单已经加挂了其他平台的订单，你上传是环球平台的订单，不能混装';
                } else if( !isset( $platformOrder[2] ) && !empty( $platformShipBatch ) && in_array( 2, $platformShipBatch ) ) {
                    $data['valid'] = FALSE;
                    $response['platformError'] .= '出区单已经加挂了环球平台的订单，你上传的是其他平台订单，不能混装';
                }
		$tmp = md5('ORDER-IN-AND-OUT-' . microtime(TRUE)) . '.php'; // 临时文件名
		$cache = '<?php return ' . var_export($data, TRUE) . '; ?>'; // 缓存内容
		if (FALSE === file_put_contents($cacheDir . $tmp, $cache)) { // 生成缓存文件
                    $response['message'] = '生成缓存文件时发生异常';
		} else {
                    $response['status'] = 1;
                    $response['message'] = $tmp;
		}
		unset($data); // 释放数组
		unlink($file); // 删除文件
		return $response;
	}
	/**
	 * 从缓存文件中读取信息，根据客户创建ASN单
	 *
	 * @param string $cache    缓存文件名
	 * @param array  $param    参数数组
	 * @return array
	 */
	public static function createAsn($cache, $param = array()) {
		$cache = trim($cache);
		if (!self::isCache($cache)) { // 缓存判定
			return array();
		}
		$data = include self::getCacheDir() . $cache; // 加载数据
		$car = $data['car'][0];
		$group = array(); // 按客户分组
		foreach ($data['upload'] as $item) {
			$group[$item['customer']][] = $item;
			$group[$item['customer']]['weight']+= $item['weight'];
		}
		unset($data); // 释放数组
		foreach ($group as $customerCode => $items) { // 根据客户创建ASN单
			$db = Common_Common::getAdapter();
			$weight = $items['weight'];
			unset($items['weight']);
			$piece = count($items);
			$result = array('customer' => $customerCode, 'asn' => '', 'ref' => '', 'piece' => $piece, 'weight' => $weight, 'valid' => TRUE, 'message' => 'ASN单创建成功',);
			$db->beginTransaction(); // 开启事务
			try {
				$user = new Zend_Session_Namespace('userAuthorization');
				$asnCode = Common_GetNumbers::getOnlyCode('ASNOnly', 'BHR');
				$operationTime = date('Y-m-d H:i:s');
				$customer = Service_Customer::getByField($customerCode, 'customer_code');
				$warehouse = Service_Warehouse::getByField('SZ01', 'warehouse_code');
				$refCustomer = strtoupper(uniqid($customerCode)); // 客户参考号，随机产生
				if (empty($customer)) {
					throw new Exception('客户代码【' . $customerCode . '】不存在');
				} elseif (2 !== (int)$customer['customer_status']) {
					throw new Exception('客户【' . $customerCode . '】账号不是正常状态');
				}
				// ASN单信息
				$receiving = array('receiving_code' => $asnCode, // ASN单号
				'reference_no' => $refCustomer, // 客户参考号
				'warehouse_id' => $warehouse['warehouse_id'], // 仓库ID
				'customer_id' => $customer['customer_id'], // 客户ID
				'customer_code' => $customer['customer_code'], // 客户代码
				'receiving_type' => 0, // 收货类型，默认为0
				'receiving_status' => 1, // ASN单状态，默认草稿
				'receiving_add_time' => $operationTime, // 增加时间
				'receiving_update_time' => $operationTime, // 更新时间
				'is_delivery' => isset($param['is_delivery']) ? $param['is_delivery'] : 0, // 是否提货，默认0（不提货）
				'ie_port' => isset($param['ie_port']) ? $param['ie_port'] : '5349', // 进出口口岸，默认深圳前海湾保税港区口岸作业区
				'form_type' => isset($param['form_type']) ? $param['form_type'] : 'I211', // 业务类型，默认一般清关出口入区
				'traf_name' => $car, // 车牌号
				'wrap_type' => isset($param['wrap_type']) ? $param['wrap_type'] : 2, // 包装类型，默认纸箱
				'pack_no' => $piece, // 总件数
				'traf_mode' => isset($param['traf_mode']) ? $param['traf_mode'] : 'Y', // 出入港区运输方式，默认保税港区
				'trade_mode' => isset($param['trade_mode']) ? $param['trade_mode'] : '0110', // 监管方式，默认一般贸易
				'trans_mode' => 3, // 成交方式，默认FOB
				'roughweight' => $weight, // 毛重
				/* 以下内容不用理会 */
				'haveconta' => 0, // 有无集装箱号
				'conta_id' => '', // 集装箱号
				'conta_model' => '', // 集装箱规格号
				'conta_wt' => 0, // 集装箱自重
				'receive_model_type' => 1, // 集货模式
				'receiving_description' => '', // 描述
				);
				$receivingId = Service_Receiving::add($receiving);
				if (!$receivingId) { // 写入ASN数据
					throw new Exception('无法向receiving表写入数据');
				}
				$hasDealOrderCode = array();
				foreach ($items as $item) {
					if (in_array($item['order_code'], $hasDealOrderCode)) continue;
					$order = $item['order']; // 订单信息，缓存的信息
					$order = Service_Orders::getByField((int)$order['order_id'], 'order_id'); // 重新获取订单信息
					$receivingOrderDetail = array('receiving_id' => $receivingId, 'receiving_code' => $asnCode, 'rd_status' => 0, 'order_code' => $order['order_code'], 'rd_add_time' => $operationTime,);
					if (2 !== (int)$order['order_status']) { // 验证订单状态
						throw new Exception('订单【' . $order['order_code'] . '】不是确认状态');
					}
					if (!Service_ReceivingOrderDetail::add($receivingOrderDetail)) { // 写入与ASN相关的订单数据
						throw new Exception('无法向receiving_order_detail表写入数据');
					}
					// 订单状态更新
					Service_Orders::update(array('order_status' => 4, // 已提交状态
					'update_time' => $operationTime,), $order['order_code'], 'order_code');
					// 写订单日志
					Service_OrderLog::add(array('order_id' => (int)$order['order_id'], 'order_code' => $order['order_code'], 'ol_type' => 0, 'order_status_from' => $order['order_status'], 'order_status_to' => 4, 'ol_add_time' => $operationTime, 'user_id' => (int)$user->userId, 'account_id' => 0, 'ol_ip' => Common_Common::getIP(),));
					// 写订单轨迹
					Service_ShipOrderTracking::add(array('order_code' => $order['order_code'], 'sot_location' => '客户仓库', 'sot_add_time' => $operationTime, 'warehouse_id' => (int)$order['warehouse_id'], 'sot_description' => '集货ASN新建成功,集货订单自动提交', 'sot_type' => 0, 'sot_time_offset' => '', 'tracking_number' => $order['order_code'], 'ref_tracking_number' => '', 'status_desc' => '已提交', 'user_id' => (int)$user->userId,));
					// 更新订单操作时间
					Service_OrderOperationTime::update(array('order_id' => (int)$order['order_id'], 'order_code' => $order['order_code'], 'submit_time' => $operationTime, 'submit_user_id' => (int)$user->userId,), $order['order_code'], 'order_code');
					// 预扣费
					$balance = new Service_CustomerBalanceProcess();
					$feeResult = $balance->freezeFee($order['order_code'], $customer['customer_id']);
					if (TRUE !== $feeResult) { // 预扣费异常
						throw new Exception($feeResult);
					}
					$hasDealOrderCode[] = $item['order_code'];
				}
				// 添加ASN日志
				Service_ReceivingLog::add(array('receiving_id' => $receivingId, 'receiving_code' => $asnCode, 'user_id' => (int)$user->userId, 'customer_code' => $customer['customer_code'], 'rl_note' => 'create ASN', 'rl_add_time' => $operationTime, 'rl_status_from' => 1, 'rl_status_to' => 1, 'account_id' => 0, 'rl_ip' => Common_Common::getIP(),));
				$db->commit();
				$result['asn'] = $asnCode;
				$result['ref'] = $refCustomer;
				$result['weight'] = $receiving['roughweight'];
			}
			catch(Exception $e) {
				$db->rollBack();
				$result['asn'] = '';
				$result['ref'] = '';
				$result['valid'] = FALSE;
				$result['message'] = '创建ASN单发生异常：' . $e->getMessage();
			}
			$response[] = $result;
		}
		unset($group); // 释放数组
		self::removeCache($cache);
		return $response;
	}
	/**
	 * 订单加挂同时完成收货、装袋动作
	 *
	 * @param string $cache    缓存文件名
	 * @return mixed           处理成功时返回TRUE，否则返回异常信息
	 */
	public static function mbrProcess($cache) {
		if (!self::isCache($cache)) {
			return '无效的缓存文件名';
		}
		$errorTip = '';
		$data = include self::getCacheDir() . trim($cache);
		$upload = array();
		foreach ($data['upload'] as $item) {
			if (array_key_exists($item['order']['order_id'], $upload)) {
				$shipOrderDetail = array('sub_tracking_number' => $item['sub_tracking_number'], 'weight' => $item['weight'], 'length' => $item['length'], 'width' => $item['width'], 'height' => $item['height'], 'so_fee_weight' => $item['so_fee_weight'],);
				$upload[$item['order']['order_id']]['weight']+= $item['weight'];
				$upload[$item['order']['order_id']]['so_fee_weight']+= $item['so_fee_weight'];
				$upload[$item['order']['order_id']]['shipOrderDetail'][] = $shipOrderDetail;
			} else {
				$upload[$item['order']['order_id']] = $item;
				$shipOrderDetail = array('sub_tracking_number' => $item['sub_tracking_number'], 'weight' => $item['weight'], 'length' => $item['length'], 'width' => $item['width'], 'height' => $item['height'], 'so_fee_weight' => $item['so_fee_weight'],);
				$upload[$item['order']['order_id']]['shipOrderDetail'][] = $shipOrderDetail;
			}
		}
		$data['upload'] = $upload;
		$asnGroup = array(); // 按ASN单分组，以便集中收货
		$bagGroup = array(); // 按包袋号分组，以便集中装袋、加挂
		$shipBatch = $data['shipBatch']; // 出货总单信息，缓存的信息
		$db = Common_Common::getAdapter();
		foreach ($data['upload'] as $item) {
			$ansGroup[$item['asn_code']][] = $item;
			$bagGroup[$item['bag_number']][] = $item;
		}
		unset($data); // 释放数组
		$db->beginTransaction(); // 开启事务
		try {
			$shipBatch = Service_ShipBatch::getByField((int)$shipBatch['sb_id'], 'sb_id');
			// 重新获取出货总单信息
			self::receive($ansGroup); // ASN收货
			//throw new Exception('收货完成');
			self::bag($bagGroup); // 订单装袋
			//throw new Exception('装袋完成');
			self::mount($bagGroup, $shipBatch); // 袋子加挂
			//throw new Exception('加挂完成');
			//throw new Exception('收货、装袋、加挂完成');
			$db->commit(); // 事务提交，加挂完成
			
		}
		catch(Exception $e) {
			$db->rollBack(); // 发生异常回滚
			$errorTip = $e->getMessage();
			if ('' === trim($errorTip)) { // 防止空白异常信息的情况
				$errorTip = '未知错误异常';
			}
		}
		unset($ansGroup); // 释放数组
		unset($bagGroup); // 释放数组
		self::removeCache($cache); // 删除缓存文件
		return ('' === $errorTip) ? TRUE : $errorTip;
	}
	/**
	 * ASN收货
	 *
	 * @param array $asnGroup    数组引用
	 * @return void
	 */
	private static function receive(&$asnGroup) {
		$operationTime = date('Y-m-d H:i:s');
		$userId = Service_User::getUserId();
		$userIp = Common_Common::getIP();
		foreach ($asnGroup as $asnCode => $record) { // ASN单逐个收货
			$asnInfo = Service_Receiving::getByField($asnCode, 'receiving_code');
			$asnOrderCount = (int)Service_ReceivingOrderDetail::getByCondition(array('receiving_code' => $asnCode, 'rd_status' => '0',), 'count(*)');
			$isWholeAsn = (count($record) === $asnOrderCount); // 标记是否为整个ASN操作
			if (!in_array((int)$asnInfo['receiving_status'], array(5, 6), TRUE)) { // 验证ASN单状态
				throw new Exception('ASN单【' . $asnInfo['receiving_code'] . '】不是在途或收货中状态');
			}
			$shipOrderDetailWeight = array();
			foreach ($record as $item) { // ASN单中订单逐个处理
				$order = $item['order']; // 订单信息，缓存的信息
				$order = Service_Orders::getByField((int)$order['order_id'], 'order_id'); // 重新获取订单信息
				$shipOrder = Service_ShipOrder::getByField($order['order_code'], 'order_code');
				if (4 !== (int)$order['order_status']) { // 验证订单状态
					throw new Exception('订单【' . $order['order_code'] . '】不是已提交状态');
				}
				if (!empty($shipOrder)) { // 存在ship_order数据，只需更新
					$shipOrderRow = array('tracking_number' => $order['ref_tracking_number'], 'so_update_time' => $operationTime,);
					Service_ShipOrder::update($shipOrderRow, $order['order_code']);
					$shipOrderDetail = $item['shipOrderDetail'];
					foreach ($shipOrderDetail as $sod) {
						if ($sod['sub_tracking_number'] == "") continue;
						$Con = array('order_code' => $order['order_code'], 'sub_tracking_number' => $sod['sub_tracking_number'],);
						$exitSOD = Service_ShipOrderDetail::getByCondition($Con, "*", 1, 1);
						if (empty($exitSOD)) {
							$addShipOrderDetail = array('so_code' => $shipOrder['so_code'], 'so_id' => $shipOrder['so_id'], 'order_id' => $shipOrder['order_id'], 'order_code' => $shipOrder['order_code'], 'sub_tracking_number' => $sod['sub_tracking_number'], 'sod_length' => $sod['length'], 'sod_width' => $sod['width'], 'sod_height' => $sod['height'], 'sod_weight' => $sod['weight'],);
							Service_ShipOrderDetail::add($addShipOrderDetail);
						} else {
							$updateShipOrderDetail = array('sub_tracking_number' => $sod['sub_tracking_number'], 'sod_length' => $sod['length'], 'sod_width' => $sod['width'], 'sod_height' => $sod['height'], 'sod_weight' => $sod['weight'],);
							Service_ShipOrderDetail::update($updateShipOrderDetail, $exitSOD[0]['sod_id'], "sod_id");
						}
					}
				} else { // 不存在ship_order数据，往ship_order表写数据
					$soCode = Common_GetNumbers::getCode('shiporder', $order['customer_code'], 'SP');
					$shipOrderRow = array('so_code' => $soCode, 'order_id' => $order['order_id'], 'order_code' => $order['order_code'], 'tracking_number' => $order['ref_tracking_number'], 'warehouse_id' => $order['warehouse_id'], 'pp_barcode' => '', 'sm_code' => $order['sm_code'], 'so_status' => 0, 'so_weight' => $item['weight'], 'so_vol_weight' => '', 'so_length' => '', 'so_width' => '', 'so_height' => '', 'so_declared_value' => '', 'so_shipping_fee' => '', 'currency_code' => '', 'so_add_time' => $operationTime, 'so_ship_time' => $operationTime, 'so_update_time' => $operationTime, 'so_fee_weight' => $item['so_fee_weight'],);
					Service_ShipOrder::add($shipOrderRow);
					$shipOrder = Service_ShipOrder::getByField($order['order_code'], 'order_code');
					$shipOrderDetail = $item['shipOrderDetail'];
					foreach ($shipOrderDetail as $sod) {
						if ($sod['sub_tracking_number'] == "") continue;
						$Con = array('order_code' => $order['order_code'], 'sub_tracking_number' => $sod['sub_tracking_number'],);
						$exitSOD = Service_ShipOrderDetail::getByCondition($Con, "*", 1, 1);
						if (empty($exitSOD)) {
							$addShipOrderDetail = array('so_code' => $shipOrder['so_code'], 'so_id' => $shipOrder['so_id'], 'order_id' => $shipOrder['order_id'], 'order_code' => $shipOrder['order_code'], 'sub_tracking_number' => $sod['sub_tracking_number'], 'sod_length' => $sod['length'], 'sod_width' => $sod['width'], 'sod_height' => $sod['height'], 'sod_weight' => $sod['weight'],);
							Service_ShipOrderDetail::add($addShipOrderDetail);
						} else {
							$updateShipOrderDetail = array('sub_tracking_number' => $sod['sub_tracking_number'], 'sod_length' => $sod['length'], 'sod_width' => $sod['width'], 'sod_height' => $sod['height'], 'sod_weight' => $sod['weight'],);
							Service_ShipOrderDetail::update($updateShipOrderDetail, $exitSOD[0]['sod_id'], "sod_id");
						}
					}
				}
				// 更新订单信息
				$orderRow = array('order_status' => 7, // 从已提交状态变为已打包状态
				'time_of_receipt' => $operationTime, 'update_time' => $operationTime,);
				Service_Orders::update($orderRow, (int)$order['order_id'], 'order_id');
				// 添加订单日志
				$orderLog = array('order_id' => $order['order_id'], 'order_code' => $order['order_code'], 'ol_type' => 1, 'order_status_from' => $order['order_status'], 'order_status_to' => 7, 'ol_add_time' => $operationTime, 'user_id' => $userId, 'ol_ip' => $userIp,);
				Service_OrderLog::add($orderLog);
				// 添加轨迹信息
				$warehouse = Service_Warehouse::getByField($order['warehouse_id'], 'warehouse_id');
				$tracker = array('order_code' => $order['order_code'], 'sot_location' => $warehouse['warehouse_desc'], 'sot_add_time' => $operationTime, 'warehouse_id' => $order['warehouse_id'], 'sot_description' => '集货ASN仓库收货中', 'sot_type' => 0, 'sot_time_offset' => '', 'tracking_number' => $order['order_code'], 'ref_tracking_number' => '', 'status_desc' => '已打包', 'user_id' => $userId,);
				Service_ShipOrderTracking::add($tracker);
				// 更新ASN订单列表订单状态
				$rodRow = array('rd_status' => 1, 'rd_update_time' => $operationTime,);
				Service_ReceivingOrderDetail::update($rodRow, $order['order_code'], 'order_code');
				// 更新订单操作时间
				$ootRow = array('pack_time' => $operationTime, 'pack_user_id' => $userId,);
				Service_OrderOperationTime::update($ootRow, $order['order_code'], 'order_code');
			}
			if (!empty($shipOrderDetailWeight)) {
				foreach ($shipOrderDetailWeight as $orderCode => $weight) {
					$updateShipOrder = array('so_weight' => $weight);
					Service_ShipOrder::update($updateShipOrder, $orderCode, 'order_code');
				}
			}
			if (5 === (int)$asnInfo['receiving_status']) { // 把ASN在途状态更新为收货中状态
				// 更新ASN单状态
				$asnRow = array('receiving_status' => 6, 'receiving_update_time' => $operationTime,);
				Service_Receiving::update($asnRow, $asnInfo['receiving_id'], 'receiving_id');
				// 添加ASN日志
				$asnLog = array('receiving_id' => (int)$asnInfo['receiving_id'], 'receiving_code' => $asnInfo['receiving_code'], 'user_id' => $userId, 'customer_code' => $asnInfo['customer_code'], 'rl_note' => '收货中', 'rl_status_from' => 5, 'rl_status_to' => 6, 'rl_add_time' => $operationTime, 'rl_ip' => $userIp,);
				Service_ReceivingLog::add($asnLog);
				// 更新收货时间
				Service_ReceivingAttribute::update(array('receiving_time' => $operationTime,), (int)$asnInfo['receiving_id'], 'receiving_id');
			}
			if ($isWholeAsn) { // 若为整个ASN单操作，则执行整个ASN的收货动作
				$asnWeight = $asnInfo['roughweight']; // ASN毛重
				// 更新ASN单订单列表状态
				Service_ReceivingOrderDetail::update(array('rd_status' => 2, // 处理完成
				), (int)$asnInfo['receiving_id'], 'receiving_id');
				foreach ($record as $item) {
					$packProcess = new Service_PackProcess();
					$order = $item['order'];
					$packProcess->jhpack($order['order_code'], '', $order['order_pick_type'], NULL);
				}
				// 更新ASN单状态
				Service_Receiving::update(array('receiving_status' => 7, // 收货完成
				'receiving_update_time' => $operationTime,), (int)$asnInfo['receiving_id'], 'receiving_id');
				// 添加ASN单日志
				$asnLog = array('receiving_id' => (int)$asnInfo['receiving_id'], 'receiving_code' => $asnInfo['receiving_code'], 'user_id' => $userId, 'customer_code' => $asnInfo['customer_code'], 'rl_note' => '收货中->收货完成', 'rl_status_from' => 6, 'rl_status_to' => 7, 'rl_add_time' => $operationTime, 'rl_ip' => $userIp,);
				Service_ReceivingLog::add($asnLog);
				// 完成收货时间
				Service_ReceivingAttribute::update(array('complete_received_time' => $operationTime,), (int)$asnInfo['receiving_id'], 'receiving_id');
				// 需要提货的，扣除提货费
				if (1 === (int)$asnInfo['is_delivery']) {
					$income = array(); // 应收
					$payment = array(); // 应付
					$keys = array('warehouseId' => (int)$asnInfo['warehouse_id'], 'receiving_weight' => $asnWeight, 'receiving_code' => $asnInfo['receiving_code'],);
					$otherFeeObj = new Common_CalculateOtherFee();
					$otherFeeObj->setParams($keys);
					$otherFee = $otherFeeObj->getOtherFee('TIHUO');
					$otherFeeTihuo = $otherFee['data']['otherFee']['tihuo'];
					$asnOrder = $asnInfo;
					$asnOrder['order_code'] = $asnInfo['receiving_code'];
					$customer = Service_Customer::getByField($asnOrder['customer_code'], 'customer_code', array('customer_saler_user_id', 'customer_currency',));
					if ($otherFeeTihuo['price'] > 0) {
						$tihuoFee = Service_OtherFee::getByField('TIHUO', 'fee_code');
						if (!empty($tihuoFee)) { // 解冻提货费
							Service_CustomerBalanceProcess::unfreezeOtherFeeById($asnOrder, $tihuoFee['fee_id'], 'ASN收货,解冻提货费');
						}
						// 扣除提货费
						Service_CustomerBalanceProcess::deductFee($asnOrder['customer_id'], $otherFeeTihuo, 'ASN收货，扣提货费', $asnOrder['receiving_code'], 'TIHUO', $otherFeeTihuo['fee_id']);
						// 转换为客户的币种
						$customerFee = Service_Currency::converByCode($otherFeeTihuo['currency_code'], $customer['customer_currency'], $otherFeeTihuo['price']);
						// 应收
						$income[] = array('customer_code' => $asnOrder['customer_code'], 'ft_code' => 'TIHUO', 'ut_code' => 'PCE', 'sm_code' => '', 'bi_amount' => $customerFee, 'bi_org_amount' => $otherFeeTihuo['price'], 'currency_code' => $otherFeeTihuo['currency_code'], 'currency_rate' => '', 'bi_chargeable_time' => $operationTime, 'bi_note' => '提货费',);
					}
					// 应付费用，服务商不能为空
					if (isset($otherFeeTihuo['cost']) && $otherFeeTihuo['cost'] > 0 && '' !== $otherFeeTihuo['sp_code']) {
						$spRow = Service_ServiceProvider::getByField($otherFeeTihuo['sp_code'], 'sp_code');
						$spCurrency = $spRow['currency_code'];
						$spFee = Service_Currency::converByCode($otherFeeTihuo['currency_code'], $spCurrency, $otherFeeTihuo['cost']); // 转为服务商币种
						$payment[] = array('sp_code' => $otherFeeTihuo['sp_code'], //服务商代码
						'ft_code' => 'TIHUO', 'ut_code' => 'PCE', 'sm_code' => '', 'bp_amount' => $spFee, 'bp_org_amount' => $otherFeeTihuo['cost'], 'currency_code' => $otherFeeTihuo['currency_code'], 'currency_rate' => '', 'bp_chargeable_time' => $operationTime,);
					}
					// 判断是否存在应收应付
					if (!empty($income) || !empty($payment)) {
						//写入业务表
						$businessLog = array('ds_code' => 'asn', 'customer_code' => $asnOrder['customer_code'], 'warehouse_id' => $asnOrder['warehouse_id'], 'sm_code' => '', 'bb_volume_weight' => $asnWeight, 'bb_charge_weight' => $asnWeight, 'bb_delivered_weight' => $asnWeight, 'bb_pieces' => $piece, 'bb_declared_value' => 0, 'bb_declared_currency_code' => 'USD', 'country_code' => '', 'bb_postcode' => '', 'bb_charge_time' => $operationTime, 'bb_declared_time' => $operationTime, // 发货时间，此时间与服务商对接
						'bb_sales_id' => $customer['customer_saler_user_id'], 'bb_refer_code' => $asnOrder['receiving_code'], 'bb_service_number' => '', //ref_tracking_number
						'bb_reference_no' => '',);
						$businessObj = new Process_Business();
						$response = $businessObj->businessFee($businessLog, $income, $payment);
						if (1 !== (int)$response['state']) {
							throw new Exception($response['message']);
						}
					}
				} // END IF - 提货费
				
			} // END IF - 整个ASN单执行收货动作
			
		} // END FOREACH - 逐个ASN单收货
		
	}
	/**
	 * 订单装袋
	 *
	 * @param array $bagGroup    数组引用
	 * @return void
	 */
	private static function bag(&$bagGroup) {
		$testUser = array('E0110', 'E0207'); // 测试账号
		foreach ($bagGroup as $bagCode => $record) { // 按包袋号逐个处理
			$outboundBag = Service_OutboundBag::getByField($bagCode, 'ob_no');
			$smCode = $record[0]['order']['sm_code']; // 包袋运输方式
			$bagWeight = 0; // 包袋总重量
			if (!empty($outboundBag)) { // 存在包袋号则判断其状态是否为草稿状态
				if (0 !== (int)$outboundBag['ob_status']) {
					throw new Exception('包袋【' . $bagCode . '】不是草稿状态');
				} elseif ($smCode !== $outboundBag['sm_code']) {
					throw new Exception('包袋【' . $bagCode . '】与所属订单运输方式不一致');
				}
				$outboundBagDetail = Service_OutboundBagDetail::getByCondition(array('ob_no' => $bagCode));
				if (!empty($outboundBagDetail) && count($outboundBagDetail) > 0) {
					throw new Exception('包袋【' . $bagCode . '】不是空袋');
				}
			} else { // 不存在包袋则创建
				if (!Service_OutboundBag::create($bagCode, $smCode, "")) {
					throw new Exception('创建包袋【' . $bagCode . '】失败，请稍候再试');
				} else { // 补充包袋信息
					$outboundBag = Service_OutboundBag::getByField($bagCode, 'ob_no');
				}
			}
			$shipOrderProcess = new Service_ShipOrderProcess();
			foreach ($record as $item) { // 逐个订单装袋
				$order = $item['order']; // 订单信息，缓存的信息
				$order = Service_Orders::getByField((int)$order['order_id'], 'order_id'); // 重新获取订单信息
				$shipOrder = Service_ShipOrder::getByField($order['order_code'], 'order_code');
				$bagWeight+= $item['weight'];
				$customer = $item['customer']; // 客户代码
				if (7 !== (int)$order['order_status']) { // 验证订单状态
					throw new Exception('订单【' . $order['order_code'] . '】不是已打包状态');
				}
				if (empty($shipOrder)) {
					throw new Exception('订单【' . $order['order_code'] . '】物流订单不存在');
				} elseif (0 !== (int)$shipOrder['so_status']) {
					throw new Exception('订单【' . $order['order_code'] . '】物流订单不是草稿状态');
				}
				/*if (in_array($customer, $testUser, TRUE)) { // 测试用户不能出货
					throw new Exception('测试账号【' . $customer . '】不能加挂出货');
				}*/
				$shipOrderProcess->deliveryForOrderInOut((int)$order['order_id'], $order['order_code'], $bagCode, $item['weight'], $item['tracking_number'], $shipOrder['so_code'], $smCode, array());
			} // END FOREACH - 逐个订单装袋
			$shipOrderProcess->finishBagForOrderInOut($outboundBag, $bagWeight); // 完成装袋动作
			
		} // END FOREACH - 按包袋号逐个处理
		
	}
	/**
	 * 袋子加挂
	 *
	 * @param array $bagGroup     数组引用
	 * @param array $shipBatch    出货总单信息数组引用
	 * @return void
	 */
	private static function mount(&$bagGroup, &$shipBatch) {
		if (0 !== (int)$shipBatch['sb_status']) {
			throw new Exception('出货总单【' . $shipBatch['sb_code'] . '】不是草稿状态');
		}
		$operationTime = date('Y-m-d H:i:s');
		$shipOrderProcess = new Service_ShipOrderProcess();
		foreach ($bagGroup as $bagCode => $record) { // 按袋子逐个加挂
			$outboundBag = Service_OutboundBag::getByField($bagCode, 'ob_no');
			$smCode = $record[0]['order']['sm_code']; // 包袋运输方式
			$carNumber = $record[0]['car_number'];
			$order_id = $record[0]['shipOrderDetail'];
			$sum = 0;
			foreach ($order_id as $key => $value) {
				if (!empty($value['sub_tracking_number'])) {
					$sum++;
				}
			}
			if ($carNumber !== trim($shipBatch['sb_truck_no'])) { // 车牌号与出货总单车牌不一致
				throw new Exception('包袋【' . $bagCode . '】车牌与出货总单【' . $shipBatch['sb_code'] . '】车牌不一致');
			}
			if (empty($outboundBag)) { // 包袋不存在
				throw new Exception('包袋【' . $bagCode . '】不存在');
			}
			if (1 !== (int)$outboundBag['ob_status']) { // 包袋状态不对
				throw new Exception('包袋【' . $bagCode . '】不是已完成状态');
			}
			if ('' !== trim($shipBatch['sm_code']) && $smCode !== $shipBatch['sm_code']) {
				throw new Exception('包袋【' . $bagCode . '】与出货总单【' . $shipBatch['sb_code'] . '】运输方式不一致');
			}
			$shipOrderProcess->mountForOrderInOut($bagCode, $shipBatch['sb_code'], $outboundBag['ob_weight']);
			Service_ShipOrder::update(array('so_piece' => $sum), $record[0]['order']['order_code'], 'order_code');
			/* Service_Receiving::update(array(
			       'receiving_status'      => 7, // 收货完成
			       'receiving_update_time' => $operationTime,
			     ), (int) $asnInfo['receiving_id'], 'receiving_id');*/
		} // END FOREACH - 按袋子逐个加挂
		
	}
	/**
	 * 根据索引映射为可读性的名称
	 *
	 * @param integer|string $index    索引值
	 * @return mixed                   若存在返回对应的映射，否则返回原来的内容
	 */
	private static function getMapIndex($index) {
		switch ($index) {
			case 0:
			case 'A':
			case 'a':
				return 'car_number';
			case 1:
			case 'B':
			case 'b':
				return 'bag_number';
			case 2:
			case 'C':
			case 'c':
				return 'order_code';
			case 3:
			case 'D':
			case 'd':
				return 'tracking_number';
			case 4:
			case 'E':
			case 'e':
				return 'sub_tracking_number';
			case 5:
			case 'F':
			case 'f':
				return 'weight';
			case 6:
			case 'G':
			case 'g':
				return 'length';
			case 7:
			case 'H':
			case 'h':
				return 'width';
			case 8:
			case 'I':
			case 'i':
				return 'height';
			case 9:
			case 'J':
			case 'j':
				return 'so_fee_weight';
			default:
				return $index;
		}
	}
    public static function getPlatformOfShipBatch( $sbCode ) {
        $platform = array();
        if( $sbCode ) {
            $sbDetails = Service_ShipBatchDetail::getByCondition( array( 'sb_code' => $sbCode ), 'ob_no' );
            foreach( $sbDetails as $sbDetail ) {
                $bagDetails = Service_OutboundBagDetail::getByCondition( array( 'ob_no' => $sbDetail['ob_no'] ) );
                foreach( $bagDetails as $bagDetail ) {
                    $order = Service_Orders::getByField( $bagDetail['order_code'],  'order_code', 'platform');
                    if( $order ) {
                        $platform[] = $order['platform'];
                    }
                }
            }
        }
        return array_unique( $platform );
    }
}
